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

Revision 1954, 14.2 KB checked in by mattausch, 17 years ago (diff)
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// the devil library
8#include <IL/il.h>
9#include <IL/ilu.h>
10#include <IL/ilut.h>
11
12#include <Cg/cg.h>
13#include <Cg/cgGL.h>
14
15//#include <QtOpenGL>
16
17namespace GtpVisibilityPreprocessor {
18
19
20static CGcontext sCgContext = NULL;
21static CGprogram sCgDepthPeelingProgram = NULL;
22static CGprogram sCgPassThroughProgram = NULL;
23
24static CGprofile sCgFragmentProfile;
25static CGparameter sTextureParam;
26
27GlobalLinesRenderer *globalLinesRenderer = NULL;
28
29static int texWidth = 256;
30static int texHeight = 256;
31
32
33static void InitDevIl()
34{
35        ilInit();
36        ILuint ImageName;
37        ilGenImages(1, &ImageName);
38        ilBindImage(ImageName);
39        ilEnable(IL_FILE_OVERWRITE);
40
41        //  ilRegisterFormat(IL_RGBA);
42        //  ilRegisterType(IL_FLOAT);
43
44        //  ilEnable(IL_ORIGIN_SET);
45        //  ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
46}
47
48
49static void cgErrorCallback()
50{
51        CGerror lastError = cgGetError();
52
53        if(lastError)
54        {
55                printf("%s\n\n", cgGetErrorString(lastError));
56                printf("%s\n", cgGetLastListing(sCgContext));
57                printf("Cg error, exiting...\n");
58
59                exit(0);
60        }
61}
62
63static void PrintGLerror(char *msg)
64{
65        GLenum errCode;
66        const GLubyte *errStr;
67       
68        if ((errCode = glGetError()) != GL_NO_ERROR)
69        {
70                errStr = gluErrorString(errCode);
71                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
72        }
73}
74
75
76void Reshape(int w, int h)
77{
78        if (h == 0) h = 1;
79
80        glViewport(0, 0, w, h);
81
82        glMatrixMode(GL_PROJECTION);
83        glLoadIdentity();
84
85        //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 3, 5000.0);
86        //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.5, 10.0);
87        glOrtho(-1, 1, -1, 1, 0.5, 15);
88}
89
90
91void SetFrustum(int sizeX, int sizeY, float nearPlane, float farPlane)
92{
93        glMatrixMode(GL_PROJECTION);
94        glLoadIdentity();
95
96        glOrtho(-sizeX / 2, sizeX / 2,
97                        -sizeY / 2, sizeY / 2,
98                        nearPlane, farPlane);
99
100        /*glOrtho(0, sizeX,
101                    0, sizeY ,
102                        nearPlane, farPlane);*/
103}
104
105void Display()
106{
107        //globalLinesRenderer->DrawGeometry();
108        globalLinesRenderer->CastGlobalLines(Beam(), 0);
109        PrintGLerror("display");
110
111        glutSwapBuffers();
112}
113
114
115void Idle()
116{
117        glutPostRedisplay();
118}
119
120
121void Keyboard(unsigned char key, int x, int y)
122{
123        switch(key)
124        {
125        case '2':
126                ++ globalLinesRenderer->mMaxDepth;
127                cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl;
128                return;
129        case '1':
130                -- globalLinesRenderer->mMaxDepth;
131                cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl;
132                return;
133        case '3':
134                //globalLinesRenderer->ApplyDepthPeeling(Beam(), 0);
135                globalLinesRenderer->GrabDepthBuffer(globalLinesRenderer->mNewDepthBuffer, globalLinesRenderer->mNewTexture);
136        default:
137                return;
138        }
139}
140
141
142/*GlobalLinesRenderer::GlobalLinesRenderer(RenderTexture *buffer1,
143                                                                                 RenderTexture *buffer2,
144                                                                                 Preprocessor *preprocessor,
145                                                                                 GlRenderer *renderer)
146: mNewTexture(buffer1), mOldTexture(buffer2), mPreprocessor(preprocessor), mMaxDepth(100),
147mRenderer(renderer)
148{
149}
150*/
151
152
153GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor,
154                                                                                 GlRenderer *renderer):
155mNewTexture(NULL),
156mOldTexture(NULL),
157mMaxDepth(0),
158mRenderer(renderer),
159mPreprocessor(preprocessor)
160{
161}
162
163
164GlobalLinesRenderer::~GlobalLinesRenderer()
165{
166        if (sCgDepthPeelingProgram)
167                cgDestroyProgram(sCgDepthPeelingProgram);
168        if (sCgContext)
169                cgDestroyContext(sCgContext);
170}
171
172 
173void GlobalLinesRenderer::CastGlobalLines(Beam &beam, const int samples)
174{
175        // bind pixel shader implementing the front depth buffer functionality
176        ApplyDepthPeeling(beam, samples);
177}
178
179
180void GlobalLinesRenderer::RenderObject(Intersectable *obj)
181{
182        mRenderer->RenderIntersectable(obj);
183}
184
185
186void GlobalLinesRenderer::DrawGeometry()
187{
188        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
189        glMatrixMode(GL_MODELVIEW);
190
191        glPushMatrix();
192        {
193                //glLoadIdentity();
194                       
195                //mRenderer->mUseFalseColors = true;
196                ObjectContainer::const_iterator oit, oit_end = mPreprocessor->mObjects.end();
197
198                Intersectable::NewMail();
199
200                for (oit = mPreprocessor->mObjects.begin(); oit != oit_end; ++ oit)
201                {
202                        RenderObject(*oit);
203                }
204        }
205        glPopMatrix();
206}
207
208
209void GlobalLinesRenderer::SwitchRenderTextures()
210{
211        RenderTexture *buffer = mOldTexture;
212        mOldTexture = mNewTexture;
213        mNewTexture = buffer;
214}
215
216
217void GlobalLinesRenderer::InitGl()
218{
219        InitDevIl();
220
221        glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
222        glutInitWindowPosition(50, 50);
223        glutInitWindowSize(512, 512);
224        glutCreateWindow("TestRenderDepthTexture"); 
225
226        int err = glewInit();
227        if (GLEW_OK != err)
228        {
229                // problem: glewInit failed, something is seriously wrong
230                fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
231                exit(-1);
232        } 
233       
234        glutKeyboardFunc(Keyboard);
235        glutDisplayFunc(Display);
236        glutIdleFunc(Idle);
237        glutReshapeFunc(Reshape);
238
239        Reshape(512, 512);
240        glMatrixMode(GL_MODELVIEW);
241        glLoadIdentity();
242
243        // init the receiving buffers
244        mNewDepthBuffer = new float[texWidth * texHeight];
245        mOldDepthBuffer = new float[texWidth * texHeight];
246       
247        mNewItemBuffer = new int[texWidth * texHeight *4];
248        mOldItemBuffer = new int[texWidth * texHeight *4];
249       
250        AxisAlignedBox3 bbox = globalLinesRenderer->mPreprocessor->mKdTree->GetBox();
251       
252        Vector3 midPoint = bbox.Center();
253       
254        const float sceneSize = Magnitude(bbox.Diagonal());
255        Vector3 viewPoint = midPoint + Vector3(0.5 * sceneSize, 0, 0);
256       
257        cout << "mid point: " << midPoint << endl;
258        cout << "view point: " << viewPoint << endl;
259        cout << "scene: " << bbox << endl;
260
261        /*gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z,
262                          midPoint.x, midPoint.y, midPoint.z,
263                          0, 1, 0);
264*/
265        gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
266
267        //glDisable(GL_CULL_FACE);
268        glEnable(GL_CULL_FACE);
269        glDisable(GL_LIGHTING);
270        glDisable(GL_COLOR_MATERIAL);
271        glEnable(GL_DEPTH_TEST);
272        glClearColor(0.1, 0.2, 0.3, 1);
273       
274        // A square, mipmapped, anisotropically filtered 8-bit RGBA texture with
275        // depth and stencil.
276        // Note that RT_COPY_TO_TEXTURE is required for depth textures on ATI hardware
277       
278        mNewTexture = new RenderTexture(texWidth, texHeight, true, true);
279        //mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
280        mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
281       
282        mOldTexture = new RenderTexture(texWidth, texHeight, true, true);
283        //mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE);
284        mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE);
285
286        // Setup Cg
287        cgSetErrorCallback(cgErrorCallback);
288
289        // Create cgContext.
290        sCgContext = cgCreateContext();
291
292        // get the best profile for this hardware
293        sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
294       
295        //assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN);
296        cgGLSetOptimalOptions(sCgFragmentProfile);
297
298        sCgDepthPeelingProgram =
299                cgCreateProgramFromFile(sCgContext,
300                                                                CG_SOURCE,
301                                                                mNewTexture->IsRectangleTexture() ?
302                                                                "../src/depth_peelingRect.cg" : "../src/depth_peeling2d.cg",
303                                                                GLEW_ARB_fragment_program ? CG_PROFILE_ARBFP1 : CG_PROFILE_FP30,
304                                                                NULL,
305                                                                NULL);
306
307        if(sCgDepthPeelingProgram != NULL)
308        {
309                cgGLLoadProgram(sCgDepthPeelingProgram);
310                sTextureParam = cgGetNamedParameter(sCgDepthPeelingProgram, "depthTex"); 
311        }
312
313        sCgPassThroughProgram =
314                cgCreateProgramFromFile(sCgContext,
315                                                                CG_SOURCE,
316                                                                "../src/passthrough.cg",
317                                                                GLEW_ARB_fragment_program ? CG_PROFILE_ARBFP1 : CG_PROFILE_FP30,
318                                                                NULL,
319                                                                NULL);
320
321        if(sCgPassThroughProgram != NULL)
322        {
323                cgGLLoadProgram(sCgPassThroughProgram);
324        }
325
326    // setup the rendering context for the RenderTexture
327        mNewTexture->BeginCapture();
328        {
329                //Reshape(texWidth, texHeight);
330                glViewport(0, 0, texWidth, texHeight);
331                SetFrustum(sceneSize, sceneSize, 1, sceneSize);
332
333                glClearColor(0.1, 0.7, 0.2, 1);
334                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
335
336                glFrontFace(GL_CCW);
337                glCullFace(GL_BACK);
338                glEnable(GL_CULL_FACE);
339                glShadeModel(GL_FLAT);
340                glEnable(GL_DEPTH_TEST);
341               
342                glMatrixMode(GL_MODELVIEW);
343                glLoadIdentity();
344                gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z,
345                                  midPoint.x, midPoint.y, midPoint.z,
346                                  0, 1, 0);
347
348                //SetFrustum(sceneSize, sceneSize, 1, sceneSize);
349        }
350        mNewTexture->EndCapture();
351
352        // setup the rendering context for the RenderTexture
353        mOldTexture->BeginCapture();
354        {
355                glClearColor(0.1, 0.7, 0.2, 1);
356       
357                //Reshape(texWidth, texHeight);
358                glViewport(0, 0, texWidth, texHeight);
359                SetFrustum(sceneSize, sceneSize, 1, sceneSize);
360
361                glMatrixMode(GL_MODELVIEW);
362                glLoadIdentity();
363               
364                glFrontFace(GL_CCW);
365                glCullFace(GL_BACK);
366                glEnable(GL_CULL_FACE);
367                glShadeModel(GL_FLAT);
368                glEnable(GL_DEPTH_TEST);
369               
370                gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z,
371                                  midPoint.x, midPoint.y, midPoint.z,
372                                  0, 1, 0);
373
374                //SetFrustum(sceneSize, sceneSize, 1, sceneSize);
375        }
376        mOldTexture->EndCapture();
377
378        PrintGLerror("init");
379}
380
381
382Intersectable *GetObject(const int index)
383{
384        return NULL;
385}
386
387
388void GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays)
389{
390        GrabDepthBuffer(mNewDepthBuffer, mNewTexture);
391        GrabDepthBuffer(mOldDepthBuffer, mOldTexture);
392
393        GrabItemBuffer(mNewItemBuffer, mNewTexture);
394        GrabItemBuffer(mOldItemBuffer, mOldTexture);
395
396        for (int y = 0; y < texHeight; ++ y)
397        {
398                for (int x = 0; x < texWidth; ++ x)
399                {
400                        const int index = x + texWidth * y;
401                        const float newDepth = mNewDepthBuffer[index];
402                        const float oldDepth = mOldDepthBuffer[index];
403
404                        float newDummy1 = mNear + (mFar - mNear) * newDepth;
405                        float oldDummy1 = mNear + (mFar - mNear) * oldDepth;
406
407                        float newDummy2 = x - texWidth / 2;
408                        float newDummy3 = y -  texHeight / 2;
409
410                        float oldDummy2 = newDummy2;
411                        float oldDummy3 = newDummy3;
412
413                        const Vector3 newPt = newDepth * mEyeVec + newDummy1 * mLeftVec + newDummy2 * mUpVec;
414                        const Vector3 oldPt = oldDepth * mEyeVec + oldDummy1 * mLeftVec + oldDummy2 * mUpVec;
415
416                        Intersectable *termObj1 = GetObject(mNewItemBuffer[index]);
417                        Intersectable *termObj2 = GetObject(mOldItemBuffer[index]);
418
419                        // create rays in both directions
420                        vssRays.push_back(new VssRay(oldPt, newPt, NULL, termObj1));
421                        vssRays.push_back(new VssRay(newPt, oldPt, NULL, termObj2));
422                }
423        }
424}
425
426
427void GlobalLinesRenderer::Run()
428{
429        glutMainLoop();
430}
431
432
433void GlobalLinesRenderer::GrabDepthBuffer(float *data, RenderTexture *rt)
434{
435        rt->BindDepth();
436        rt->EnableTextureTarget();
437        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
438
439        const int texFormat = GL_DEPTH_COMPONENT;
440        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
441
442        mNewTexture->DisableTextureTarget();
443}
444
445
446void GlobalLinesRenderer::GrabItemBuffer(int *data, RenderTexture *rt)
447{
448        rt->BindDepth();
449        rt->EnableTextureTarget();
450        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
451
452        const int texFormat = GL_DEPTH_COMPONENT;
453        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
454
455        mNewTexture->DisableTextureTarget();
456}
457
458void GlobalLinesRenderer::ExportDepthBuffer()
459{
460        mNewTexture->BindDepth();
461        mNewTexture->EnableTextureTarget();
462        cout << "depth: " << mNewTexture->GetDepthBits() << endl;
463
464        const bool components = 1;//mNewTexture->GetDepthBits() / 8;
465
466        float *data = new float[texWidth * texHeight * components];
467        //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV;
468        const int texFormat = GL_DEPTH_COMPONENT;
469        //const int texFormat = GL_RGBA;
470        glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data);
471
472        /*for (int i = texWidth * 123; i < texWidth * 124; ++ i)
473        {
474                cout << data[i] << " ";
475        }
476        cout << "Saving image " << texWidth << " " << texHeight << endl;
477*/
478        string filename("depth.tga");
479        ilRegisterType(IL_FLOAT);
480
481        const int depth = 1;
482        const int bpp = components;
483
484        ilTexImage(texWidth, texHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data);
485        ilSaveImage((char *const)filename.c_str());
486
487        cout << "finished" << endl;
488        delete data;
489        cout << "data deleted" << endl;
490        mNewTexture->DisableTextureTarget();
491        PrintGLerror("grab texture");
492}
493
494
495void GlobalLinesRenderer::ApplyDepthPeeling(Beam &beam, const int samples)
496{
497        mNewTexture->BeginCapture();
498        {
499                //cgGLBindProgram(sCgPassThroughProgram);
500                //cgGLEnableProfile(sCgFragmentProfile);
501                DrawGeometry();
502        }
503        mNewTexture->EndCapture();
504       
505        PrintGLerror("firstpass");
506
507        if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl;
508
509        for(int i = 0; i < mMaxDepth; ++ i)
510        {
511                // Peel another layer
512                SwitchRenderTextures(); // switch pointer between rendertextures
513
514                mNewTexture->BeginCapture();
515                {
516                        //if (mNewTexture->IsDoubleBuffered())
517                        //      glDrawBuffer(GL_BACK);
518
519                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         
520
521                        cgGLBindProgram(sCgDepthPeelingProgram);
522                //      cgGLBindProgram(sCgPassThroughProgram);
523                        cgGLEnableProfile(sCgFragmentProfile);
524                        cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID());
525                        cgGLEnableTextureParameter(sTextureParam);
526
527                        //glutSolidTorus(0.25, 1, 32, 64);
528                        DrawGeometry();
529                       
530                        glPopMatrix();
531
532                        cgGLDisableTextureParameter(sTextureParam);
533                        cgGLDisableProfile(sCgFragmentProfile);
534                }
535                mNewTexture->EndCapture();
536        }
537
538        PrintGLerror("endpeeling");
539
540        //mNewTexture->Bind();
541        mNewTexture->BindDepth();
542        mNewTexture->EnableTextureTarget();
543       
544        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
545       
546        if (mNewTexture->IsRectangleTexture())
547        {
548                glBegin(GL_QUADS);
549                glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
550                glTexCoord2f(mNewTexture->GetWidth(), 0); glVertex3f( 1, -1, -0.5f);
551                glTexCoord2f(mNewTexture->GetWidth(), mNewTexture->GetHeight()); glVertex3f( 1,  1, -0.5f);
552                glTexCoord2f(0, mNewTexture->GetHeight()); glVertex3f(-1, 1, -0.5f);
553                glEnd();
554        }
555        else
556        {
557                glBegin(GL_QUADS);
558                glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
559                glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
560                glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
561                glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
562                glEnd();
563        } 
564
565        mNewTexture->DisableTextureTarget();
566        PrintGLerror("displaytexture");
567}
568
569
570}
Note: See TracBrowser for help on using the repository browser.