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

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

worked on gvs efficiency

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;
[2726]171                        int invalidSamples = 0;
172                        glStrategy.GenerateSamples(5, simpleRays, invalidSamples);
[1969]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                }
[1960]196        case '8':
197                {
198                        isDepth = !isDepth;
199                        return;
200                }
201        case '9':
202                {
[1958]203                        VssRayContainer rays;
[1964]204                        globalLinesRenderer->ApplyDepthPeeling(rays);
[1969]205
206                        // visualize
[1960]207                        VssRayContainer outRays;
208                        VssRayContainer::const_iterator vit, vit_end = rays.end();
[1958]209
[1960]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;
[1964]227                        globalLinesRenderer->ApplyDepthPeeling(rays);
[1960]228                        CLEAR_CONTAINER(rays);
[1958]229                        return;
230                }
[1944]231        default:
232                return;
233        }
234}
235
[1953]236
[1949]237GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor,
[1968]238                                                                                 const int texHeight,
239                                                                                 const int texWidth,
240                                                                                 const float eps,
241                                                                                 const int maxDepth,
242                                                                                 const bool sampleReverse):
[1953]243mNewTexture(NULL),
244mOldTexture(NULL),
[1964]245mPreprocessor(preprocessor),
[1969]246mTexHeight(texHeight),
247mTexWidth(texWidth),
[1968]248mEpsilon(eps),
249mMaxDepth(maxDepth),
250mSampleReverse(sampleReverse)
[1944]251{
[1968]252        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
253                                                           mPreprocessor->mViewCellsManager,
254                                                           mPreprocessor->mKdTree);
255
[1944]256}
257
258
[1968]259GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor):
[1964]260mNewTexture(NULL),
261mOldTexture(NULL),
[1968]262mMaxDepth(40),
[1964]263mPreprocessor(preprocessor),
264mTexHeight(128),
265mTexWidth(128),
[1968]266mEpsilon(0.0001),
267mSampleReverse(true)
268{
269        mRenderer = new GlRenderer(mPreprocessor->mSceneGraph,
270                                                           mPreprocessor->mViewCellsManager,
271                                                           mPreprocessor->mKdTree);
272}
[1964]273
274
[1960]275void GlobalLinesRenderer::DisplayBuffer(const bool isDepth)
[1958]276{
[1960]277        if (!isDepth)
278                mNewTexture->Bind();
279        else
280                mNewTexture->BindDepth();
[1970]281
[1958]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
[1944]310GlobalLinesRenderer::~GlobalLinesRenderer()
311{
312        if (sCgDepthPeelingProgram)
313                cgDestroyProgram(sCgDepthPeelingProgram);
314        if (sCgContext)
315                cgDestroyContext(sCgContext);
[1958]316
317        // init the receiving buffers
318        delete mNewDepthBuffer;
319        delete mOldDepthBuffer;
320       
321        delete mNewItemBuffer;
322        delete mOldItemBuffer;
[1968]323
324        DEL_PTR(mRenderer);
[1944]325}
326
327 
[1968]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
[1964]361void GlobalLinesRenderer::InitScene(const float alpha, const float beta)
[1944]362{
[1968]363        AxisAlignedBox3 bbox =
364                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
[1970]365
[1964]366        const float sceneSize = Magnitude(bbox.Diagonal());
[1958]367
[1964]368        // compute the center of the scene
[1968]369        mTermination = bbox.Center();
[1964]370       
371        // add a small offset to provide some randomness in the sampling
[1968]372        if (0)
373        {
374                Vector3 offset(
375                        Random(sceneSize * 1e-3f),
376                        Random(sceneSize * 1e-3f),
377                        Random(sceneSize * 1e-3f));
[1964]378
[1968]379                mTermination += offset;
380        }
[1964]381               
382        mNear = 1;
383        mFar = sceneSize * 2;
384        mWidth = sceneSize;
385
386        ComputeLookAt(alpha,
387                                  beta,
388                                  mEyeVec,
389                                  mUpVec,
390                                  mLeftVec);
391       
[1968]392        mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec;
[1964]393
[1969]394        //cout << "termination point: " << mTermination << endl;
395        //cout << "view point: " << mViewPoint << endl;
396        //cout << "scene: " << bbox << endl;
[1964]397
[1968]398        InitRenderTexture(mNewTexture);
399        InitRenderTexture(mOldTexture);
400       
[1969]401        //cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
[1968]402}
[1964]403
404
[1968]405void GlobalLinesRenderer::InitScene(const SimpleRay &ray)
406{
407        AxisAlignedBox3 bbox =
408                globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
409       
410        const float sceneSize = Magnitude(bbox.Diagonal());
[1964]411
[1968]412        // compute the center of the scene
413        mViewPoint = ray.mOrigin;
414        mTermination = ray.mOrigin + ray.mDirection;
[1964]415
[1968]416        mEyeVec = Normalize(ray.mDirection);
[1964]417
[1968]418        mNear = 1;
419        mFar = sceneSize * 2;
420        mWidth = sceneSize;
[1964]421
[1968]422        mEyeVec.RightHandedBase(mUpVec, mLeftVec);
[1964]423
[1969]424        //cout << "termination point: " << mTermination << endl;
425        //cout << "view point: " << mViewPoint << endl;
426        //cout << "scene: " << bbox << endl;
[1964]427
[1968]428        InitRenderTexture(mNewTexture);
429        InitRenderTexture(mOldTexture);
430       
[1969]431        //cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl;
[1964]432}
433
434
[1969]435int GlobalLinesRenderer::CastGlobalLines(const float alpha,
[1964]436                                                                                  const float beta,
437                                                                                  VssRayContainer &rays)
438{
439        InitScene(alpha, beta);
440
[1944]441        // bind pixel shader implementing the front depth buffer functionality
[1969]442        const int layers = ApplyDepthPeeling(rays);
443
444        return layers;
[1944]445}
446
447
[1969]448int GlobalLinesRenderer::CastGlobalLines(const SimpleRay &ray,
[1968]449                                                                                  VssRayContainer &rays)
450{
[1969]451        const long startTime = GetTime();
452        cout << "casting global lines ... " << endl;
453
[1968]454        InitScene(ray);
455
456        // bind pixel shader implementing the front depth buffer functionality
[1969]457        const int layers = ApplyDepthPeeling(rays);
[1968]458
[1972]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
[1969]463        return layers;
[1944]464}
465
466
467void GlobalLinesRenderer::DrawGeometry()
[1945]468{
[1951]469        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
470        glMatrixMode(GL_MODELVIEW);
[1944]471
[1951]472        glPushMatrix();
473        {
[1953]474                //glLoadIdentity();
[1951]475                Intersectable::NewMail();
[1969]476                mRenderer->RenderScene();
[1944]477        }
[1951]478        glPopMatrix();
[1944]479}
480
481
482void GlobalLinesRenderer::SwitchRenderTextures()
483{
[1953]484        RenderTexture *buffer = mOldTexture;
485        mOldTexture = mNewTexture;
486        mNewTexture = buffer;
[1944]487}
488
489
[1958]490void GlobalLinesRenderer::ComputeLookAt(const float alpha,
491                                                                                const float beta,
492                                                                                Vector3 &eye,
493                                                                                Vector3 &up,
[1964]494                                                                                Vector3 &left)
[1958]495{
496        eye.x = sin(alpha) * cos(beta);
497        eye.y = sin(alpha) * sin(beta);
[1964]498        eye.z = cos(alpha);
[1958]499
500        eye.RightHandedBase(up, left);
501}
502
503
[1944]504void GlobalLinesRenderer::InitGl()
505{
[1953]506        InitDevIl();
[1970]507        cout << "texwidth: " << mTexWidth << " texheight: " << mTexHeight << endl;
[1960]508    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
[1944]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
[1958]530        // initialise the receiving buffers
[1964]531        mNewDepthBuffer = new float[mTexWidth * mTexHeight];
532        mNewItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4];
[1960]533
[1964]534        mOldDepthBuffer = new float[mTexWidth * mTexHeight];
535    mOldItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4];
[1960]536
[1964]537        for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
[1958]538        {
539                mNewDepthBuffer[i] = 1;
540                mOldDepthBuffer[i] = 1;
541
[1960]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;
[1958]551        }
552
[1960]553        /*gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
[1944]554                          midPoint.x, midPoint.y, midPoint.z,
555                          0, 1, 0);
556*/
557        gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
558
[1949]559        //glDisable(GL_CULL_FACE);
560        glEnable(GL_CULL_FACE);
[1944]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
[1970]569
[1964]570        mNewTexture = new RenderTexture(mTexWidth, mTexHeight, true, true);
571#ifdef ATI
[1969]572        mNewTexture->Initialize(true, true, false, false, false, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
[1964]573#else
[1969]574        mNewTexture->Initialize(true, true, false, false, false, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
[1964]575#endif
576
577        mOldTexture = new RenderTexture(mTexWidth, mTexHeight, true, true);
578
579#ifdef ATI
[1969]580        mOldTexture ->Initialize(true, true, false, false, false, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
[1964]581#else
[1969]582        mOldTexture ->Initialize(true, true, false, false, false, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
[1964]583#endif
[1944]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,
[1953]600                                                                mNewTexture->IsRectangleTexture() ?
[1951]601                                                                "../src/depth_peelingRect.cg" : "../src/depth_peeling2d.cg",
[1944]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"); 
[1964]610               
611                // we need size of texture for scaling
612                if (!mNewTexture->IsRectangleTexture())
613                {
[1969]614                        sTexWidthParam = cgGetNamedParameter(sCgDepthPeelingProgram, "invTexWidth");
[1964]615                }
616
617                sStepSizeParam = cgGetNamedParameter(sCgDepthPeelingProgram, "stepSize");
618
[1969]619                cgGLSetParameter1f(sTexWidthParam, 1.0f / (float)mTexWidth);
[1964]620                cgGLSetParameter1f(sStepSizeParam, mEpsilon);
[1944]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        }
[1970]635
[1964]636        const float alpha = 1.1;
637        const float beta = 0.9;
[1970]638
[1964]639        InitScene(alpha, beta);
[1970]640
[1944]641        PrintGLerror("init");
642}
643
644
[1960]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
[1944]651{
[1964]652        const int depthIndex = x + mTexWidth * y;
[1960]653        const int itemIndex = 4 * depthIndex;
654
655        const float depth = depthBuffer[depthIndex];
656        const float eyeDist = mNear + (mFar - mNear) * depth;
657       
[1964]658        const float leftDist = -0.5f * mWidth + mWidth * ((float)x + 0.5f) / mTexWidth;
[1990]659        const float upDist   = -0.5f * mWidth + mWidth * ((float)y + 0.5f) / mTexHeight;
[1964]660
[1960]661        hitPoint = mViewPoint +
662                       eyeDist * mEyeVec +
[1964]663                           upDist * mUpVec +
664                           leftDist * mLeftVec;
[1960]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
[1961]682        // test for invalid view space
683        if (DotProd(dir, norm) >= -Limits::Small)
684                return NULL;
685
686        return intersect;
[1944]687}
688
689
[1990]690void GlobalLinesRenderer::ComputeBoundingQuad(int &xMin,
691                                                                                          int &yMin,
692                                                                                          int &xMax,
693                                                                                          int &yMax)
[1980]694{
695        const AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox();
696
697        Matrix4x4 m(mEyeVec, mUpVec, mLeftVec);
698
699        m.Invert();
700
[1990]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]);
[1980]704
705        Vector3 boxMin(1e20f);
706        Vector3 boxMax(-1e20f);
707       
[1990]708        for (int i = 0; i < 8; ++ i)
[1980]709        {
[1990]710        Vector3 vtx;
711
712                bbox.GetVertex(i, vtx);
713
714                Vector3 pt = vtx.x * eye + vtx.y * up + vtx.z * left;
715
[1980]716                // TODO
[1990]717                if (boxMin.x > pt.x)
718                        boxMin.x = pt.x;
[1980]719               
[1990]720                if (boxMin.y > pt.y)
721                        boxMin.y = pt.y;
[1980]722
[1990]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;
[1980]734        }
735
[1990]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);
[1980]742}
743
744
[1968]745bool GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays,
[1963]746                                                                                         const bool oldBufferInitialised,
747                                                                                         const int pass)
[1953]748{
749        GrabDepthBuffer(mNewDepthBuffer, mNewTexture);
750        GrabItemBuffer(mNewItemBuffer, mNewTexture);
751
[1960]752        if (oldBufferInitialised)
[1953]753        {
[1960]754                GrabDepthBuffer(mOldDepthBuffer, mOldTexture);
755                GrabItemBuffer(mOldItemBuffer, mOldTexture);
756        }
757        else
758        {
[1964]759                for (int i = 0; i < mTexWidth * mTexHeight; ++ i)
[1953]760                {
[1960]761                        mOldDepthBuffer[i] = 0;
[1953]762
[1960]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        }
[1953]769
[1990]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
[1968]775        /////////////////
776        // test for validity
777
778        bool buffersEqual = true;
779        bool bufferEmpty = true;
780
[1964]781        for (int y = 0; y < mTexHeight; ++ y)
[1960]782        {
[1964]783                for (int x = 0; x < mTexWidth; ++ x)
[1960]784                {
[1968]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                {
[1960]820                        Vector3 newPt, oldPt;
[1953]821
[1960]822                        Intersectable *termObj1 = ExtractSamplePoint(mNewDepthBuffer,
823                                                                                                                 mNewItemBuffer,
824                                                                                                                 x,
825                                                                                                                 y,
826                                                                                                                 newPt,
827                                                                                                                 true);
[1953]828
[1960]829                        Intersectable *termObj2 = ExtractSamplePoint(mOldDepthBuffer,
830                                                                                                                 mOldItemBuffer,
831                                                                                                                 x,
832                                                                                                                 y,
833                                                                                                                 oldPt,
834                                                                                                                 false);
[1953]835
[1963]836                        if (!termObj1 && !termObj2) // we do not create a ray
837                                continue;
838
839                        Vector3 clippedOldPt, clippedNewPt;
840
[1970]841                        if (ClipToViewSpaceBox(oldPt, newPt, clippedOldPt, clippedNewPt))//;if(1)
[1958]842                        {
[1969]843                                //clippedOldPt = oldPt;
844                                //clippedNewPt = newPt;
[1958]845
[1969]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                                }
[1961]858                        }
[1953]859                }
860        }
[1968]861
862        return true;
[1953]863}
864
865
[1963]866bool GlobalLinesRenderer::ClipToViewSpaceBox(const Vector3 &origin,
867                                                                                         const Vector3 &termination,
868                                                                                         Vector3 &clippedOrigin,
869                                                                                         Vector3 &clippedTermination)
[1944]870{
[1963]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
[1970]878        AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox();
[1963]879
[1970]880        //bbox.Enlarge(1);
881        if (!bbox.ComputeMinMaxT(ray, &tmin, &tmax) || (tmin >= tmax))
[1963]882        {
883                return false;
884        }
885       
[1970]886        if (tmin >= 1.0f || tmax <= 0.0f)
[1963]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;
[1944]900}
901
902
[1963]903void GlobalLinesRenderer::Run()
[1960]904{
[1963]905        glutMainLoop();
[1960]906}
907
908
909void GlobalLinesRenderer::Visualize(const VssRayContainer &vssRays)
910{
[1972]911        cout << "exporting visualization ... ";
[1960]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();
[1963]922        VssRayContainer outRays;
[1960]923
[1963]924        Intersectable::NewMail();
925
[1960]926        for (vit = vssRays.begin(); vit != vit_end; ++ vit)
927        {
928                VssRay *ray = *vit;
[1963]929                Intersectable *obj = (*vit)->mTerminationObject;
930
931                if (!obj->Mailed())
932                {
933                        obj->Mail();
934                        exporter->ExportIntersectable(obj);
935                }
936
[1972]937                //if (ray->mPass == 4)
[1963]938                        outRays.push_back(ray);
[1960]939        }       
940
[1972]941        //exporter->ExportRays(outRays);
942        cout << "finished" << endl;
[1960]943        delete exporter;
944}
945
946
[1953]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
[1960]959void GlobalLinesRenderer::GrabItemBuffer(unsigned char *data, RenderTexture *rt)
[1953]960{
[1958]961        rt->Bind();
[1953]962        rt->EnableTextureTarget();
963
[1958]964        const int texFormat = GL_RGBA;
[1960]965        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data);
[1953]966
967        mNewTexture->DisableTextureTarget();
968}
969
[1958]970
[1953]971void GlobalLinesRenderer::ExportDepthBuffer()
972{
973        mNewTexture->BindDepth();
974        mNewTexture->EnableTextureTarget();
975        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
976
[1960]977        const int components = 1;//mNewTexture->GetDepthBits() / 8;
[1953]978
[1964]979        float *data = new float[mTexWidth * mTexHeight * components];
[1953]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
[1964]991        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data);
[1953]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
[1958]1001
[1960]1002void GlobalLinesRenderer::ExportItemBuffer()
1003{
1004        mNewTexture->Bind();
1005        mNewTexture->EnableTextureTarget();
1006        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
[1958]1007
[1960]1008        const int components = 4;//mNewTexture->GetDepthBits() / 8;
[1958]1009
[1964]1010        unsigned char *data = new unsigned char [mTexWidth * mTexHeight * components];
[1960]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
[1964]1021        ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data);
[1960]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
[1969]1032int GlobalLinesRenderer::ApplyDepthPeeling(VssRayContainer &rays)
[1958]1033{
[1969]1034        int layers = 1;
1035
[1953]1036        mNewTexture->BeginCapture();
[1944]1037        {
1038                //cgGLBindProgram(sCgPassThroughProgram);
1039                //cgGLEnableProfile(sCgFragmentProfile);
[1951]1040                DrawGeometry();
[1944]1041        }
[1953]1042        mNewTexture->EndCapture();
[1944]1043       
[1951]1044        PrintGLerror("firstpass");
[1953]1045        if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl;
[1944]1046
[1958]1047        // process the buffers for the first layer
[1963]1048        ProcessDepthBuffer(rays, false, 0);
[1958]1049
[1971]1050        long renderTime = 0;
1051        long bufferTime = 0;
1052
[1969]1053        for(; layers < mMaxDepth; ++ layers)
[1944]1054        {
[1971]1055                cout << ".";
1056                const long startRenderTime = GetTime();
1057
[1944]1058                // Peel another layer
[1962]1059                // switch pointer between rendertextures
1060                SwitchRenderTextures();
[1944]1061
[1953]1062                mNewTexture->BeginCapture();
[1944]1063                {
1064                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         
1065
1066                        cgGLBindProgram(sCgDepthPeelingProgram);
1067                        cgGLEnableProfile(sCgFragmentProfile);
[1953]1068                        cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID());
[1944]1069                        cgGLEnableTextureParameter(sTextureParam);
1070
[1951]1071                        DrawGeometry();
1072                       
[1944]1073                        cgGLDisableTextureParameter(sTextureParam);
[1949]1074                        cgGLDisableProfile(sCgFragmentProfile);
[1944]1075                }
[1953]1076                mNewTexture->EndCapture();
[1960]1077
[1971]1078                renderTime += TimeDiff(startRenderTime, GetTime());
1079
1080                const long startBufferTime = GetTime();
1081
[1960]1082                // process the buffers for following layer
[1968]1083                // jump out of loop for the first invalid buffer
[1969]1084                if (!ProcessDepthBuffer(rays, true, layers))
[1968]1085                        break;
[1971]1086
1087                bufferTime += TimeDiff(startBufferTime, GetTime());
[1944]1088        }
1089
[1972]1090        Debug << "time spent in rendering: " << renderTime * 1e-3f << endl;
1091        Debug << "time spent in buffer: " << bufferTime * 1e-3f << endl;
[1971]1092       
[1951]1093        PrintGLerror("endpeeling");
[1969]1094
1095        return layers;
[1944]1096}
1097
[1990]1098}
[1944]1099
[1990]1100#endif
Note: See TracBrowser for help on using the repository browser.