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

Revision 2726, 26.3 KB checked in by mattausch, 16 years ago (diff)

worked on gvs efficiency

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// the devil library
12#include <IL/il.h>
13#include <IL/ilu.h>
14#include <IL/ilut.h>
15
16#ifdef USE_CG
17
18#include <Cg/cg.h>
19#include <Cg/cgGL.h>
20
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                        int invalidSamples = 0;
172                        glStrategy.GenerateSamples(5, simpleRays, invalidSamples);
173
174                        //cout << "simple ray: " << simpleRays[4] << endl;
175                        globalLinesRenderer->CastGlobalLines(simpleRays[1], rays);
176
177                        // visualize
178                        VssRayContainer outRays;
179                        VssRayContainer::const_iterator vit, vit_end = rays.end();
180
181                        const float p = 8.0f / (float)rays.size();
182
183                        for (vit = rays.begin(); vit != vit_end; ++ vit)
184                        {
185                                if (Random(1.0f) < p)
186                                {
187                                        outRays.push_back(*vit);
188                                }
189                        }
190
191                        globalLinesRenderer->Visualize(rays);
192
193                        CLEAR_CONTAINER(rays);
194                        return;
195                }
196        case '8':
197                {
198                        isDepth = !isDepth;
199                        return;
200                }
201        case '9':
202                {
203                        VssRayContainer rays;
204                        globalLinesRenderer->ApplyDepthPeeling(rays);
205
206                        // visualize
207                        VssRayContainer outRays;
208                        VssRayContainer::const_iterator vit, vit_end = rays.end();
209
210                        const float p = 8.0f / (float)rays.size();
211
212                        for (vit = rays.begin(); vit != vit_end; ++ vit)
213                        {
214                                if (Random(1.0f) < p)
215                                {
216                                        outRays.push_back(*vit);
217                                }
218                        }
219
220                        globalLinesRenderer->Visualize(rays);
221                        CLEAR_CONTAINER(rays);
222                        return;
223                }
224        case '0':
225                {
226                        VssRayContainer rays;
227                        globalLinesRenderer->ApplyDepthPeeling(rays);
228                        CLEAR_CONTAINER(rays);
229                        return;
230                }
231        default:
232                return;
233        }
234}
235
236
237GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor,
238                                                                                 const int texHeight,
239                                                                                 const int texWidth,
240                                                                                 const float eps,
241                                                                                 const int maxDepth,
242                                                                                 const bool sampleReverse):
243mNewTexture(NULL),
244mOldTexture(NULL),
245mPreprocessor(preprocessor),
246mTexHeight(texHeight),
247mTexWidth(texWidth),
248mEpsilon(eps),
249mMaxDepth(maxDepth),
250mSampleReverse(sampleReverse)
251{
252        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
253                                                           mPreprocessor->mViewCellsManager,
254                                                           mPreprocessor->mKdTree);
255
256}
257
258
259GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor):
260mNewTexture(NULL),
261mOldTexture(NULL),
262mMaxDepth(40),
263mPreprocessor(preprocessor),
264mTexHeight(128),
265mTexWidth(128),
266mEpsilon(0.0001),
267mSampleReverse(true)
268{
269        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
270                                                           mPreprocessor->mViewCellsManager,
271                                                           mPreprocessor->mKdTree);
272}
273
274
275void GlobalLinesRenderer::DisplayBuffer(const bool isDepth)
276{
277        if (!isDepth)
278                mNewTexture->Bind();
279        else
280                mNewTexture->BindDepth();
281
282        mNewTexture->EnableTextureTarget();
283       
284        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
285       
286        if (mNewTexture->IsRectangleTexture())
287        {
288                glBegin(GL_QUADS);
289                glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
290                glTexCoord2f(mNewTexture->GetWidth(), 0); glVertex3f( 1, -1, -0.5f);
291                glTexCoord2f(mNewTexture->GetWidth(), mNewTexture->GetHeight()); glVertex3f( 1,  1, -0.5f);
292                glTexCoord2f(0, mNewTexture->GetHeight()); glVertex3f(-1, 1, -0.5f);
293                glEnd();
294        }
295        else
296        {
297                glBegin(GL_QUADS);
298                glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
299                glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
300                glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
301                glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
302                glEnd();
303        } 
304
305        mNewTexture->DisableTextureTarget();
306        PrintGLerror("displaytexture");
307}
308
309
310GlobalLinesRenderer::~GlobalLinesRenderer()
311{
312        if (sCgDepthPeelingProgram)
313                cgDestroyProgram(sCgDepthPeelingProgram);
314        if (sCgContext)
315                cgDestroyContext(sCgContext);
316
317        // init the receiving buffers
318        delete mNewDepthBuffer;
319        delete mOldDepthBuffer;
320       
321        delete mNewItemBuffer;
322        delete mOldItemBuffer;
323
324        DEL_PTR(mRenderer);
325}
326
327 
328void GlobalLinesRenderer::InitRenderTexture(RenderTexture *rt)
329{
330         // setup the rendering context for the RenderTexture
331        rt->BeginCapture();
332        {
333                //Reshape(mTexWidth, mTexHeight);
334                glViewport(0, 0, mTexWidth, mTexHeight);
335                SetFrustum(mWidth, mWidth, mNear, mFar);
336
337                // for item buffer: white means no color
338                glClearColor(1, 1, 1, 1);
339                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
340
341                glFrontFace(GL_CCW);
342                glCullFace(GL_BACK);
343
344                glDisable(GL_CULL_FACE);
345                //glEnable(GL_CULL_FACE);
346
347                glShadeModel(GL_FLAT);
348                glEnable(GL_DEPTH_TEST);
349               
350                glMatrixMode(GL_MODELVIEW);
351                glLoadIdentity();
352                gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
353                                  mTermination.x, mTermination.y, mTermination.z,
354                                  mUpVec.x, mUpVec.y, mUpVec.z);
355
356        }
357        rt->EndCapture();
358}
359
360
361void GlobalLinesRenderer::InitScene(const float alpha, const float beta)
362{
363        AxisAlignedBox3 bbox =
364                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
365
366        const float sceneSize = Magnitude(bbox.Diagonal());
367
368        // compute the center of the scene
369        mTermination = bbox.Center();
370       
371        // add a small offset to provide some randomness in the sampling
372        if (0)
373        {
374                Vector3 offset(
375                        Random(sceneSize * 1e-3f),
376                        Random(sceneSize * 1e-3f),
377                        Random(sceneSize * 1e-3f));
378
379                mTermination += offset;
380        }
381               
382        mNear = 1;
383        mFar = sceneSize * 2;
384        mWidth = sceneSize;
385
386        ComputeLookAt(alpha,
387                                  beta,
388                                  mEyeVec,
389                                  mUpVec,
390                                  mLeftVec);
391       
392        mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec;
393
394        //cout << "termination point: " << mTermination << endl;
395        //cout << "view point: " << mViewPoint << endl;
396        //cout << "scene: " << bbox << endl;
397
398        InitRenderTexture(mNewTexture);
399        InitRenderTexture(mOldTexture);
400       
401        //cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
402}
403
404
405void GlobalLinesRenderer::InitScene(const SimpleRay &ray)
406{
407        AxisAlignedBox3 bbox =
408                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
409       
410        const float sceneSize = Magnitude(bbox.Diagonal());
411
412        // compute the center of the scene
413        mViewPoint = ray.mOrigin;
414        mTermination = ray.mOrigin + ray.mDirection;
415
416        mEyeVec = Normalize(ray.mDirection);
417
418        mNear = 1;
419        mFar = sceneSize * 2;
420        mWidth = sceneSize;
421
422        mEyeVec.RightHandedBase(mUpVec, mLeftVec);
423
424        //cout << "termination point: " << mTermination << endl;
425        //cout << "view point: " << mViewPoint << endl;
426        //cout << "scene: " << bbox << endl;
427
428        InitRenderTexture(mNewTexture);
429        InitRenderTexture(mOldTexture);
430       
431        //cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
432}
433
434
435int GlobalLinesRenderer::CastGlobalLines(const float alpha,
436                                                                                  const float beta,
437                                                                                  VssRayContainer &rays)
438{
439        InitScene(alpha, beta);
440
441        // bind pixel shader implementing the front depth buffer functionality
442        const int layers = ApplyDepthPeeling(rays);
443
444        return layers;
445}
446
447
448int GlobalLinesRenderer::CastGlobalLines(const SimpleRay &ray,
449                                                                                  VssRayContainer &rays)
450{
451        const long startTime = GetTime();
452        cout << "casting global lines ... " << endl;
453
454        InitScene(ray);
455
456        // bind pixel shader implementing the front depth buffer functionality
457        const int layers = ApplyDepthPeeling(rays);
458
459        const float rays_per_sec = (float)rays.size() / (TimeDiff(startTime, GetTime()) * 1e-3f);
460        cout << "cast " << rays.size() << " samples in " << layers << " layers in "
461                 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs (" << rays_per_sec << " rays/sec)" << endl;
462
463        return layers;
464}
465
466
467void GlobalLinesRenderer::DrawGeometry()
468{
469        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
470        glMatrixMode(GL_MODELVIEW);
471
472        glPushMatrix();
473        {
474                //glLoadIdentity();
475                Intersectable::NewMail();
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        cout << "texwidth: " << mTexWidth << " texheight: " << mTexHeight << endl;
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
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        }
635
636        const float alpha = 1.1;
637        const float beta = 0.9;
638
639        InitScene(alpha, beta);
640
641        PrintGLerror("init");
642}
643
644
645Intersectable *GlobalLinesRenderer::ExtractSamplePoint(float *depthBuffer,
646                                                                                                           unsigned char *itemBuffer,
647                                                                                                           const int x,
648                                                                                                           const int y,
649                                                                                                           Vector3 &hitPoint,
650                                                                                                           const bool isFrontBuffer) const
651{
652        const int depthIndex = x + mTexWidth * y;
653        const int itemIndex = 4 * depthIndex;
654
655        const float depth = depthBuffer[depthIndex];
656        const float eyeDist = mNear + (mFar - mNear) * depth;
657       
658        const float leftDist = -0.5f * mWidth + mWidth * ((float)x + 0.5f) / mTexWidth;
659        const float upDist   = -0.5f * mWidth + mWidth * ((float)y + 0.5f) / mTexHeight;
660
661        hitPoint = mViewPoint +
662                       eyeDist * mEyeVec +
663                           upDist * mUpVec +
664                           leftDist * mLeftVec;
665                               
666        unsigned char r = itemBuffer[itemIndex];
667        unsigned char g = itemBuffer[itemIndex + 1];
668        unsigned char b = itemBuffer[itemIndex + 2];
669                       
670        // 3 times 255 means no valid object
671        if ((r == 255) && (g == 255) && (b == 255))
672                return NULL;
673
674        const int id = mRenderer->GetId(r, g, b);
675        //cout << "r: " << (int)r << "g: " << (int)g << " b: " << (int)b << " id: " << id << "|";
676        Intersectable *intersect = mPreprocessor->GetObjectById(id);
677
678        const Vector3 dir = isFrontBuffer ? mEyeVec : -mEyeVec;
679        // HACK: assume triangle intersectable
680        const Vector3 norm = intersect->GetNormal(0);
681
682        // test for invalid view space
683        if (DotProd(dir, norm) >= -Limits::Small)
684                return NULL;
685
686        return intersect;
687}
688
689
690void GlobalLinesRenderer::ComputeBoundingQuad(int &xMin,
691                                                                                          int &yMin,
692                                                                                          int &xMax,
693                                                                                          int &yMax)
694{
695        const AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox();
696
697        Matrix4x4 m(mEyeVec, mUpVec, mLeftVec);
698
699        m.Invert();
700
701        Vector3 eye(m.x[0][0], m.x[1][0], m.x[2][0]);
702        Vector3 up(m.x[0][0], m.x[1][1], m.x[2][1]);
703        Vector3 left(m.x[0][2], m.x[1][2], m.x[2][2]);
704
705        Vector3 boxMin(1e20f);
706        Vector3 boxMax(-1e20f);
707       
708        for (int i = 0; i < 8; ++ i)
709        {
710        Vector3 vtx;
711
712                bbox.GetVertex(i, vtx);
713
714                Vector3 pt = vtx.x * eye + vtx.y * up + vtx.z * left;
715
716                // TODO
717                if (boxMin.x > pt.x)
718                        boxMin.x = pt.x;
719               
720                if (boxMin.y > pt.y)
721                        boxMin.y = pt.y;
722
723                if (boxMin.z > pt.z)
724                        boxMin.z = pt.z;
725
726                if (boxMax.x < pt.x)
727                        boxMax.x = pt.x;
728               
729                if (boxMax.y < pt.y)
730                        boxMax.y = pt.y;
731
732                if (boxMax.z < pt.z)
733                        boxMax.z = pt.z;
734        }
735
736        cout << "xmin: " << boxMin.x << " ymin " << boxMin.y << " xmax: " << boxMax.x << " ymax: " << boxMax.y << endl;
737
738        xMin = (int)(-0.5f * mWidth + mWidth * (boxMin.x + 0.5f) / mTexWidth);
739        yMin = (int)(-0.5f * mWidth + mWidth * (boxMin.y + 0.5f) / mTexHeight);
740        xMax = (int)(-0.5f * mWidth + mWidth * (boxMax.x + 0.5f) / mTexWidth);
741        yMax = (int)(-0.5f * mWidth + mWidth * (boxMax.y + 0.5f) / mTexHeight);
742}
743
744
745bool GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays,
746                                                                                         const bool oldBufferInitialised,
747                                                                                         const int pass)
748{
749        GrabDepthBuffer(mNewDepthBuffer, mNewTexture);
750        GrabItemBuffer(mNewItemBuffer, mNewTexture);
751
752        if (oldBufferInitialised)
753        {
754                GrabDepthBuffer(mOldDepthBuffer, mOldTexture);
755                GrabItemBuffer(mOldItemBuffer, mOldTexture);
756        }
757        else
758        {
759                for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
760                {
761                        mOldDepthBuffer[i] = 0;
762
763                        mOldItemBuffer[i * 4]     = 255;
764                        mOldItemBuffer[i * 4 + 1] = 255;
765                        mOldItemBuffer[i * 4 + 2] = 255;
766                        mOldItemBuffer[i * 4 + 3] = 255;
767                }
768        }
769
770        int xMin, yMin, xMax, yMax;
771        ComputeBoundingQuad(xMin, yMin, xMax, yMax);
772       
773        cout << "xmin2: " << xMin << " ymin " << yMin << " xmax: " << xMax << " ymax: " << yMax << endl;
774
775        /////////////////
776        // test for validity
777
778        bool buffersEqual = true;
779        bool bufferEmpty = true;
780
781        for (int y = 0; y < mTexHeight; ++ y)
782        {
783                for (int x = 0; x < mTexWidth; ++ x)
784                {
785                        const int depthIndex = x + mTexWidth * y;   
786                        const int itemIndex = 4 * depthIndex;
787               
788                        if (mOldItemBuffer[itemIndex] != mNewItemBuffer[itemIndex])
789                        {
790                                buffersEqual = false;
791                        }
792
793                        unsigned char r = mNewItemBuffer[itemIndex];
794                        unsigned char g = mNewItemBuffer[itemIndex + 1];
795                        unsigned char b = mNewItemBuffer[itemIndex + 2];
796
797                        // 3 times 255 means no valid object
798                        if (!((r == 255) && (g == 255) && (b == 255)))
799                        {
800                                bufferEmpty = false;
801                        }
802                }
803               
804                // early exit
805                if (!buffersEqual && !bufferEmpty)
806                        break;
807        }
808
809        // depth buffer not valid
810        if (buffersEqual || bufferEmpty)
811        {
812                cout << "stopped at layer " << pass << endl;
813                return false;
814        }
815
816        for (int y = 0; y < mTexHeight; ++ y)
817        {
818                for (int x = 0; x < mTexWidth; ++ x)
819                {
820                        Vector3 newPt, oldPt;
821
822                        Intersectable *termObj1 = ExtractSamplePoint(mNewDepthBuffer,
823                                                                                                                 mNewItemBuffer,
824                                                                                                                 x,
825                                                                                                                 y,
826                                                                                                                 newPt,
827                                                                                                                 true);
828
829                        Intersectable *termObj2 = ExtractSamplePoint(mOldDepthBuffer,
830                                                                                                                 mOldItemBuffer,
831                                                                                                                 x,
832                                                                                                                 y,
833                                                                                                                 oldPt,
834                                                                                                                 false);
835
836                        if (!termObj1 && !termObj2) // we do not create a ray
837                                continue;
838
839                        Vector3 clippedOldPt, clippedNewPt;
840
841                        if (ClipToViewSpaceBox(oldPt, newPt, clippedOldPt, clippedNewPt))//;if(1)
842                        {
843                                //clippedOldPt = oldPt;
844                                //clippedNewPt = newPt;
845
846                                // create rays in both directions
847                                if (termObj1)
848                                {
849                                        vssRays.push_back(new VssRay(clippedOldPt, clippedNewPt, NULL, termObj1, pass));
850                                        //cout << "new pt: " << newPt << endl;
851                                }
852
853                                if (mSampleReverse && termObj2)
854                                {
855                                        vssRays.push_back(new VssRay(clippedNewPt, clippedOldPt, NULL, termObj2, pass));
856                                        //cout << "old pt: " << oldPt << endl;
857                                }
858                        }
859                }
860        }
861
862        return true;
863}
864
865
866bool GlobalLinesRenderer::ClipToViewSpaceBox(const Vector3 &origin,
867                                                                                         const Vector3 &termination,
868                                                                                         Vector3 &clippedOrigin,
869                                                                                         Vector3 &clippedTermination)
870{
871        Ray ray(origin, termination - origin, Ray::LINE_SEGMENT);       
872        ray.Precompute();
873       
874        float tmin, tmax;
875       
876        //const AxisAlignedBox3 bbox = mPreprocessor->mViewCellsManager->GetViewSpaceBox();
877        // hack
878        AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox();
879
880        //bbox.Enlarge(1);
881        if (!bbox.ComputeMinMaxT(ray, &tmin, &tmax) || (tmin >= tmax))
882        {
883                return false;
884        }
885       
886        if (tmin >= 1.0f || tmax <= 0.0f)
887                return false;
888
889        if (tmin > 0.0f)
890                clippedOrigin = ray.Extrap(tmin);
891        else
892                clippedOrigin = origin;
893
894        if (tmax < 1.0f)
895                clippedTermination = ray.Extrap(tmax);
896        else
897                clippedTermination = termination;
898
899        return true;
900}
901
902
903void GlobalLinesRenderer::Run()
904{
905        glutMainLoop();
906}
907
908
909void GlobalLinesRenderer::Visualize(const VssRayContainer &vssRays)
910{
911        cout << "exporting visualization ... ";
912        Exporter *exporter = Exporter::GetExporter("globalLines.wrl");
913       
914        if (!exporter)
915                return;
916
917        exporter->SetWireframe();
918        //exporter->ExportGeometry(preprocessor->mObjects);
919        exporter->SetFilled();
920
921        VssRayContainer::const_iterator vit, vit_end = vssRays.end();
922        VssRayContainer outRays;
923
924        Intersectable::NewMail();
925
926        for (vit = vssRays.begin(); vit != vit_end; ++ vit)
927        {
928                VssRay *ray = *vit;
929                Intersectable *obj = (*vit)->mTerminationObject;
930
931                if (!obj->Mailed())
932                {
933                        obj->Mail();
934                        exporter->ExportIntersectable(obj);
935                }
936
937                //if (ray->mPass == 4)
938                        outRays.push_back(ray);
939        }       
940
941        //exporter->ExportRays(outRays);
942        cout << "finished" << endl;
943        delete exporter;
944}
945
946
947void GlobalLinesRenderer::GrabDepthBuffer(float *data, RenderTexture *rt)
948{
949        rt->BindDepth();
950        rt->EnableTextureTarget();
951
952        const int texFormat = GL_DEPTH_COMPONENT;
953        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
954
955        mNewTexture->DisableTextureTarget();
956}
957
958
959void GlobalLinesRenderer::GrabItemBuffer(unsigned char *data, RenderTexture *rt)
960{
961        rt->Bind();
962        rt->EnableTextureTarget();
963
964        const int texFormat = GL_RGBA;
965        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data);
966
967        mNewTexture->DisableTextureTarget();
968}
969
970
971void GlobalLinesRenderer::ExportDepthBuffer()
972{
973        mNewTexture->BindDepth();
974        mNewTexture->EnableTextureTarget();
975        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
976
977        const int components = 1;//mNewTexture->GetDepthBits() / 8;
978
979        float *data = new float[mTexWidth * mTexHeight * components];
980        //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV;
981        const int texFormat = GL_DEPTH_COMPONENT;
982        //const int texFormat = GL_RGBA;
983        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
984
985        string filename("depth.tga");
986        ilRegisterType(IL_FLOAT);
987
988        const int depth = 1;
989        const int bpp = components;
990
991        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data);
992        ilSaveImage((char *const)filename.c_str());
993
994        cout << "finished" << endl;
995        delete data;
996        cout << "data deleted" << endl;
997        mNewTexture->DisableTextureTarget();
998        PrintGLerror("grab texture");
999}
1000
1001
1002void GlobalLinesRenderer::ExportItemBuffer()
1003{
1004        mNewTexture->Bind();
1005        mNewTexture->EnableTextureTarget();
1006        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
1007
1008        const int components = 4;//mNewTexture->GetDepthBits() / 8;
1009
1010        unsigned char *data = new unsigned char [mTexWidth * mTexHeight * components];
1011        //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV;
1012        const int texFormat = GL_RGBA;
1013        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data);
1014
1015        string filename("items.jpg");
1016        ilRegisterType(IL_UNSIGNED_BYTE);
1017
1018        const int depth = 1;
1019        const int bpp = components;
1020
1021        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data);
1022        ilSaveImage((char *const)filename.c_str());
1023
1024        cout << "finished" << endl;
1025        delete data;
1026        cout << "data deleted" << endl;
1027        mNewTexture->DisableTextureTarget();
1028        PrintGLerror("grab texture");
1029}
1030
1031
1032int GlobalLinesRenderer::ApplyDepthPeeling(VssRayContainer &rays)
1033{
1034        int layers = 1;
1035
1036        mNewTexture->BeginCapture();
1037        {
1038                //cgGLBindProgram(sCgPassThroughProgram);
1039                //cgGLEnableProfile(sCgFragmentProfile);
1040                DrawGeometry();
1041        }
1042        mNewTexture->EndCapture();
1043       
1044        PrintGLerror("firstpass");
1045        if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl;
1046
1047        // process the buffers for the first layer
1048        ProcessDepthBuffer(rays, false, 0);
1049
1050        long renderTime = 0;
1051        long bufferTime = 0;
1052
1053        for(; layers < mMaxDepth; ++ layers)
1054        {
1055                cout << ".";
1056                const long startRenderTime = GetTime();
1057
1058                // Peel another layer
1059                // switch pointer between rendertextures
1060                SwitchRenderTextures();
1061
1062                mNewTexture->BeginCapture();
1063                {
1064                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         
1065
1066                        cgGLBindProgram(sCgDepthPeelingProgram);
1067                        cgGLEnableProfile(sCgFragmentProfile);
1068                        cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID());
1069                        cgGLEnableTextureParameter(sTextureParam);
1070
1071                        DrawGeometry();
1072                       
1073                        cgGLDisableTextureParameter(sTextureParam);
1074                        cgGLDisableProfile(sCgFragmentProfile);
1075                }
1076                mNewTexture->EndCapture();
1077
1078                renderTime += TimeDiff(startRenderTime, GetTime());
1079
1080                const long startBufferTime = GetTime();
1081
1082                // process the buffers for following layer
1083                // jump out of loop for the first invalid buffer
1084                if (!ProcessDepthBuffer(rays, true, layers))
1085                        break;
1086
1087                bufferTime += TimeDiff(startBufferTime, GetTime());
1088        }
1089
1090        Debug << "time spent in rendering: " << renderTime * 1e-3f << endl;
1091        Debug << "time spent in buffer: " << bufferTime * 1e-3f << endl;
1092       
1093        PrintGLerror("endpeeling");
1094
1095        return layers;
1096}
1097
1098}
1099
1100#endif
Note: See TracBrowser for help on using the repository browser.