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

Line 
1#include "glInterface.h"
2#include "GlobalLinesRenderer.h"
3#include "common.h"
4#include "RenderTexture.h"
5#include "Preprocessor.h"
6#include "GlRenderer.h"
7#include "Exporter.h"
8#include "ViewCellsManager.h"
9
10
11// the devil library
12#include <IL/il.h>
13#include <IL/ilu.h>
14#include <IL/ilut.h>
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;
30static CGparameter sTexWidthParam;
31static CGparameter sStepSizeParam;
32
33GlobalLinesRenderer *globalLinesRenderer = NULL;
34
35static bool isDepth = true;
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
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
89        //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 3, 5000.0);
90        //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.5, 10.0);
91        glOrtho(-1, 1, -1, 1, 0.5, 15);
92}
93
94
95void SetFrustum(const int sizeX, const int sizeY,
96                                const float nearPlane, const float farPlane)
97{
98        glMatrixMode(GL_PROJECTION);
99        glLoadIdentity();
100
101        glOrtho(-sizeX * 0.5, sizeX * 0.5,
102                        -sizeY * 0.5, sizeY * 0.5,
103                        nearPlane, farPlane);
104
105        /*glOrtho(0, sizeX,
106                    0, sizeY ,
107                        nearPlane, farPlane);*/
108}
109
110void Display()
111{
112        //globalLinesRenderer->DrawGeometry();
113        //globalLinesRenderer->CastGlobalLines(Beam(), 0);
114        globalLinesRenderer->DisplayBuffer(isDepth);
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        {
131        case '2':
132                {
133                        VssRayContainer rays;
134
135                        ++ globalLinesRenderer->mMaxDepth;
136                        globalLinesRenderer->ApplyDepthPeeling(rays);
137
138                        cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl;
139                        CLEAR_CONTAINER(rays);
140                        return;
141                }
142        case '1':
143                {
144                        VssRayContainer rays;
145
146                        -- globalLinesRenderer->mMaxDepth;
147                        cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl;
148                       
149                        globalLinesRenderer->ApplyDepthPeeling(rays);
150                        CLEAR_CONTAINER(rays);
151                        return;
152                }
153        case '3':
154                {
155                        globalLinesRenderer->ExportDepthBuffer();
156                        return;
157                }
158        case '4':
159                {
160                        globalLinesRenderer->ExportItemBuffer();
161                        return;
162                }
163        case '8':
164                {
165                        isDepth = !isDepth;
166                        return;
167                }
168        case '9':
169                {
170                        VssRayContainer rays;
171                        globalLinesRenderer->ApplyDepthPeeling(rays);
172                        VssRayContainer outRays;
173                        VssRayContainer::const_iterator vit, vit_end = rays.end();
174
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;
192                        globalLinesRenderer->ApplyDepthPeeling(rays);
193                        CLEAR_CONTAINER(rays);
194                        return;
195                }
196        default:
197                return;
198        }
199}
200
201
202GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor,
203                                                                                 const int texHeight,
204                                                                                 const int texWidth,
205                                                                                 const float eps,
206                                                                                 const int maxDepth,
207                                                                                 const bool sampleReverse):
208mNewTexture(NULL),
209mOldTexture(NULL),
210mPreprocessor(preprocessor),
211mTexHeight(mTexHeight),
212mTexWidth(mTexWidth),
213mEpsilon(eps),
214mMaxDepth(maxDepth),
215mSampleReverse(sampleReverse)
216{
217        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
218                                                           mPreprocessor->mViewCellsManager,
219                                                           mPreprocessor->mKdTree);
220
221}
222
223
224GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor):
225mNewTexture(NULL),
226mOldTexture(NULL),
227mMaxDepth(40),
228mPreprocessor(preprocessor),
229mTexHeight(128),
230mTexWidth(128),
231mEpsilon(0.0001),
232mSampleReverse(true)
233{
234        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
235                                                           mPreprocessor->mViewCellsManager,
236                                                           mPreprocessor->mKdTree);
237}
238
239
240void GlobalLinesRenderer::DisplayBuffer(const bool isDepth)
241{
242        if (!isDepth)
243                mNewTexture->Bind();
244        else
245                mNewTexture->BindDepth();
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
274GlobalLinesRenderer::~GlobalLinesRenderer()
275{
276        if (sCgDepthPeelingProgram)
277                cgDestroyProgram(sCgDepthPeelingProgram);
278        if (sCgContext)
279                cgDestroyContext(sCgContext);
280
281        // init the receiving buffers
282        delete mNewDepthBuffer;
283        delete mOldDepthBuffer;
284       
285        delete mNewItemBuffer;
286        delete mOldItemBuffer;
287
288        DEL_PTR(mRenderer);
289}
290
291 
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
325void GlobalLinesRenderer::InitScene(const float alpha, const float beta)
326{
327        AxisAlignedBox3 bbox =
328                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
329       
330        const float sceneSize = Magnitude(bbox.Diagonal());
331
332        // compute the center of the scene
333        mTermination = bbox.Center();
334       
335        // add a small offset to provide some randomness in the sampling
336        if (0)
337        {
338                Vector3 offset(
339                        Random(sceneSize * 1e-3f),
340                        Random(sceneSize * 1e-3f),
341                        Random(sceneSize * 1e-3f));
342
343                mTermination += offset;
344        }
345               
346        mNear = 1;
347        mFar = sceneSize * 2;
348        mWidth = sceneSize;
349
350        ComputeLookAt(alpha,
351                                  beta,
352                                  mEyeVec,
353                                  mUpVec,
354                                  mLeftVec);
355       
356        mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec;
357
358        cout << "termination point: " << mTermination << endl;
359        cout << "view point: " << mViewPoint << endl;
360        cout << "scene: " << bbox << endl;
361
362        InitRenderTexture(mNewTexture);
363        InitRenderTexture(mOldTexture);
364       
365        cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
366}
367
368
369void GlobalLinesRenderer::InitScene(const SimpleRay &ray)
370{
371        AxisAlignedBox3 bbox =
372                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
373       
374        const float sceneSize = Magnitude(bbox.Diagonal());
375
376        // compute the center of the scene
377        mViewPoint = ray.mOrigin;
378        mTermination = ray.mOrigin + ray.mDirection;
379
380        mEyeVec = Normalize(ray.mDirection);
381
382        mNear = 1;
383        mFar = sceneSize * 2;
384        mWidth = sceneSize;
385
386        mEyeVec.RightHandedBase(mUpVec, mLeftVec);
387    mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec;
388
389        cout << "termination point: " << mTermination << endl;
390        cout << "view point: " << mViewPoint << endl;
391        cout << "scene: " << bbox << endl;
392
393        InitRenderTexture(mNewTexture);
394        InitRenderTexture(mOldTexture);
395       
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
407        // bind pixel shader implementing the front depth buffer functionality
408        ApplyDepthPeeling(rays);
409}
410
411
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
421void GlobalLinesRenderer::RenderObject(Intersectable *obj)
422{
423        mRenderer->RenderIntersectable(obj);
424}
425
426
427void GlobalLinesRenderer::DrawGeometry()
428{
429        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
430        glMatrixMode(GL_MODELVIEW);
431
432        glPushMatrix();
433        {
434                //glLoadIdentity();
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                {
441                        //cout << (*oit)->GetId() << " ";
442                        RenderObject(*oit);
443                }
444        }
445        glPopMatrix();
446}
447
448
449void GlobalLinesRenderer::SwitchRenderTextures()
450{
451        RenderTexture *buffer = mOldTexture;
452        mOldTexture = mNewTexture;
453        mNewTexture = buffer;
454}
455
456
457void GlobalLinesRenderer::ComputeLookAt(const float alpha,
458                                                                                const float beta,
459                                                                                Vector3 &eye,
460                                                                                Vector3 &up,
461                                                                                Vector3 &left)
462{
463        eye.x = sin(alpha) * cos(beta);
464        eye.y = sin(alpha) * sin(beta);
465        eye.z = cos(alpha);
466
467        eye.RightHandedBase(up, left);
468}
469
470
471void GlobalLinesRenderer::InitGl()
472{
473        InitDevIl();
474
475    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
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
497        // initialise the receiving buffers
498        mNewDepthBuffer = new float[mTexWidth * mTexHeight];
499        mNewItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4];
500
501        mOldDepthBuffer = new float[mTexWidth * mTexHeight];
502    mOldItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4];
503
504        for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
505        {
506                mNewDepthBuffer[i] = 1;
507                mOldDepthBuffer[i] = 1;
508
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;
518        }
519
520        /*gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
521                          midPoint.x, midPoint.y, midPoint.z,
522                          0, 1, 0);
523*/
524        gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
525
526        //glDisable(GL_CULL_FACE);
527        glEnable(GL_CULL_FACE);
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       
537        mNewTexture = new RenderTexture(mTexWidth, mTexHeight, true, true);
538#ifdef ATI
539        mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
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
547        mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
548#else
549        mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
550#endif
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,
567                                                                mNewTexture->IsRectangleTexture() ?
568                                                                "../src/depth_peelingRect.cg" : "../src/depth_peeling2d.cg",
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"); 
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);
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
603        const float alpha = 1.1;
604        const float beta = 0.9;
605        InitScene(alpha, beta);
606
607        PrintGLerror("init");
608}
609
610
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
617{
618        const int depthIndex = x + mTexWidth * y;
619        const int itemIndex = 4 * depthIndex;
620
621        const float depth = depthBuffer[depthIndex];
622        const float eyeDist = mNear + (mFar - mNear) * depth;
623       
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;
626       
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
630        hitPoint = mViewPoint +
631                       eyeDist * mEyeVec +
632                           upDist * mUpVec +
633                           leftDist * mLeftVec;
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
651        // test for invalid view space
652        if (DotProd(dir, norm) >= -Limits::Small)
653                return NULL;
654
655        return intersect;
656}
657
658
659bool GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays,
660                                                                                         const bool oldBufferInitialised,
661                                                                                         const int pass)
662{
663        GrabDepthBuffer(mNewDepthBuffer, mNewTexture);
664        GrabItemBuffer(mNewItemBuffer, mNewTexture);
665
666        if (oldBufferInitialised)
667        {
668                GrabDepthBuffer(mOldDepthBuffer, mOldTexture);
669                GrabItemBuffer(mOldItemBuffer, mOldTexture);
670        }
671        else
672        {
673                for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
674                {
675                        mOldDepthBuffer[i] = 0;
676
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        }
683
684        /////////////////
685        // test for validity
686
687        bool buffersEqual = true;
688        bool bufferEmpty = true;
689
690        for (int y = 0; y < mTexHeight; ++ y)
691        {
692                for (int x = 0; x < mTexWidth; ++ x)
693                {
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                {
729                        Vector3 newPt, oldPt;
730
731                        Intersectable *termObj1 = ExtractSamplePoint(mNewDepthBuffer,
732                                                                                                                 mNewItemBuffer,
733                                                                                                                 x,
734                                                                                                                 y,
735                                                                                                                 newPt,
736                                                                                                                 true);
737
738                        Intersectable *termObj2 = ExtractSamplePoint(mOldDepthBuffer,
739                                                                                                                 mOldItemBuffer,
740                                                                                                                 x,
741                                                                                                                 y,
742                                                                                                                 oldPt,
743                                                                                                                 false);
744
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
754                        // create rays in both directions
755                        if (termObj1)
756                        {
757                                vssRays.push_back(new VssRay(clippedOldPt, clippedNewPt, NULL, termObj1, pass));
758                                //cout << "new pt: " << newPt << endl;
759                        }
760
761                        if (mSampleReverse && termObj2)
762                        {
763                                vssRays.push_back(new VssRay(clippedNewPt, clippedOldPt, NULL, termObj2, pass));
764                                //cout << "old pt: " << oldPt << endl;
765                        }
766                }
767        }
768
769        return true;
770}
771
772
773bool GlobalLinesRenderer::ClipToViewSpaceBox(const Vector3 &origin,
774                                                                                         const Vector3 &termination,
775                                                                                         Vector3 &clippedOrigin,
776                                                                                         Vector3 &clippedTermination)
777{
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;
807}
808
809
810void GlobalLinesRenderer::Run()
811{
812        glutMainLoop();
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();
828        VssRayContainer outRays;
829
830        Intersectable::NewMail();
831
832        for (vit = vssRays.begin(); vit != vit_end; ++ vit)
833        {
834                VssRay *ray = *vit;
835                Intersectable *obj = (*vit)->mTerminationObject;
836
837                if (!obj->Mailed())
838                {
839                        obj->Mail();
840                        exporter->ExportIntersectable(obj);
841                }
842
843                //if (ray->mPass == 4)
844                        outRays.push_back(ray);
845        }       
846
847        exporter->ExportRays(outRays);
848
849        delete exporter;
850}
851
852
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
865void GlobalLinesRenderer::GrabItemBuffer(unsigned char *data, RenderTexture *rt)
866{
867        rt->Bind();
868        rt->EnableTextureTarget();
869
870        const int texFormat = GL_RGBA;
871        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data);
872
873        mNewTexture->DisableTextureTarget();
874}
875
876
877void GlobalLinesRenderer::ExportDepthBuffer()
878{
879        mNewTexture->BindDepth();
880        mNewTexture->EnableTextureTarget();
881        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
882
883        const int components = 1;//mNewTexture->GetDepthBits() / 8;
884
885        float *data = new float[mTexWidth * mTexHeight * components];
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
897        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data);
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
907
908void GlobalLinesRenderer::ExportItemBuffer()
909{
910        mNewTexture->Bind();
911        mNewTexture->EnableTextureTarget();
912        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
913
914        const int components = 4;//mNewTexture->GetDepthBits() / 8;
915
916        unsigned char *data = new unsigned char [mTexWidth * mTexHeight * components];
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
927        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data);
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
938void GlobalLinesRenderer::ApplyDepthPeeling(VssRayContainer &rays)
939{
940        mNewTexture->BeginCapture();
941        {
942                //cgGLBindProgram(sCgPassThroughProgram);
943                //cgGLEnableProfile(sCgFragmentProfile);
944                DrawGeometry();
945        }
946        mNewTexture->EndCapture();
947       
948        PrintGLerror("firstpass");
949        if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl;
950
951        // process the buffers for the first layer
952        ProcessDepthBuffer(rays, false, 0);
953
954        for(int i = 1; i < mMaxDepth; ++ i)
955        {
956                // Peel another layer
957                // switch pointer between rendertextures
958                SwitchRenderTextures();
959
960                mNewTexture->BeginCapture();
961                {
962                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         
963
964                        cgGLBindProgram(sCgDepthPeelingProgram);
965                        cgGLEnableProfile(sCgFragmentProfile);
966                        cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID());
967                        cgGLEnableTextureParameter(sTextureParam);
968
969                        DrawGeometry();
970                       
971                        cgGLDisableTextureParameter(sTextureParam);
972                        cgGLDisableProfile(sCgFragmentProfile);
973                }
974                mNewTexture->EndCapture();
975
976                // process the buffers for following layer
977                // jump out of loop for the first invalid buffer
978                if (!ProcessDepthBuffer(rays, true, i))
979                        break;
980        }
981
982        PrintGLerror("endpeeling");
983}
984
985
986}
Note: See TracBrowser for help on using the repository browser.