#include "glInterface.h" #include "GlobalLinesRenderer.h" #include "common.h" #include "RenderTexture.h" #include "Preprocessor.h" #include "GlRenderer.h" #include "Exporter.h" #include "ViewCellsManager.h" #include "SamplingStrategy.h" // the devil library #include #include #include #ifdef USE_CG #include #include namespace GtpVisibilityPreprocessor { static CGcontext sCgContext = NULL; static CGprogram sCgDepthPeelingProgram = NULL; static CGprogram sCgPassThroughProgram = NULL; static CGprofile sCgFragmentProfile; static CGparameter sTextureParam; static CGparameter sTexWidthParam; static CGparameter sStepSizeParam; GlobalLinesRenderer *globalLinesRenderer = NULL; static bool isDepth = true; 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(const int sizeX, const int sizeY, const float nearPlane, const float farPlane) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-sizeX * 0.5, sizeX * 0.5, -sizeY * 0.5, sizeY * 0.5, nearPlane, farPlane); /*glOrtho(0, sizeX, 0, sizeY , nearPlane, farPlane);*/ } void Display() { //globalLinesRenderer->DrawGeometry(); //globalLinesRenderer->CastGlobalLines(Beam(), 0); globalLinesRenderer->DisplayBuffer(isDepth); PrintGLerror("display"); glutSwapBuffers(); } void Idle() { glutPostRedisplay(); } void Keyboard(unsigned char key, int x, int y) { switch(key) { case '2': { VssRayContainer rays; ++ globalLinesRenderer->mMaxDepth; globalLinesRenderer->ApplyDepthPeeling(rays); cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl; CLEAR_CONTAINER(rays); return; } case '1': { VssRayContainer rays; -- globalLinesRenderer->mMaxDepth; cout << "max depth: " << globalLinesRenderer->mMaxDepth << endl; globalLinesRenderer->ApplyDepthPeeling(rays); CLEAR_CONTAINER(rays); return; } case '3': { globalLinesRenderer->ExportDepthBuffer(); return; } case '4': { globalLinesRenderer->ExportItemBuffer(); return; } case '5': { VssRayContainer rays; HwGlobalLinesDistribution glStrategy(*globalLinesRenderer->mPreprocessor); SimpleRayContainer simpleRays; glStrategy.GenerateSamples(5, simpleRays); //cout << "simple ray: " << simpleRays[4] << endl; globalLinesRenderer->CastGlobalLines(simpleRays[1], rays); // visualize VssRayContainer outRays; VssRayContainer::const_iterator vit, vit_end = rays.end(); const float p = 8.0f / (float)rays.size(); for (vit = rays.begin(); vit != vit_end; ++ vit) { if (Random(1.0f) < p) { outRays.push_back(*vit); } } globalLinesRenderer->Visualize(rays); CLEAR_CONTAINER(rays); return; } case '8': { isDepth = !isDepth; return; } case '9': { VssRayContainer rays; globalLinesRenderer->ApplyDepthPeeling(rays); // visualize VssRayContainer outRays; VssRayContainer::const_iterator vit, vit_end = rays.end(); const float p = 8.0f / (float)rays.size(); for (vit = rays.begin(); vit != vit_end; ++ vit) { if (Random(1.0f) < p) { outRays.push_back(*vit); } } globalLinesRenderer->Visualize(rays); CLEAR_CONTAINER(rays); return; } case '0': { VssRayContainer rays; globalLinesRenderer->ApplyDepthPeeling(rays); CLEAR_CONTAINER(rays); return; } default: return; } } GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor, const int texHeight, const int texWidth, const float eps, const int maxDepth, const bool sampleReverse): mNewTexture(NULL), mOldTexture(NULL), mPreprocessor(preprocessor), mTexHeight(texHeight), mTexWidth(texWidth), mEpsilon(eps), mMaxDepth(maxDepth), mSampleReverse(sampleReverse) { mRenderer = new GlRenderer(mPreprocessor->mSceneGraph, mPreprocessor->mViewCellsManager, mPreprocessor->mKdTree); } GlobalLinesRenderer::GlobalLinesRenderer(Preprocessor *preprocessor): mNewTexture(NULL), mOldTexture(NULL), mMaxDepth(40), mPreprocessor(preprocessor), mTexHeight(128), mTexWidth(128), mEpsilon(0.0001), mSampleReverse(true) { mRenderer = new GlRenderer(mPreprocessor->mSceneGraph, mPreprocessor->mViewCellsManager, mPreprocessor->mKdTree); } void GlobalLinesRenderer::DisplayBuffer(const bool isDepth) { if (!isDepth) mNewTexture->Bind(); else 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"); } GlobalLinesRenderer::~GlobalLinesRenderer() { if (sCgDepthPeelingProgram) cgDestroyProgram(sCgDepthPeelingProgram); if (sCgContext) cgDestroyContext(sCgContext); // init the receiving buffers delete mNewDepthBuffer; delete mOldDepthBuffer; delete mNewItemBuffer; delete mOldItemBuffer; DEL_PTR(mRenderer); } void GlobalLinesRenderer::InitRenderTexture(RenderTexture *rt) { // setup the rendering context for the RenderTexture rt->BeginCapture(); { //Reshape(mTexWidth, mTexHeight); glViewport(0, 0, mTexWidth, mTexHeight); SetFrustum(mWidth, mWidth, mNear, mFar); // for item buffer: white means no color glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glFrontFace(GL_CCW); glCullFace(GL_BACK); glDisable(GL_CULL_FACE); //glEnable(GL_CULL_FACE); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z, mTermination.x, mTermination.y, mTermination.z, mUpVec.x, mUpVec.y, mUpVec.z); } rt->EndCapture(); } void GlobalLinesRenderer::InitScene(const float alpha, const float beta) { AxisAlignedBox3 bbox = globalLinesRenderer->mPreprocessor->mKdTree->GetBox(); const float sceneSize = Magnitude(bbox.Diagonal()); // compute the center of the scene mTermination = bbox.Center(); // add a small offset to provide some randomness in the sampling if (0) { Vector3 offset( Random(sceneSize * 1e-3f), Random(sceneSize * 1e-3f), Random(sceneSize * 1e-3f)); mTermination += offset; } mNear = 1; mFar = sceneSize * 2; mWidth = sceneSize; ComputeLookAt(alpha, beta, mEyeVec, mUpVec, mLeftVec); mViewPoint = mTermination - 0.5f * sceneSize * mEyeVec; //cout << "termination point: " << mTermination << endl; //cout << "view point: " << mViewPoint << endl; //cout << "scene: " << bbox << endl; InitRenderTexture(mNewTexture); InitRenderTexture(mOldTexture); //cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl; } void GlobalLinesRenderer::InitScene(const SimpleRay &ray) { AxisAlignedBox3 bbox = globalLinesRenderer->mPreprocessor->mKdTree->GetBox(); const float sceneSize = Magnitude(bbox.Diagonal()); // compute the center of the scene mViewPoint = ray.mOrigin; mTermination = ray.mOrigin + ray.mDirection; mEyeVec = Normalize(ray.mDirection); mNear = 1; mFar = sceneSize * 2; mWidth = sceneSize; mEyeVec.RightHandedBase(mUpVec, mLeftVec); //cout << "termination point: " << mTermination << endl; //cout << "view point: " << mViewPoint << endl; //cout << "scene: " << bbox << endl; InitRenderTexture(mNewTexture); InitRenderTexture(mOldTexture); //cout << "eye: " << mEyeVec << " left: " << mLeftVec << " up: " << mUpVec << endl; } int GlobalLinesRenderer::CastGlobalLines(const float alpha, const float beta, VssRayContainer &rays) { InitScene(alpha, beta); // bind pixel shader implementing the front depth buffer functionality const int layers = ApplyDepthPeeling(rays); return layers; } int GlobalLinesRenderer::CastGlobalLines(const SimpleRay &ray, VssRayContainer &rays) { const long startTime = GetTime(); cout << "casting global lines ... " << endl; InitScene(ray); // bind pixel shader implementing the front depth buffer functionality const int layers = ApplyDepthPeeling(rays); const float rays_per_sec = (float)rays.size() / (TimeDiff(startTime, GetTime()) * 1e-3f); cout << "cast " << rays.size() << " samples in " << layers << " layers in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs (" << rays_per_sec << " rays/sec)" << endl; return layers; } void GlobalLinesRenderer::DrawGeometry() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glPushMatrix(); { //glLoadIdentity(); ObjectContainer::const_iterator oit, oit_end = mPreprocessor->mObjects.end(); Intersectable::NewMail(); mRenderer->RenderScene(); } glPopMatrix(); } void GlobalLinesRenderer::SwitchRenderTextures() { RenderTexture *buffer = mOldTexture; mOldTexture = mNewTexture; mNewTexture = buffer; } void GlobalLinesRenderer::ComputeLookAt(const float alpha, const float beta, Vector3 &eye, Vector3 &up, Vector3 &left) { eye.x = sin(alpha) * cos(beta); eye.y = sin(alpha) * sin(beta); eye.z = cos(alpha); eye.RightHandedBase(up, left); } void GlobalLinesRenderer::InitGl() { InitDevIl(); cout << "texwidth: " << mTexWidth << " texheight: " << mTexHeight << endl; 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(); // initialise the receiving buffers mNewDepthBuffer = new float[mTexWidth * mTexHeight]; mNewItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4]; mOldDepthBuffer = new float[mTexWidth * mTexHeight]; mOldItemBuffer = new unsigned char[mTexWidth * mTexHeight * 4]; for (int i = 0; i < mTexWidth * mTexHeight; ++ i) { mNewDepthBuffer[i] = 1; mOldDepthBuffer[i] = 1; mNewItemBuffer[i * 4] = 255; mNewItemBuffer[i * 4 + 1] = 255; mNewItemBuffer[i * 4 + 2] = 255; mNewItemBuffer[i * 4 + 3] = 255; mOldItemBuffer[i * 4] = 255; mOldItemBuffer[i * 4 + 1] = 255; mOldItemBuffer[i * 4 + 2] = 255; mOldItemBuffer[i * 4 + 3] = 255; } /*gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.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(mTexWidth, mTexHeight, true, true); #ifdef ATI mNewTexture->Initialize(true, true, false, false, false, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE); #else mNewTexture->Initialize(true, true, false, false, false, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE); #endif mOldTexture = new RenderTexture(mTexWidth, mTexHeight, true, true); #ifdef ATI mOldTexture ->Initialize(true, true, false, false, false, 8, 8, 8, 8, RenderTexture::RT_COPY_TO_TEXTURE); #else mOldTexture ->Initialize(true, true, false, false, false, 8, 8, 8, 8);//, RenderTexture::RT_COPY_TO_TEXTURE); #endif // 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"); // we need size of texture for scaling if (!mNewTexture->IsRectangleTexture()) { sTexWidthParam = cgGetNamedParameter(sCgDepthPeelingProgram, "invTexWidth"); } sStepSizeParam = cgGetNamedParameter(sCgDepthPeelingProgram, "stepSize"); cgGLSetParameter1f(sTexWidthParam, 1.0f / (float)mTexWidth); cgGLSetParameter1f(sStepSizeParam, mEpsilon); } 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); } const float alpha = 1.1; const float beta = 0.9; InitScene(alpha, beta); PrintGLerror("init"); } Intersectable *GlobalLinesRenderer::ExtractSamplePoint(float *depthBuffer, unsigned char *itemBuffer, const int x, const int y, Vector3 &hitPoint, const bool isFrontBuffer) const { const int depthIndex = x + mTexWidth * y; const int itemIndex = 4 * depthIndex; const float depth = depthBuffer[depthIndex]; const float eyeDist = mNear + (mFar - mNear) * depth; const float leftDist = -0.5f * mWidth + mWidth * ((float)x + 0.5f) / mTexWidth; const float upDist = -0.5f * mWidth + mWidth * ((float)y + 0.5f) / mTexHeight; hitPoint = mViewPoint + eyeDist * mEyeVec + upDist * mUpVec + leftDist * mLeftVec; unsigned char r = itemBuffer[itemIndex]; unsigned char g = itemBuffer[itemIndex + 1]; unsigned char b = itemBuffer[itemIndex + 2]; // 3 times 255 means no valid object if ((r == 255) && (g == 255) && (b == 255)) return NULL; const int id = mRenderer->GetId(r, g, b); //cout << "r: " << (int)r << "g: " << (int)g << " b: " << (int)b << " id: " << id << "|"; Intersectable *intersect = mPreprocessor->GetObjectById(id); const Vector3 dir = isFrontBuffer ? mEyeVec : -mEyeVec; // HACK: assume triangle intersectable const Vector3 norm = intersect->GetNormal(0); // test for invalid view space if (DotProd(dir, norm) >= -Limits::Small) return NULL; return intersect; } void GlobalLinesRenderer::ComputeBoundingQuad(int &xMin, int &yMin, int &xMax, int &yMax) { const AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox(); Matrix4x4 m(mEyeVec, mUpVec, mLeftVec); m.Invert(); Vector3 eye(m.x[0][0], m.x[1][0], m.x[2][0]); Vector3 up(m.x[0][0], m.x[1][1], m.x[2][1]); Vector3 left(m.x[0][2], m.x[1][2], m.x[2][2]); Vector3 boxMin(1e20f); Vector3 boxMax(-1e20f); for (int i = 0; i < 8; ++ i) { Vector3 vtx; bbox.GetVertex(i, vtx); Vector3 pt = vtx.x * eye + vtx.y * up + vtx.z * left; // TODO if (boxMin.x > pt.x) boxMin.x = pt.x; if (boxMin.y > pt.y) boxMin.y = pt.y; if (boxMin.z > pt.z) boxMin.z = pt.z; if (boxMax.x < pt.x) boxMax.x = pt.x; if (boxMax.y < pt.y) boxMax.y = pt.y; if (boxMax.z < pt.z) boxMax.z = pt.z; } cout << "xmin: " << boxMin.x << " ymin " << boxMin.y << " xmax: " << boxMax.x << " ymax: " << boxMax.y << endl; xMin = (int)(-0.5f * mWidth + mWidth * (boxMin.x + 0.5f) / mTexWidth); yMin = (int)(-0.5f * mWidth + mWidth * (boxMin.y + 0.5f) / mTexHeight); xMax = (int)(-0.5f * mWidth + mWidth * (boxMax.x + 0.5f) / mTexWidth); yMax = (int)(-0.5f * mWidth + mWidth * (boxMax.y + 0.5f) / mTexHeight); } bool GlobalLinesRenderer::ProcessDepthBuffer(VssRayContainer &vssRays, const bool oldBufferInitialised, const int pass) { GrabDepthBuffer(mNewDepthBuffer, mNewTexture); GrabItemBuffer(mNewItemBuffer, mNewTexture); if (oldBufferInitialised) { GrabDepthBuffer(mOldDepthBuffer, mOldTexture); GrabItemBuffer(mOldItemBuffer, mOldTexture); } else { for (int i = 0; i < mTexWidth * mTexHeight; ++ i) { mOldDepthBuffer[i] = 0; mOldItemBuffer[i * 4] = 255; mOldItemBuffer[i * 4 + 1] = 255; mOldItemBuffer[i * 4 + 2] = 255; mOldItemBuffer[i * 4 + 3] = 255; } } int xMin, yMin, xMax, yMax; ComputeBoundingQuad(xMin, yMin, xMax, yMax); cout << "xmin2: " << xMin << " ymin " << yMin << " xmax: " << xMax << " ymax: " << yMax << endl; ///////////////// // test for validity bool buffersEqual = true; bool bufferEmpty = true; for (int y = 0; y < mTexHeight; ++ y) { for (int x = 0; x < mTexWidth; ++ x) { const int depthIndex = x + mTexWidth * y; const int itemIndex = 4 * depthIndex; if (mOldItemBuffer[itemIndex] != mNewItemBuffer[itemIndex]) { buffersEqual = false; } unsigned char r = mNewItemBuffer[itemIndex]; unsigned char g = mNewItemBuffer[itemIndex + 1]; unsigned char b = mNewItemBuffer[itemIndex + 2]; // 3 times 255 means no valid object if (!((r == 255) && (g == 255) && (b == 255))) { bufferEmpty = false; } } // early exit if (!buffersEqual && !bufferEmpty) break; } // depth buffer not valid if (buffersEqual || bufferEmpty) { cout << "stopped at layer " << pass << endl; return false; } for (int y = 0; y < mTexHeight; ++ y) { for (int x = 0; x < mTexWidth; ++ x) { Vector3 newPt, oldPt; Intersectable *termObj1 = ExtractSamplePoint(mNewDepthBuffer, mNewItemBuffer, x, y, newPt, true); Intersectable *termObj2 = ExtractSamplePoint(mOldDepthBuffer, mOldItemBuffer, x, y, oldPt, false); if (!termObj1 && !termObj2) // we do not create a ray continue; Vector3 clippedOldPt, clippedNewPt; if (ClipToViewSpaceBox(oldPt, newPt, clippedOldPt, clippedNewPt))//;if(1) { //clippedOldPt = oldPt; //clippedNewPt = newPt; // create rays in both directions if (termObj1) { vssRays.push_back(new VssRay(clippedOldPt, clippedNewPt, NULL, termObj1, pass)); //cout << "new pt: " << newPt << endl; } if (mSampleReverse && termObj2) { vssRays.push_back(new VssRay(clippedNewPt, clippedOldPt, NULL, termObj2, pass)); //cout << "old pt: " << oldPt << endl; } } } } return true; } bool GlobalLinesRenderer::ClipToViewSpaceBox(const Vector3 &origin, const Vector3 &termination, Vector3 &clippedOrigin, Vector3 &clippedTermination) { Ray ray(origin, termination - origin, Ray::LINE_SEGMENT); ray.Precompute(); float tmin, tmax; //const AxisAlignedBox3 bbox = mPreprocessor->mViewCellsManager->GetViewSpaceBox(); // hack AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox(); //bbox.Enlarge(1); if (!bbox.ComputeMinMaxT(ray, &tmin, &tmax) || (tmin >= tmax)) { return false; } if (tmin >= 1.0f || tmax <= 0.0f) return false; if (tmin > 0.0f) clippedOrigin = ray.Extrap(tmin); else clippedOrigin = origin; if (tmax < 1.0f) clippedTermination = ray.Extrap(tmax); else clippedTermination = termination; return true; } void GlobalLinesRenderer::Run() { glutMainLoop(); } void GlobalLinesRenderer::Visualize(const VssRayContainer &vssRays) { cout << "exporting visualization ... "; Exporter *exporter = Exporter::GetExporter("globalLines.wrl"); if (!exporter) return; exporter->SetWireframe(); //exporter->ExportGeometry(preprocessor->mObjects); exporter->SetFilled(); VssRayContainer::const_iterator vit, vit_end = vssRays.end(); VssRayContainer outRays; Intersectable::NewMail(); for (vit = vssRays.begin(); vit != vit_end; ++ vit) { VssRay *ray = *vit; Intersectable *obj = (*vit)->mTerminationObject; if (!obj->Mailed()) { obj->Mail(); exporter->ExportIntersectable(obj); } //if (ray->mPass == 4) outRays.push_back(ray); } //exporter->ExportRays(outRays); cout << "finished" << endl; delete exporter; } void GlobalLinesRenderer::GrabDepthBuffer(float *data, RenderTexture *rt) { rt->BindDepth(); rt->EnableTextureTarget(); const int texFormat = GL_DEPTH_COMPONENT; glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_FLOAT, data); mNewTexture->DisableTextureTarget(); } void GlobalLinesRenderer::GrabItemBuffer(unsigned char *data, RenderTexture *rt) { rt->Bind(); rt->EnableTextureTarget(); const int texFormat = GL_RGBA; glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data); mNewTexture->DisableTextureTarget(); } void GlobalLinesRenderer::ExportDepthBuffer() { mNewTexture->BindDepth(); mNewTexture->EnableTextureTarget(); cout << "depth: " << mNewTexture->GetDepthBits() << endl; const int components = 1;//mNewTexture->GetDepthBits() / 8; float *data = new float[mTexWidth * mTexHeight * 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); string filename("depth.tga"); ilRegisterType(IL_FLOAT); const int depth = 1; const int bpp = components; ilTexImage(mTexWidth, mTexHeight, 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::ExportItemBuffer() { mNewTexture->Bind(); mNewTexture->EnableTextureTarget(); cout << "depth: " << mNewTexture->GetDepthBits() << endl; const int components = 4;//mNewTexture->GetDepthBits() / 8; unsigned char *data = new unsigned char [mTexWidth * mTexHeight * components]; //const int texFormat = WGL_TEXTURE_DEPTH_COMPONENT_NV; const int texFormat = GL_RGBA; glGetTexImage(mNewTexture->GetTextureTarget(), 0, texFormat, GL_UNSIGNED_BYTE, data); string filename("items.jpg"); ilRegisterType(IL_UNSIGNED_BYTE); const int depth = 1; const int bpp = components; ilTexImage(mTexWidth, mTexHeight, depth, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data); ilSaveImage((char *const)filename.c_str()); cout << "finished" << endl; delete data; cout << "data deleted" << endl; mNewTexture->DisableTextureTarget(); PrintGLerror("grab texture"); } int GlobalLinesRenderer::ApplyDepthPeeling(VssRayContainer &rays) { int layers = 1; mNewTexture->BeginCapture(); { //cgGLBindProgram(sCgPassThroughProgram); //cgGLEnableProfile(sCgFragmentProfile); DrawGeometry(); } mNewTexture->EndCapture(); PrintGLerror("firstpass"); if (mNewTexture->IsRectangleTexture()) cout << "rect" << endl; // process the buffers for the first layer ProcessDepthBuffer(rays, false, 0); long renderTime = 0; long bufferTime = 0; for(; layers < mMaxDepth; ++ layers) { cout << "."; const long startRenderTime = GetTime(); // Peel another layer // switch pointer between rendertextures SwitchRenderTextures(); mNewTexture->BeginCapture(); { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); cgGLBindProgram(sCgDepthPeelingProgram); cgGLEnableProfile(sCgFragmentProfile); cgGLSetTextureParameter(sTextureParam, mOldTexture->GetDepthTextureID()); cgGLEnableTextureParameter(sTextureParam); DrawGeometry(); cgGLDisableTextureParameter(sTextureParam); cgGLDisableProfile(sCgFragmentProfile); } mNewTexture->EndCapture(); renderTime += TimeDiff(startRenderTime, GetTime()); const long startBufferTime = GetTime(); // process the buffers for following layer // jump out of loop for the first invalid buffer if (!ProcessDepthBuffer(rays, true, layers)) break; bufferTime += TimeDiff(startBufferTime, GetTime()); } Debug << "time spent in rendering: " << renderTime * 1e-3f << endl; Debug << "time spent in buffer: " << bufferTime * 1e-3f << endl; PrintGLerror("endpeeling"); return layers; } } #endif