#include "SceneQuery.h" #include "glInterface.h" #include "Vector3.h" #include "Camera.h" #include "SceneQuery.h" #include "RenderTraverser.h" #include #include #include "RenderTexture.h" using namespace std; static int texWidth = 2048; static int texHeight = 2048; static void PrintGLerror(char *msg) { GLenum errCode; const GLubyte *errStr; if ((errCode = glGetError()) != GL_NO_ERROR) { errStr = gluErrorString(errCode); fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg); } } void startil() { ilInit(); assert(ilGetError() == IL_NO_ERROR); } void stopil() { ilShutDown(); assert(ilGetError() == IL_NO_ERROR); } namespace CHCDemoEngine { void GrabDepthBuffer(float *data, RenderTexture *rt) { rt->BindDepth(); rt->EnableTextureTarget(); const int texFormat = GL_DEPTH_COMPONENT; glGetTexImage(rt->GetTextureTarget(), 0, texFormat, GL_FLOAT, data); rt->DisableTextureTarget(); } void ExportDepthBuffer(float *data) { startil(); ILstring filename = ILstring("depth.tga"); ilRegisterType(IL_FLOAT); const int depth = 1; const int bpp = 1; if (!ilTexImage(texWidth, texHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data)) { cerr << "IL error " << ilGetError() << endl; stopil(); return; } if (!ilSaveImage(filename)) { cerr << "TGA write error " << ilGetError() << endl; } stopil(); cout << "exported depth buffer" << endl; } SceneQuery::SceneQuery(const AxisAlignedBox3 &sceneBox, RenderTraverser *renderer): mSceneBox(sceneBox), mDepth(NULL) { Prepare(renderer); } bool SceneQuery::CalcIntersection(Vector3 &pt) { const int px = (pt.x - mSceneBox.Min(0)) * (texWidth - 1) / mSceneBox.Size(0); const int py = (pt.y - mSceneBox.Min(1)) * (texHeight - 1) / mSceneBox.Size(1); float d = mDepth[px + py * texHeight]; static float depth = d; if (d > 0) { // temporal smoothing of depth values const float x = 0.5f; depth = d * x + depth * (1.0f - x); const float offs = mSceneBox.Size(2) * 5e-2f; pt.z = mSceneBox.Max().z - mSceneBox.Size().z * depth + offs; return true; } return false; } void SceneQuery::Prepare(RenderTraverser *renderer) { cout << "Preparing scene queries" << endl; const float xlen = mSceneBox.Size().x * 0.5f; const float ylen = mSceneBox.Size().y * 0.5f; Camera *orthoCam = new Camera(xlen, ylen); orthoCam->SetOrtho(true); orthoCam->SetNear(0.0f); orthoCam->Yaw(M_PI * 0.5f); Vector3 pos = Vector3(mSceneBox.Center().x, mSceneBox.Center().y, mSceneBox.Max().z); orthoCam->SetPosition(pos); RenderTexture *depthTexture = new RenderTexture(texWidth, texHeight, true, true); #ifdef ATI depthTexture->Initialize(true, true, false, false, false, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE); #else depthTexture->Initialize(true, true, false, false, false, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE); #endif PrintGLerror("Init"); depthTexture->BeginCapture(); { glViewport(0, 0, texWidth, texHeight); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glFrontFace(GL_CCW); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-xlen, xlen, -ylen, ylen, 0.0f, mSceneBox.Size().z); glMatrixMode(GL_MODELVIEW); orthoCam->SetupCameraView(); mDepth = new float[texHeight * texWidth]; //renderer->SetCamera(orthoCam); renderer->RenderScene(); } depthTexture->EndCapture(); GrabDepthBuffer(mDepth, depthTexture); //ExportDepthBuffer(mDepth); //PrintGLerror("grab"); DEL_PTR(depthTexture); DEL_PTR(orthoCam); } }