#include "glInterface.h" #include "GlobalLinesRenderer.h" #include "common.h" #include "RenderTexture.h" #include "Preprocessor.h" #include "GlRenderer.h" // the devil library #include #include #include #include #include //#include namespace GtpVisibilityPreprocessor { static CGcontext sCgContext = NULL; static CGprogram sCgDepthPeelingProgram = NULL; static CGprogram sCgPassThroughProgram = NULL; static CGprofile sCgFragmentProfile; static CGparameter sTextureParam; GlobalLinesRenderer *globalLinesRenderer = NULL; static int texWidth = 256; static int texHeight = 256; static void InitDevIl() { ilInit(); ILuint ImageName; ilGenImages(1, &ImageName); ilBindImage(ImageName); ilEnable(IL_FILE_OVERWRITE); // ilRegisterFormat(IL_RGBA); // ilRegisterType(IL_FLOAT); // ilEnable(IL_ORIGIN_SET); // ilOriginFunc(IL_ORIGIN_UPPER_LEFT); } static void cgErrorCallback() { CGerror lastError = cgGetError(); if(lastError) { printf("%s\n\n", cgGetErrorString(lastError)); printf("%s\n", cgGetLastListing(sCgContext)); printf("Cg error, exiting...\n"); exit(0); } } 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 Reshape(int w, int h) { if (h == 0) h = 1; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 3, 5000.0); //gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.5, 10.0); glOrtho(-1, 1, -1, 1, 0.5, 15); } void SetFrustum(int sizeX, int sizeY, float nearPlane, float farPlane) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-sizeX / 2, sizeX / 2, -sizeY / 2, sizeY / 2, nearPlane, farPlane); /*glOrtho(0, sizeX, 0, sizeY , nearPlane, farPlane);*/ } void Display() { //globalLinesRenderer->DrawGeometry(); globalLinesRenderer->CastGlobalLines(Beam(), 0); PrintGLerror("display"); glutSwapBuffers(); } void Idle() { glutPostRedisplay(); } void Keyboard(unsigned char key, int x, int y) { switch(key) { case '2': ++ globalLinesRenderer->mMaxDepth; cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl; return; case '1': -- globalLinesRenderer->mMaxDepth; cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl; return; case '3': //globalLinesRenderer->ApplyDepthPeeling(Beam(), 0); globalLinesRenderer->GrabDepthBuffer(globalLinesRenderer->mNewDepthBuffer, globalLinesRenderer->mNewTexture); default: return; } } /*GlobalLinesRenderer::GlobalLinesRenderer(RenderTexture *buffer1, RenderTexture *buffer2, Preprocessor *preprocessor, GlRenderer *renderer) : mNewTexture(buffer1), mOldTexture(buffer2), mPreprocessor(preprocessor), mMaxDepth(100), mRenderer(renderer) { } */ GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor, GlRenderer *renderer): mNewTexture(NULL), mOldTexture(NULL), mMaxDepth(0), mRenderer(renderer), mPreprocessor(preprocessor) { } GlobalLinesRenderer::~GlobalLinesRenderer() { if (sCgDepthPeelingProgram) cgDestroyProgram(sCgDepthPeelingProgram); if (sCgContext) cgDestroyContext(sCgContext); } void GlobalLinesRenderer::CastGlobalLines(Beam &beam, const int samples) { // bind pixel shader implementing the front depth buffer functionality ApplyDepthPeeling(beam, samples); } void GlobalLinesRenderer::RenderObject(Intersectable *obj) { mRenderer->RenderIntersectable(obj); } void GlobalLinesRenderer::DrawGeometry() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glPushMatrix(); { //glLoadIdentity(); //mRenderer->mUseFalseColors = true; ObjectContainer::const_iterator oit, oit_end = mPreprocessor->mObjects.end(); Intersectable::NewMail(); for (oit = mPreprocessor->mObjects.begin(); oit != oit_end; ++ oit) { RenderObject(*oit); } } glPopMatrix(); } void GlobalLinesRenderer::SwitchRenderTextures() { RenderTexture *buffer = mOldTexture; mOldTexture = mNewTexture; mNewTexture = buffer; } void GlobalLinesRenderer::InitGl() { InitDevIl(); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowPosition(50, 50); glutInitWindowSize(512, 512); glutCreateWindow("TestRenderDepthTexture"); int err = glewInit(); if (GLEW_OK != err) { // problem: glewInit failed, something is seriously wrong fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); exit(-1); } glutKeyboardFunc(Keyboard); glutDisplayFunc(Display); glutIdleFunc(Idle); glutReshapeFunc(Reshape); Reshape(512, 512); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); AxisAlignedBox3 bbox = globalLinesRenderer->mPreprocessor->mKdTree->GetBox(); Vector3 midPoint = bbox.Center(); const float sceneSize = Magnitude(bbox.Diagonal()); Vector3 viewPoint = midPoint + Vector3(0.5 * sceneSize, 0, 0); cout << "mid point: " << midPoint << endl; cout << "view point: " << viewPoint << endl; cout << "scene: " << bbox << endl; /*gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z, midPoint.x, midPoint.y, midPoint.z, 0, 1, 0); */ gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0); //glDisable(GL_CULL_FACE); glEnable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); glClearColor(0.1, 0.2, 0.3, 1); // A square, mipmapped, anisotropically filtered 8-bit RGBA texture with // depth and stencil. // Note that RT_COPY_TO_TEXTURE is required for depth textures on ATI hardware mNewTexture = new RenderTexture(texWidth, texHeight, true, true); //mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE); mNewTexture->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE); mOldTexture = new RenderTexture(texWidth, texHeight, true, true); //mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE); mOldTexture ->Initialize(true, true, false, true, true, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE); // Setup Cg cgSetErrorCallback(cgErrorCallback); // Create cgContext. sCgContext = cgCreateContext(); // get the best profile for this hardware sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); //assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN); cgGLSetOptimalOptions(sCgFragmentProfile); sCgDepthPeelingProgram = cgCreateProgramFromFile(sCgContext, CG_SOURCE, mNewTexture->IsRectangleTexture() ? "../src/depth_peelingRect.cg" : "../src/depth_peeling2d.cg", GLEW_ARB_fragment_program ? CG_PROFILE_ARBFP1 : CG_PROFILE_FP30, NULL, NULL); if(sCgDepthPeelingProgram != NULL) { cgGLLoadProgram(sCgDepthPeelingProgram); sTextureParam = cgGetNamedParameter(sCgDepthPeelingProgram, "depthTex"); } sCgPassThroughProgram = cgCreateProgramFromFile(sCgContext, CG_SOURCE, "../src/passthrough.cg", GLEW_ARB_fragment_program ? CG_PROFILE_ARBFP1 : CG_PROFILE_FP30, NULL, NULL); if(sCgPassThroughProgram != NULL) { cgGLLoadProgram(sCgPassThroughProgram); } // setup the rendering context for the RenderTexture mNewTexture->BeginCapture(); { //Reshape(texWidth, texHeight); glViewport(0, 0, texWidth, texHeight); SetFrustum(sceneSize, sceneSize, 1, sceneSize); glClearColor(0.1, 0.7, 0.2, 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_MODELVIEW); glLoadIdentity(); gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z, midPoint.x, midPoint.y, midPoint.z, 0, 1, 0); //SetFrustum(sceneSize, sceneSize, 1, sceneSize); } mNewTexture->EndCapture(); // setup the rendering context for the RenderTexture mOldTexture->BeginCapture(); { glClearColor(0.1, 0.7, 0.2, 1); //Reshape(texWidth, texHeight); glViewport(0, 0, texWidth, texHeight); SetFrustum(sceneSize, sceneSize, 1, sceneSize); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glFrontFace(GL_CCW); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z, midPoint.x, midPoint.y, midPoint.z, 0, 1, 0); //SetFrustum(sceneSize, sceneSize, 1, sceneSize); } mOldTexture->EndCapture(); PrintGLerror("init"); } Intersectable *GetObject(const int index) { return NULL; } void GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays) { GrabDepthBuffer(mNewDepthBuffer, mNewTexture); GrabDepthBuffer(mOldDepthBuffer, mOldTexture); GrabItemBuffer(mNewItemBuffer, mNewTexture); GrabItemBuffer(mOldItemBuffer, mOldTexture); for (int y = 0; y < texHeight; ++ y) { for (int x = 0; x < texWidth; ++ x) { const int index = x + texWidth * y; const float newDepth = mNewDepthBuffer[index]; const float oldDepth = mOldDepthBuffer[index]; float newDummy1 = mNear + (mFar - mNear) * newDepth; float oldDummy1 = mNear + (mFar - mNear) * oldDepth; float newDummy2 = x - texWidth / 2; float newDummy3 = y - texHeight / 2; float oldDummy2 = newDummy2; float oldDummy3 = newDummy3; const Vector3 newPt = newDepth * mEyeVec + newDummy1 * mLeftVec + newDummy2 * mUpVec; const Vector3 oldPt = oldDepth * mEyeVec + oldDummy1 * mLeftVec + oldDummy2 * mUpVec; Intersectable *termObj1 = GetObject(mNewItemBuffer[index]); Intersectable *termObj2 = GetObject(mOldItemBuffer[index]); // create rays in both directions vssRays.push_back(new VssRay(oldPt, newPt, NULL, termObj1)); vssRays.push_back(new VssRay(newPt, oldPt, NULL, termObj2)); } } } void GlobalLinesRenderer::Run() { glutMainLoop(); } void GlobalLinesRenderer::GrabDepthBuffer(float *data, RenderTexture *rt) { rt->BindDepth(); rt->EnableTextureTarget(); cout << "depth: " << mNewTexture->GetDepthBits() << endl; const int texFormat = GL_DEPTH_COMPONENT; glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data); mNewTexture->DisableTextureTarget(); } void GlobalLinesRenderer::GrabItemBuffer(float *data, RenderTexture *rt) { rt->BindDepth(); rt->EnableTextureTarget(); cout << "depth: " << mNewTexture->GetDepthBits() << endl; const int texFormat = GL_DEPTH_COMPONENT; glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data); mNewTexture->DisableTextureTarget(); } void GlobalLinesRenderer::ExportDepthBuffer() { mNewTexture->BindDepth(); mNewTexture->EnableTextureTarget(); cout << "depth: " << mNewTexture->GetDepthBits() << endl; const bool components = 1;//mNewTexture->GetDepthBits() / 8; float *data = new float[texWidth * texHeight * components]; //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV; const int texFormat = GL_DEPTH_COMPONENT; //const int texFormat = GL_RGBA; glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data); /*for (int i = texWidth * 123; i < texWidth * 124; ++ i) { cout << data[i] << " "; } cout << "Saving image " << texWidth << " " << texHeight << endl; */ string filename("depth.tga"); ilRegisterType(IL_FLOAT); const int depth = 1; const int bpp = components; ilTexImage(texWidth, texHeight, depth, bpp, IL_LUMINANCE, IL_FLOAT, data); ilSaveImage((char *const)filename.c_str()); cout << "finished" << endl; delete data; cout << "data deleted" << endl; mNewTexture->DisableTextureTarget(); PrintGLerror("grab texture"); } void GlobalLinesRenderer::ApplyDepthPeeling(Beam &beam, const int samples) { mNewTexture->BeginCapture(); { //cgGLBindProgram(sCgPassThroughProgram); //cgGLEnableProfile(sCgFragmentProfile); DrawGeometry(); } mNewTexture->EndCapture(); PrintGLerror("firstpass"); if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl; for(int i = 0; i < mMaxDepth; ++ i) { // Peel another layer SwitchRenderTextures(); // switch pointer between rendertextures mNewTexture->BeginCapture(); { //if (mNewTexture->IsDoubleBuffered()) // glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); cgGLBindProgram(sCgDepthPeelingProgram); // cgGLBindProgram(sCgPassThroughProgram); cgGLEnableProfile(sCgFragmentProfile); cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID()); cgGLEnableTextureParameter(sTextureParam); //glutSolidTorus(0.25, 1, 32, 64); DrawGeometry(); glPopMatrix(); cgGLDisableTextureParameter(sTextureParam); cgGLDisableProfile(sCgFragmentProfile); } mNewTexture->EndCapture(); } PrintGLerror("endpeeling"); //mNewTexture->Bind(); mNewTexture->BindDepth(); mNewTexture->EnableTextureTarget(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (mNewTexture->IsRectangleTexture()) { glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f); glTexCoord2f(mNewTexture->GetWidth(), 0); glVertex3f( 1, -1, -0.5f); glTexCoord2f(mNewTexture->GetWidth(), mNewTexture->GetHeight()); glVertex3f( 1, 1, -0.5f); glTexCoord2f(0, mNewTexture->GetHeight()); glVertex3f(-1, 1, -0.5f); glEnd(); } else { glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f); glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f); glTexCoord2f(1, 1); glVertex3f( 1, 1, -0.5f); glTexCoord2f(0, 1); glVertex3f(-1, 1, -0.5f); glEnd(); } mNewTexture->DisableTextureTarget(); PrintGLerror("displaytexture"); } }