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

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