source: GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.cpp @ 1968

Revision 1968, 23.5 KB checked in by mattausch, 17 years ago (diff)

early exit for global lines
preprocessor support

RevLine 
[1944]1#include "glInterface.h"
2#include "GlobalLinesRenderer.h"
3#include "common.h"
4#include "RenderTexture.h"
5#include "Preprocessor.h"
6#include "GlRenderer.h"
[1960]7#include "Exporter.h"
[1963]8#include "ViewCellsManager.h"
[1960]9
[1963]10
[1953]11// the devil library
12#include <IL/il.h>
13#include <IL/ilu.h>
14#include <IL/ilut.h>
[1944]15
16#include <Cg/cg.h>
17#include <Cg/cgGL.h>
18
19//#include <QtOpenGL>
20
21namespace GtpVisibilityPreprocessor {
22
23
24static CGcontext sCgContext = NULL;
25static CGprogram sCgDepthPeelingProgram = NULL;
26static CGprogram sCgPassThroughProgram = NULL;
27
28static CGprofile sCgFragmentProfile;
29static CGparameter sTextureParam;
[1964]30static CGparameter sTexWidthParam;
31static CGparameter sStepSizeParam;
[1944]32
33GlobalLinesRenderer *globalLinesRenderer = NULL;
34
[1960]35static bool isDepth = true;
[1953]36
37static void InitDevIl()
38{
39        ilInit();
40        ILuint ImageName;
41        ilGenImages(1, &ImageName);
42        ilBindImage(ImageName);
43        ilEnable(IL_FILE_OVERWRITE);
44
45        //  ilRegisterFormat(IL_RGBA);
46        //  ilRegisterType(IL_FLOAT);
47
48        //  ilEnable(IL_ORIGIN_SET);
49        //  ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
50}
51
52
[1944]53static void cgErrorCallback()
54{
55        CGerror lastError = cgGetError();
56
57        if(lastError)
58        {
59                printf("%s\n\n", cgGetErrorString(lastError));
60                printf("%s\n", cgGetLastListing(sCgContext));
61                printf("Cg error, exiting...\n");
62
63                exit(0);
64        }
65}
66
67static void PrintGLerror(char *msg)
68{
69        GLenum errCode;
70        const GLubyte *errStr;
71       
72        if ((errCode = glGetError()) != GL_NO_ERROR)
73        {
74                errStr = gluErrorString(errCode);
75                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
76        }
77}
78
79
80void Reshape(int w, int h)
81{
82        if (h == 0) h = 1;
83
84        glViewport(0, 0, w, h);
85
86        glMatrixMode(GL_PROJECTION);
87        glLoadIdentity();
88
[1949]89        //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 3, 5000.0);
[1944]90        //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.5, 10.0);
[1951]91        glOrtho(-1, 1, -1, 1, 0.5, 15);
[1944]92}
93
94
[1960]95void SetFrustum(const int sizeX, const int sizeY,
96                                const float nearPlane, const float farPlane)
[1953]97{
98        glMatrixMode(GL_PROJECTION);
99        glLoadIdentity();
100
[1960]101        glOrtho(-sizeX * 0.5, sizeX * 0.5,
102                        -sizeY * 0.5, sizeY * 0.5,
[1953]103                        nearPlane, farPlane);
104
105        /*glOrtho(0, sizeX,
106                    0, sizeY ,
107                        nearPlane, farPlane);*/
108}
109
[1944]110void Display()
111{
112        //globalLinesRenderer->DrawGeometry();
[1958]113        //globalLinesRenderer->CastGlobalLines(Beam(), 0);
[1960]114        globalLinesRenderer->DisplayBuffer(isDepth);
[1944]115        PrintGLerror("display");
116
117        glutSwapBuffers();
118}
119
120
121void Idle()
122{
123        glutPostRedisplay();
124}
125
126
127void Keyboard(unsigned char key, int x, int y)
128{
129        switch(key)
130        {
[1949]131        case '2':
[1958]132                {
133                        VssRayContainer rays;
134
135                        ++ globalLinesRenderer->mMaxDepth;
[1964]136                        globalLinesRenderer->ApplyDepthPeeling(rays);
[1958]137
138                        cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl;
[1960]139                        CLEAR_CONTAINER(rays);
[1958]140                        return;
141                }
[1949]142        case '1':
[1958]143                {
144                        VssRayContainer rays;
145
146                        -- globalLinesRenderer->mMaxDepth;
147                        cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl;
148                       
[1964]149                        globalLinesRenderer->ApplyDepthPeeling(rays);
[1960]150                        CLEAR_CONTAINER(rays);
[1958]151                        return;
152                }
[1953]153        case '3':
[1958]154                {
155                        globalLinesRenderer->ExportDepthBuffer();
156                        return;
157                }
158        case '4':
159                {
[1960]160                        globalLinesRenderer->ExportItemBuffer();
161                        return;
162                }
163        case '8':
164                {
165                        isDepth = !isDepth;
166                        return;
167                }
168        case '9':
169                {
[1958]170                        VssRayContainer rays;
[1964]171                        globalLinesRenderer->ApplyDepthPeeling(rays);
[1960]172                        VssRayContainer outRays;
173                        VssRayContainer::const_iterator vit, vit_end = rays.end();
[1958]174
[1960]175                        const float p = 8.0f / (float)rays.size();
176
177                        for (vit = rays.begin(); vit != vit_end; ++ vit)
178                        {
179                                if (Random(1.0f) < p)
180                                {
181                                        outRays.push_back(*vit);
182                                }
183                        }
184
185                        globalLinesRenderer->Visualize(rays);
186                        CLEAR_CONTAINER(rays);
187                        return;
188                }
189        case '0':
190                {
191                        VssRayContainer rays;
[1964]192                        globalLinesRenderer->ApplyDepthPeeling(rays);
[1960]193                        CLEAR_CONTAINER(rays);
[1958]194                        return;
195                }
[1944]196        default:
197                return;
198        }
199}
200
[1953]201
[1949]202GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor,
[1968]203                                                                                 const int texHeight,
204                                                                                 const int texWidth,
205                                                                                 const float eps,
206                                                                                 const int maxDepth,
207                                                                                 const bool sampleReverse):
[1953]208mNewTexture(NULL),
209mOldTexture(NULL),
[1964]210mPreprocessor(preprocessor),
211mTexHeight(mTexHeight),
212mTexWidth(mTexWidth),
[1968]213mEpsilon(eps),
214mMaxDepth(maxDepth),
215mSampleReverse(sampleReverse)
[1944]216{
[1968]217        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
218                                                           mPreprocessor->mViewCellsManager,
219                                                           mPreprocessor->mKdTree);
220
[1944]221}
222
223
[1968]224GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor):
[1964]225mNewTexture(NULL),
226mOldTexture(NULL),
[1968]227mMaxDepth(40),
[1964]228mPreprocessor(preprocessor),
229mTexHeight(128),
230mTexWidth(128),
[1968]231mEpsilon(0.0001),
232mSampleReverse(true)
233{
234        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
235                                                           mPreprocessor->mViewCellsManager,
236                                                           mPreprocessor->mKdTree);
237}
[1964]238
239
[1960]240void GlobalLinesRenderer::DisplayBuffer(const bool isDepth)
[1958]241{
[1960]242        if (!isDepth)
243                mNewTexture->Bind();
244        else
245                mNewTexture->BindDepth();
[1958]246        mNewTexture->EnableTextureTarget();
247       
248        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
249       
250        if (mNewTexture->IsRectangleTexture())
251        {
252                glBegin(GL_QUADS);
253                glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
254                glTexCoord2f(mNewTexture->GetWidth(), 0); glVertex3f( 1, -1, -0.5f);
255                glTexCoord2f(mNewTexture->GetWidth(), mNewTexture->GetHeight()); glVertex3f( 1,  1, -0.5f);
256                glTexCoord2f(0, mNewTexture->GetHeight()); glVertex3f(-1, 1, -0.5f);
257                glEnd();
258        }
259        else
260        {
261                glBegin(GL_QUADS);
262                glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
263                glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
264                glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
265                glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
266                glEnd();
267        } 
268
269        mNewTexture->DisableTextureTarget();
270        PrintGLerror("displaytexture");
271}
272
273
[1944]274GlobalLinesRenderer::~GlobalLinesRenderer()
275{
276        if (sCgDepthPeelingProgram)
277                cgDestroyProgram(sCgDepthPeelingProgram);
278        if (sCgContext)
279                cgDestroyContext(sCgContext);
[1958]280
281        // init the receiving buffers
282        delete mNewDepthBuffer;
283        delete mOldDepthBuffer;
284       
285        delete mNewItemBuffer;
286        delete mOldItemBuffer;
[1968]287
288        DEL_PTR(mRenderer);
[1944]289}
290
291 
[1968]292void GlobalLinesRenderer::InitRenderTexture(RenderTexture *rt)
293{
294         // setup the rendering context for the RenderTexture
295        rt->BeginCapture();
296        {
297                //Reshape(mTexWidth, mTexHeight);
298                glViewport(0, 0, mTexWidth, mTexHeight);
299                SetFrustum(mWidth, mWidth, mNear, mFar);
300
301                // for item buffer: white means no color
302                glClearColor(1, 1, 1, 1);
303                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
304
305                glFrontFace(GL_CCW);
306                glCullFace(GL_BACK);
307
308                glDisable(GL_CULL_FACE);
309                //glEnable(GL_CULL_FACE);
310
311                glShadeModel(GL_FLAT);
312                glEnable(GL_DEPTH_TEST);
313               
314                glMatrixMode(GL_MODELVIEW);
315                glLoadIdentity();
316                gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
317                                  mTermination.x, mTermination.y, mTermination.z,
318                                  mUpVec.x, mUpVec.y, mUpVec.z);
319
320        }
321        rt->EndCapture();
322}
323
324
[1964]325void GlobalLinesRenderer::InitScene(const float alpha, const float beta)
[1944]326{
[1968]327        AxisAlignedBox3 bbox =
328                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
[1964]329       
330        const float sceneSize = Magnitude(bbox.Diagonal());
[1958]331
[1964]332        // compute the center of the scene
[1968]333        mTermination = bbox.Center();
[1964]334       
335        // add a small offset to provide some randomness in the sampling
[1968]336        if (0)
337        {
338                Vector3 offset(
339                        Random(sceneSize * 1e-3f),
340                        Random(sceneSize * 1e-3f),
341                        Random(sceneSize * 1e-3f));
[1964]342
[1968]343                mTermination += offset;
344        }
[1964]345               
346        mNear = 1;
347        mFar = sceneSize * 2;
348        mWidth = sceneSize;
349
350        ComputeLookAt(alpha,
351                                  beta,
352                                  mEyeVec,
353                                  mUpVec,
354                                  mLeftVec);
355       
[1968]356        mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec;
[1964]357
[1968]358        cout << "termination point: " << mTermination << endl;
[1964]359        cout << "view point: " << mViewPoint << endl;
360        cout << "scene: " << bbox << endl;
361
[1968]362        InitRenderTexture(mNewTexture);
363        InitRenderTexture(mOldTexture);
364       
365        cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
366}
[1964]367
368
[1968]369void GlobalLinesRenderer::InitScene(const SimpleRay &ray)
370{
371        AxisAlignedBox3 bbox =
372                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
373       
374        const float sceneSize = Magnitude(bbox.Diagonal());
[1964]375
[1968]376        // compute the center of the scene
377        mViewPoint = ray.mOrigin;
378        mTermination = ray.mOrigin + ray.mDirection;
[1964]379
[1968]380        mEyeVec = Normalize(ray.mDirection);
[1964]381
[1968]382        mNear = 1;
383        mFar = sceneSize * 2;
384        mWidth = sceneSize;
[1964]385
[1968]386        mEyeVec.RightHandedBase(mUpVec, mLeftVec);
387    mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec;
[1964]388
[1968]389        cout << "termination point: " << mTermination << endl;
390        cout << "view point: " << mViewPoint << endl;
391        cout << "scene: " << bbox << endl;
[1964]392
[1968]393        InitRenderTexture(mNewTexture);
394        InitRenderTexture(mOldTexture);
395       
[1964]396        cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
397}
398
399
400void GlobalLinesRenderer::CastGlobalLines(const float alpha,
401                                                                                  const float beta,
402                                                                                  //const int samples,
403                                                                                  VssRayContainer &rays)
404{
405        InitScene(alpha, beta);
406
[1944]407        // bind pixel shader implementing the front depth buffer functionality
[1964]408        ApplyDepthPeeling(rays);
[1944]409}
410
411
[1968]412void GlobalLinesRenderer::CastGlobalLines(const SimpleRay &ray,
413                                                                                  VssRayContainer &rays)
414{
415        InitScene(ray);
416
417        // bind pixel shader implementing the front depth buffer functionality
418        ApplyDepthPeeling(rays);
419}
420
[1944]421void GlobalLinesRenderer::RenderObject(Intersectable *obj)
422{
423        mRenderer->RenderIntersectable(obj);
424}
425
426
427void GlobalLinesRenderer::DrawGeometry()
[1945]428{
[1951]429        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
430        glMatrixMode(GL_MODELVIEW);
[1944]431
[1951]432        glPushMatrix();
433        {
[1953]434                //glLoadIdentity();
[1951]435                ObjectContainer::const_iterator oit, oit_end = mPreprocessor->mObjects.end();
436
437                Intersectable::NewMail();
438
439                for (oit = mPreprocessor->mObjects.begin(); oit != oit_end; ++ oit)
440                {
[1962]441                        //cout << (*oit)->GetId() << " ";
[1951]442                        RenderObject(*oit);
443                }
[1944]444        }
[1951]445        glPopMatrix();
[1944]446}
447
448
449void GlobalLinesRenderer::SwitchRenderTextures()
450{
[1953]451        RenderTexture *buffer = mOldTexture;
452        mOldTexture = mNewTexture;
453        mNewTexture = buffer;
[1944]454}
455
456
[1958]457void GlobalLinesRenderer::ComputeLookAt(const float alpha,
458                                                                                const float beta,
459                                                                                Vector3 &eye,
460                                                                                Vector3 &up,
[1964]461                                                                                Vector3 &left)
[1958]462{
463        eye.x = sin(alpha) * cos(beta);
464        eye.y = sin(alpha) * sin(beta);
[1964]465        eye.z = cos(alpha);
[1958]466
467        eye.RightHandedBase(up, left);
468}
469
470
[1944]471void GlobalLinesRenderer::InitGl()
472{
[1953]473        InitDevIl();
474
[1960]475    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
[1944]476        glutInitWindowPosition(50, 50);
477        glutInitWindowSize(512, 512);
478        glutCreateWindow("TestRenderDepthTexture"); 
479
480        int err = glewInit();
481        if (GLEW_OK != err)
482        {
483                // problem: glewInit failed, something is seriously wrong
484                fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
485                exit(-1);
486        } 
487       
488        glutKeyboardFunc(Keyboard);
489        glutDisplayFunc(Display);
490        glutIdleFunc(Idle);
491        glutReshapeFunc(Reshape);
492
493        Reshape(512, 512);
494        glMatrixMode(GL_MODELVIEW);
495        glLoadIdentity();
496
[1958]497        // initialise the receiving buffers
[1964]498        mNewDepthBuffer = new float[mTexWidth * mTexHeight];
499        mNewItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4];
[1960]500
[1964]501        mOldDepthBuffer = new float[mTexWidth * mTexHeight];
502    mOldItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4];
[1960]503
[1964]504        for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
[1958]505        {
506                mNewDepthBuffer[i] = 1;
507                mOldDepthBuffer[i] = 1;
508
[1960]509                mNewItemBuffer[i * 4]     = 255;
510                mNewItemBuffer[i * 4 + 1] = 255;
511                mNewItemBuffer[i * 4 + 2] = 255;
512                mNewItemBuffer[i * 4 + 3] = 255;
513
514                mOldItemBuffer[i * 4]     = 255;
515                mOldItemBuffer[i * 4 + 1] = 255;
516                mOldItemBuffer[i * 4 + 2] = 255;
517                mOldItemBuffer[i * 4 + 3] = 255;
[1958]518        }
519
[1960]520        /*gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
[1944]521                          midPoint.x, midPoint.y, midPoint.z,
522                          0, 1, 0);
523*/
524        gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
525
[1949]526        //glDisable(GL_CULL_FACE);
527        glEnable(GL_CULL_FACE);
[1944]528        glDisable(GL_LIGHTING);
529        glDisable(GL_COLOR_MATERIAL);
530        glEnable(GL_DEPTH_TEST);
531        glClearColor(0.1, 0.2, 0.3, 1);
532       
533        // A square, mipmapped, anisotropically filtered 8-bit RGBA texture with
534        // depth and stencil.
535        // Note that RT_COPY_TO_TEXTURE is required for depth textures on ATI hardware
536       
[1964]537        mNewTexture = new RenderTexture(mTexWidth, mTexHeight, true, true);
538#ifdef ATI
[1953]539        mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
[1964]540#else
541        mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
542#endif
543
544        mOldTexture = new RenderTexture(mTexWidth, mTexHeight, true, true);
545
546#ifdef ATI
[1953]547        mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
[1964]548#else
549        mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
550#endif
[1944]551
552        // Setup Cg
553        cgSetErrorCallback(cgErrorCallback);
554
555        // Create cgContext.
556        sCgContext = cgCreateContext();
557
558        // get the best profile for this hardware
559        sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
560       
561        //assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN);
562        cgGLSetOptimalOptions(sCgFragmentProfile);
563
564        sCgDepthPeelingProgram =
565                cgCreateProgramFromFile(sCgContext,
566                                                                CG_SOURCE,
[1953]567                                                                mNewTexture->IsRectangleTexture() ?
[1951]568                                                                "../src/depth_peelingRect.cg" : "../src/depth_peeling2d.cg",
[1944]569                                                                GLEW_ARB_fragment_program ? CG_PROFILE_ARBFP1 : CG_PROFILE_FP30,
570                                                                NULL,
571                                                                NULL);
572
573        if(sCgDepthPeelingProgram != NULL)
574        {
575                cgGLLoadProgram(sCgDepthPeelingProgram);
576                sTextureParam = cgGetNamedParameter(sCgDepthPeelingProgram, "depthTex"); 
[1964]577               
578                // we need size of texture for scaling
579                if (!mNewTexture->IsRectangleTexture())
580                {
581                        sTexWidthParam = cgGetNamedParameter(sCgDepthPeelingProgram, "texWidth");
582                }
583
584                sStepSizeParam = cgGetNamedParameter(sCgDepthPeelingProgram, "stepSize");
585
586                cgGLSetParameter1f(sTexWidthParam, (float)mTexWidth);
587                cgGLSetParameter1f(sStepSizeParam, mEpsilon);
[1944]588        }
589
590        sCgPassThroughProgram =
591                cgCreateProgramFromFile(sCgContext,
592                                                                CG_SOURCE,
593                                                                "../src/passthrough.cg",
594                                                                GLEW_ARB_fragment_program ? CG_PROFILE_ARBFP1 : CG_PROFILE_FP30,
595                                                                NULL,
596                                                                NULL);
597
598        if(sCgPassThroughProgram != NULL)
599        {
600                cgGLLoadProgram(sCgPassThroughProgram);
601        }
602
[1964]603        const float alpha = 1.1;
604        const float beta = 0.9;
605        InitScene(alpha, beta);
[1953]606
[1944]607        PrintGLerror("init");
608}
609
610
[1960]611Intersectable *GlobalLinesRenderer::ExtractSamplePoint(float *depthBuffer,
612                                                                                                           unsigned char *itemBuffer,
613                                                                                                           const int x,
614                                                                                                           const int y,
615                                                                                                           Vector3 &hitPoint,
616                                                                                                           const bool isFrontBuffer) const
[1944]617{
[1964]618        const int depthIndex = x + mTexWidth * y;
[1960]619        const int itemIndex = 4 * depthIndex;
620
621        const float depth = depthBuffer[depthIndex];
622        const float eyeDist = mNear + (mFar - mNear) * depth;
623       
[1964]624        const float leftDist = -0.5f * mWidth + mWidth * ((float)x + 0.5f) / mTexWidth;
625        //const float leftDist = 0.5f * mWidth - mWidth * ((float)x + 0.5f) / mTexWidth;
[1960]626       
[1964]627        const float upDist = -0.5f * mWidth + mWidth * ((float)y + 0.5f) / mTexHeight;
628        //const float upDist = 0.5f * mWidth - mWidth * ((float)y + 0.5f) / mTexHeight;
629
[1960]630        hitPoint = mViewPoint +
631                       eyeDist * mEyeVec +
[1964]632                           upDist * mUpVec +
633                           leftDist * mLeftVec;
[1960]634                               
635        unsigned char r = itemBuffer[itemIndex];
636        unsigned char g = itemBuffer[itemIndex + 1];
637        unsigned char b = itemBuffer[itemIndex + 2];
638                       
639        // 3 times 255 means no valid object
640        if ((r == 255) && (g == 255) && (b == 255))
641                return NULL;
642
643        const int id = mRenderer->GetId(r, g, b);
644        //cout << "r: " << (int)r << "g: " << (int)g << " b: " << (int)b << " id: " << id << "|";
645        Intersectable *intersect = mPreprocessor->GetObjectById(id);
646
647        const Vector3 dir = isFrontBuffer ? mEyeVec : -mEyeVec;
648        // HACK: assume triangle intersectable
649        const Vector3 norm = intersect->GetNormal(0);
650
[1961]651        // test for invalid view space
652        if (DotProd(dir, norm) >= -Limits::Small)
653                return NULL;
654
655        return intersect;
[1944]656}
657
658
[1968]659bool GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays,
[1963]660                                                                                         const bool oldBufferInitialised,
661                                                                                         const int pass)
[1953]662{
663        GrabDepthBuffer(mNewDepthBuffer, mNewTexture);
664        GrabItemBuffer(mNewItemBuffer, mNewTexture);
665
[1960]666        if (oldBufferInitialised)
[1953]667        {
[1960]668                GrabDepthBuffer(mOldDepthBuffer, mOldTexture);
669                GrabItemBuffer(mOldItemBuffer, mOldTexture);
670        }
671        else
672        {
[1964]673                for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
[1953]674                {
[1960]675                        mOldDepthBuffer[i] = 0;
[1953]676
[1960]677                        mOldItemBuffer[i * 4]     = 255;
678                        mOldItemBuffer[i * 4 + 1] = 255;
679                        mOldItemBuffer[i * 4 + 2] = 255;
680                        mOldItemBuffer[i * 4 + 3] = 255;
681                }
682        }
[1953]683
[1968]684        /////////////////
685        // test for validity
686
687        bool buffersEqual = true;
688        bool bufferEmpty = true;
689
[1964]690        for (int y = 0; y < mTexHeight; ++ y)
[1960]691        {
[1964]692                for (int x = 0; x < mTexWidth; ++ x)
[1960]693                {
[1968]694                        const int depthIndex = x + mTexWidth * y;   
695                        const int itemIndex = 4 * depthIndex;
696               
697                        if (mOldItemBuffer[itemIndex] != mNewItemBuffer[itemIndex])
698                        {
699                                buffersEqual = false;
700                        }
701
702                        unsigned char r = mNewItemBuffer[itemIndex];
703                        unsigned char g = mNewItemBuffer[itemIndex + 1];
704                        unsigned char b = mNewItemBuffer[itemIndex + 2];
705
706                        // 3 times 255 means no valid object
707                        if (!((r == 255) && (g == 255) && (b == 255)))
708                        {
709                                bufferEmpty = false;
710                        }
711                }
712               
713                // early exit
714                if (!buffersEqual && !bufferEmpty)
715                        break;
716        }
717
718        // depth buffer not valid
719        if (buffersEqual || bufferEmpty)
720        {
721                cout << "stopped at layer " << pass << endl;
722                return false;
723        }
724
725        for (int y = 0; y < mTexHeight; ++ y)
726        {
727                for (int x = 0; x < mTexWidth; ++ x)
728                {
[1960]729                        Vector3 newPt, oldPt;
[1953]730
[1960]731                        Intersectable *termObj1 = ExtractSamplePoint(mNewDepthBuffer,
732                                                                                                                 mNewItemBuffer,
733                                                                                                                 x,
734                                                                                                                 y,
735                                                                                                                 newPt,
736                                                                                                                 true);
[1953]737
[1960]738                        Intersectable *termObj2 = ExtractSamplePoint(mOldDepthBuffer,
739                                                                                                                 mOldItemBuffer,
740                                                                                                                 x,
741                                                                                                                 y,
742                                                                                                                 oldPt,
743                                                                                                                 false);
[1953]744
[1963]745                        if (!termObj1 && !termObj2) // we do not create a ray
746                                continue;
747
748                        Vector3 clippedOldPt, clippedNewPt;
749
750                        ClipToViewSpaceBox(oldPt, newPt, clippedOldPt, clippedNewPt);
751                        //clippedOldPt = oldPt;
752                        //clippedNewPt = newPt;
753
[1960]754                        // create rays in both directions
755                        if (termObj1)
[1958]756                        {
[1963]757                                vssRays.push_back(new VssRay(clippedOldPt, clippedNewPt, NULL, termObj1, pass));
[1960]758                                //cout << "new pt: " << newPt << endl;
[1958]759                        }
760
[1968]761                        if (mSampleReverse && termObj2)
[1961]762                        {
[1963]763                                vssRays.push_back(new VssRay(clippedNewPt, clippedOldPt, NULL, termObj2, pass));
[1961]764                                //cout << "old pt: " << oldPt << endl;
765                        }
[1953]766                }
767        }
[1968]768
769        return true;
[1953]770}
771
772
[1963]773bool GlobalLinesRenderer::ClipToViewSpaceBox(const Vector3 &origin,
774                                                                                         const Vector3 &termination,
775                                                                                         Vector3 &clippedOrigin,
776                                                                                         Vector3 &clippedTermination)
[1944]777{
[1963]778        Ray ray(origin, termination - origin, Ray::LINE_SEGMENT);       
779        ray.Precompute();
780       
781        float tmin, tmax;
782       
783        //const AxisAlignedBox3 bbox = mPreprocessor->mViewCellsManager->GetViewSpaceBox();
784        // hack
785        const AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox();
786
787        if ((!bbox.ComputeMinMaxT(ray, &tmin, &tmax)) ||
788                tmin>=tmax)
789        {
790                return false;
791        }
792       
793        if (tmin >= 1.0f || tmax <=0.0f)
794                return false;
795
796        if (tmin > 0.0f)
797                clippedOrigin = ray.Extrap(tmin);
798        else
799                clippedOrigin = origin;
800
801        if (tmax < 1.0f)
802                clippedTermination = ray.Extrap(tmax);
803        else
804                clippedTermination = termination;
805
806        return true;
[1944]807}
808
809
[1963]810void GlobalLinesRenderer::Run()
[1960]811{
[1963]812        glutMainLoop();
[1960]813}
814
815
816void GlobalLinesRenderer::Visualize(const VssRayContainer &vssRays)
817{
818        Exporter *exporter = Exporter::GetExporter("globalLines.wrl");
819       
820        if (!exporter)
821                return;
822
823        exporter->SetWireframe();
824        //exporter->ExportGeometry(preprocessor->mObjects);
825        exporter->SetFilled();
826
827        VssRayContainer::const_iterator vit, vit_end = vssRays.end();
[1963]828        VssRayContainer outRays;
[1960]829
[1963]830        Intersectable::NewMail();
831
[1960]832        for (vit = vssRays.begin(); vit != vit_end; ++ vit)
833        {
834                VssRay *ray = *vit;
[1963]835                Intersectable *obj = (*vit)->mTerminationObject;
836
837                if (!obj->Mailed())
838                {
839                        obj->Mail();
840                        exporter->ExportIntersectable(obj);
841                }
842
[1964]843                //if (ray->mPass == 4)
[1963]844                        outRays.push_back(ray);
[1960]845        }       
846
[1963]847        exporter->ExportRays(outRays);
[1960]848
849        delete exporter;
850}
851
852
[1953]853void GlobalLinesRenderer::GrabDepthBuffer(float *data, RenderTexture *rt)
854{
855        rt->BindDepth();
856        rt->EnableTextureTarget();
857
858        const int texFormat = GL_DEPTH_COMPONENT;
859        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
860
861        mNewTexture->DisableTextureTarget();
862}
863
864
[1960]865void GlobalLinesRenderer::GrabItemBuffer(unsigned char *data, RenderTexture *rt)
[1953]866{
[1958]867        rt->Bind();
[1953]868        rt->EnableTextureTarget();
869
[1958]870        const int texFormat = GL_RGBA;
[1960]871        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data);
[1953]872
873        mNewTexture->DisableTextureTarget();
874}
875
[1958]876
[1953]877void GlobalLinesRenderer::ExportDepthBuffer()
878{
879        mNewTexture->BindDepth();
880        mNewTexture->EnableTextureTarget();
881        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
882
[1960]883        const int components = 1;//mNewTexture->GetDepthBits() / 8;
[1953]884
[1964]885        float *data = new float[mTexWidth * mTexHeight * components];
[1953]886        //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV;
887        const int texFormat = GL_DEPTH_COMPONENT;
888        //const int texFormat = GL_RGBA;
889        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
890
891        string filename("depth.tga");
892        ilRegisterType(IL_FLOAT);
893
894        const int depth = 1;
895        const int bpp = components;
896
[1964]897        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data);
[1953]898        ilSaveImage((char *const)filename.c_str());
899
900        cout << "finished" << endl;
901        delete data;
902        cout << "data deleted" << endl;
903        mNewTexture->DisableTextureTarget();
904        PrintGLerror("grab texture");
905}
906
[1958]907
[1960]908void GlobalLinesRenderer::ExportItemBuffer()
909{
910        mNewTexture->Bind();
911        mNewTexture->EnableTextureTarget();
912        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
[1958]913
[1960]914        const int components = 4;//mNewTexture->GetDepthBits() / 8;
[1958]915
[1964]916        unsigned char *data = new unsigned char [mTexWidth * mTexHeight * components];
[1960]917        //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV;
918        const int texFormat = GL_RGBA;
919        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data);
920
921        string filename("items.jpg");
922        ilRegisterType(IL_UNSIGNED_BYTE);
923
924        const int depth = 1;
925        const int bpp = components;
926
[1964]927        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data);
[1960]928        ilSaveImage((char *const)filename.c_str());
929
930        cout << "finished" << endl;
931        delete data;
932        cout << "data deleted" << endl;
933        mNewTexture->DisableTextureTarget();
934        PrintGLerror("grab texture");
935}
936
937
[1964]938void GlobalLinesRenderer::ApplyDepthPeeling(VssRayContainer &rays)
[1958]939{
[1953]940        mNewTexture->BeginCapture();
[1944]941        {
942                //cgGLBindProgram(sCgPassThroughProgram);
943                //cgGLEnableProfile(sCgFragmentProfile);
[1951]944                DrawGeometry();
[1944]945        }
[1953]946        mNewTexture->EndCapture();
[1944]947       
[1951]948        PrintGLerror("firstpass");
[1953]949        if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl;
[1944]950
[1958]951        // process the buffers for the first layer
[1963]952        ProcessDepthBuffer(rays, false, 0);
[1958]953
[1963]954        for(int i = 1; i < mMaxDepth; ++ i)
[1944]955        {
956                // Peel another layer
[1962]957                // switch pointer between rendertextures
958                SwitchRenderTextures();
[1944]959
[1953]960                mNewTexture->BeginCapture();
[1944]961                {
962                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         
963
964                        cgGLBindProgram(sCgDepthPeelingProgram);
965                        cgGLEnableProfile(sCgFragmentProfile);
[1953]966                        cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID());
[1944]967                        cgGLEnableTextureParameter(sTextureParam);
968
[1951]969                        DrawGeometry();
970                       
[1944]971                        cgGLDisableTextureParameter(sTextureParam);
[1949]972                        cgGLDisableProfile(sCgFragmentProfile);
[1944]973                }
[1953]974                mNewTexture->EndCapture();
[1960]975
976                // process the buffers for following layer
[1968]977                // jump out of loop for the first invalid buffer
978                if (!ProcessDepthBuffer(rays, true, i))
979                        break;
[1944]980        }
981
[1951]982        PrintGLerror("endpeeling");
[1944]983}
984
985
986}
Note: See TracBrowser for help on using the repository browser.