source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp @ 2899

Revision 2899, 4.0 KB checked in by mattausch, 16 years ago (diff)
RevLine 
[2764]1#include "SceneQuery.h"
2#include "glInterface.h"
3#include "Vector3.h"
4#include "Camera.h"
[2778]5#include "SceneQuery.h"
6#include "RenderTraverser.h"
[2887]7#include "FrameBufferObject.h"
8
[2800]9#include <IL/il.h>
10#include <assert.h>
[2764]11
12
[2877]13
[2887]14
[2808]15using namespace std;
16
[2848]17const static int texWidth = 2048;
18const static int texHeight = 2048;
[2808]19
20
21
[2877]22
[2808]23static void PrintGLerror(char *msg)
24{
25        GLenum errCode;
26        const GLubyte *errStr;
27       
28        if ((errCode = glGetError()) != GL_NO_ERROR)
29        {
30                errStr = gluErrorString(errCode);
31                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
32        }
33}
34
35
[2887]36static void startil()
[2800]37{
38        ilInit();
39        assert(ilGetError() == IL_NO_ERROR);
40}
[2764]41
42
[2887]43static void stopil()
[2800]44{
45        ilShutDown();
46        assert(ilGetError() == IL_NO_ERROR);
47}
48
49
[2776]50namespace CHCDemoEngine
[2764]51{
52
53
[2887]54static void GrabDepthBuffer(float *data, GLuint depthTexture)
[2808]55{
[2877]56        glEnable(GL_TEXTURE_2D);
57        glBindTexture(GL_TEXTURE_2D, depthTexture);
[2764]58
[2877]59        glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data);
[2764]60
[2877]61        glBindTexture(GL_TEXTURE_2D, 0);
62        glDisable(GL_TEXTURE_2D);
[2808]63}
[2764]64
65
[2887]66static void ExportDepthBuffer(float *data)
[2808]67{
68        startil();
69
70        ILstring filename = ILstring("depth.tga");
71        ilRegisterType(IL_FLOAT);
72
73        const int depth = 1;
74        const int bpp = 1;
75
76        if (!ilTexImage(texWidth, texHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data))
77        {
78                cerr << "IL error " << ilGetError() << endl;
79                stopil();
80                return;
81        }
82
83        if (!ilSaveImage(filename))
84        {
85                cerr << "TGA write error " << ilGetError() << endl;
86        }
87
88        stopil();
89
90        cout << "exported depth buffer" << endl;
91}
92
93
[2887]94SceneQuery::SceneQuery(const AxisAlignedBox3 &sceneBox,
95                                           RenderTraverser *renderer):
[2796]96mSceneBox(sceneBox), mDepth(NULL)
[2764]97{
[2778]98        Prepare(renderer);
[2764]99}
100
101
102bool SceneQuery::CalcIntersection(Vector3 &pt)
103{
[2888]104        const int px = (mSceneBox.Max(0) - pt.x) * (texWidth - 1) / mSceneBox.Size(0);
105        const int py = (mSceneBox.Max(1) - pt.y) * (texHeight - 1) / mSceneBox.Size(1);
[2764]106
[2808]107        float d = mDepth[px + py * texHeight];
[2764]108
[2808]109        static float depth = d;
[2800]110
111        if (d > 0)
[2764]112        {
[2808]113                // temporal smoothing of depth values
[2848]114                const float x = .5f;
[2808]115                depth = d * x + depth * (1.0f - x);
[2764]116
[2808]117                const float offs = mSceneBox.Size(2) * 5e-2f;
118                pt.z =  mSceneBox.Max().z - mSceneBox.Size().z * depth + offs;
119
[2764]120                return true;
121        }
122
123        return false;
124}
125
[2778]126
127void SceneQuery::Prepare(RenderTraverser *renderer)
[2764]128{
129        cout << "Preparing scene queries" << endl;
130
[2796]131        const float xlen = mSceneBox.Size().x * 0.5f;
132        const float ylen = mSceneBox.Size().y * 0.5f;
133       
134        Camera *orthoCam = new Camera(xlen, ylen);
135        orthoCam->SetOrtho(true);
[2764]136
137        orthoCam->SetNear(0.0f);
[2897]138        orthoCam->Yaw(.5 * M_PI);
[2888]139        orthoCam->SetDirection(Vector3(0, 0, -1));
[2764]140
[2796]141        Vector3 pos = Vector3(mSceneBox.Center().x, mSceneBox.Center().y, mSceneBox.Max().z);
[2764]142        orthoCam->SetPosition(pos);
143
[2877]144        FrameBufferObject *fbo = new FrameBufferObject(texWidth, texHeight, FrameBufferObject::DEPTH_32, true);
145        fbo->AddColorBuffer(ColorBufferObject::BUFFER_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false);
[2809]146
147
[2877]148        fbo->Bind();
[2809]149
[2877]150        glDrawBuffers(1, mrt);
[2887]151
152        glPushAttrib(GL_VIEWPORT_BIT);
[2877]153        glViewport(0, 0, texWidth, texHeight);
[2764]154
[2877]155        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[2764]156
[2897]157        glDisable(GL_CULL_FACE);
[2808]158
[2877]159        glShadeModel(GL_FLAT);
160        glEnable(GL_DEPTH_TEST);
[2808]161
[2897]162        glMatrixMode(GL_MODELVIEW);
163        glPushMatrix();
164        glLoadIdentity();
165
[2877]166        glMatrixMode(GL_PROJECTION);
167        glPushMatrix();
[2897]168        glLoadIdentity();
[2808]169
[2877]170        glOrtho(+xlen, -xlen, ylen, -ylen, 0.0f, mSceneBox.Size().z);
[2764]171
[2877]172        glMatrixMode(GL_MODELVIEW);
[2764]173
[2877]174        orthoCam->SetupCameraView();
[2778]175
[2877]176        mDepth = new float[texHeight * texWidth];
[2809]177
[2897]178        Camera *oldCam = renderer->GetCamera();
179        renderer->SetCamera(orthoCam);
180
[2877]181        renderer->RenderScene();
[2897]182
183        renderer->SetCamera(oldCam);
[2877]184       
[2897]185
186        glEnable(GL_CULL_FACE);
187
188        glMatrixMode(GL_MODELVIEW);
[2877]189        glPopMatrix();
[2897]190       
[2877]191        glMatrixMode(GL_PROJECTION);
192        glPopMatrix();
[2834]193
[2877]194        glPopAttrib();
195       
196        FrameBufferObject::Release();
[2834]197
[2877]198        GrabDepthBuffer(mDepth, fbo->GetDepthTex());
[2892]199        //ExportDepthBuffer(mDepth); PrintGLerror("grab");
[2796]200
[2877]201        DEL_PTR(fbo);
[2796]202        DEL_PTR(orthoCam);
[2764]203}
204
[2808]205
206
207
[2764]208}
Note: See TracBrowser for help on using the repository browser.