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

Revision 1969, 24.6 KB checked in by mattausch, 17 years ago (diff)

global lines nearly useable!

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