Hello Constantin, On 09/16/2010 07:37 AM, Constantin Müller wrote:
I could apply the patch to the SVN repository and the github repository as well. Thanks for your instructions. I now just added the second patch, because otherwise it could not apply the second patch. Is this right, or did I make a mistake and lost some changes?
the second patch replaced the first one, that is you should apply only the second patch to a clean checkout.
The patch does not work for me. My program crashs, because the image is still not valid, but a glReadPixels is executed to write to the Image, this results in a writing access violation. Here is the glTrace to the point, where the program crashs. | ... | glCallList(1) | glGetError() | glActiveTextureARB(GL_TEXTURE0) | glDisable(GL_TEXTURE_2D) | glGetError() | glColorMask(TRUE, TRUE, TRUE, TRUE) | glDepthFunc(GL_LEQUAL) | glDepthMask(TRUE) | glDisable(GL_LIGHTING) | glDisable(GL_COLOR_MATERIAL) | glDepthMask(FALSE) | glDepthMask(TRUE) | glMatrixMode(GL_PROJECTION) | glPopMatrix() | glMatrixMode(GL_MODELVIEW) | glPopAttrib() | glReadBuffer(GL_COLOR_ATTACHMENT0_EXT) | glReadPixels(0, 0, 64, 64, GL_RGBA, GL_UNSIGNED_BYTE, 074B0888) | glReadBuffer(GL_POINTS) | glGetError() | glReadBuffer(GL_POINTS) | glReadPixels(0, 0, 64, 64, GL_DEPTH_STENCIL_NV, GL_UNSIGNED_INT_24_8_NV, 00000000)
^^^^^hm, I missed this before, but there is a NULL pointer passed to glReadPixels, in other words depthimage->editData() returns NULL. I guess the image fails to actually allocate memory because it does not know how to deal with the image format (specifically it seems to fail to determine the number of bytes per pixel).
I've attached two patches (fbo.detph.stencil.readback.03.diff replaces the previous fbo.detph.stencil.readback.02.diff [1]), with those two patches it reads back values for me (using a slightly modified Examples/Simple/fbotexture.cpp - also attached).
Sorry for all the back and forth, hopefully you'll have more success with this iteration.
Cheers, Carsten [1] either use svn revert <filename> to undo the previous patch(es) or use: patch -p1 -R <patch.diff to apply a patch reversed, that is undo it when it is already applied.
diff --git a/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.cpp b/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.cpp index af4cf4e..ac777f9 100644 --- a/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.cpp +++ b/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.cpp @@ -107,6 +107,9 @@ OSG_USING_NAMESPACE UInt32 FrameBufferObject::_uiFramebuffer_object_extension = Window::invalidExtensionID; +UInt32 FrameBufferObject::_uiPackedDepthStencilExtension = + Window::invalidExtensionID; + UInt32 FrameBufferObject::_uiFuncGenFramebuffers = Window::invalidFunctionID; @@ -179,6 +182,8 @@ void FrameBufferObject::initMethod(InitPhase ePhase) { _uiFramebuffer_object_extension = Window::registerExtension("GL_EXT_framebuffer_object"); + _uiPackedDepthStencilExtension = + Window::registerExtension("GL_EXT_packed_depth_stencil"); _uiFuncGenFramebuffers = Window::registerFunction ( @@ -403,6 +408,33 @@ void FrameBufferObject::deactivate (DrawEnv *pEnv) (*attIt)->processPreDeactivate(pEnv, index); } + + if(_sfDepthAttachment .getValue() != NULL && + _sfStencilAttachment.getValue() != NULL ) + { + if(_sfDepthAttachment.getValue() == _sfStencilAttachment.getValue()) + { + _sfDepthAttachment.getValue()->processPreDeactivate( + pEnv, GL_NONE); + } + else + { + _sfDepthAttachment .getValue()->processPreDeactivate( + pEnv, GL_NONE); + _sfStencilAttachment.getValue()->processPreDeactivate( + pEnv, GL_NONE); + } + } + else if(_sfDepthAttachment.getValue() != NULL) + { + _sfDepthAttachment .getValue()->processPreDeactivate( + pEnv, GL_NONE); + } + else if(_sfStencilAttachment.getValue() != NULL) + { + _sfStencilAttachment.getValue()->processPreDeactivate( + pEnv, GL_NONE); + } } osgGlBindFramebufferProc(GL_FRAMEBUFFER_EXT, 0); diff --git a/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.h b/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.h index 2ebedaf..8437854 100644 --- a/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.h +++ b/Source/System/Window/FrameBufferObjects/OSGFrameBufferObject.h @@ -133,6 +133,7 @@ class OSG_SYSTEM_DLLMAPPING FrameBufferObject : /*! \{ */ static UInt32 _uiFramebuffer_object_extension; + static UInt32 _uiPackedDepthStencilExtension; static UInt32 _uiFuncGenFramebuffers; static UInt32 _uiFuncCheckFramebufferStatus; diff --git a/Source/System/Window/FrameBufferObjects/OSGRenderBuffer.cpp b/Source/System/Window/FrameBufferObjects/OSGRenderBuffer.cpp index edc7891..1b8c819 100644 --- a/Source/System/Window/FrameBufferObjects/OSGRenderBuffer.cpp +++ b/Source/System/Window/FrameBufferObjects/OSGRenderBuffer.cpp @@ -280,7 +280,15 @@ void RenderBuffer::processPreDeactivate (DrawEnv *pEnv, UInt32 index) pImg->set(pImg->getPixelFormat(), pImg->getWidth (), - pImg->getHeight ()); + pImg->getHeight (), + pImg->getDepth (), + pImg->getMipMapCount(), + pImg->getFrameCount (), + pImg->getFrameDelay (), + NULL, + pImg->getDataType (), + true, + pImg->getSideCount () ); } // select GL_COLORATTACHMENTn and read data into image
diff --git a/Source/System/Image/WS/OSGImage.cpp b/Source/System/Image/WS/OSGImage.cpp index 9d1b928..a0b1023 100644 --- a/Source/System/Image/WS/OSGImage.cpp +++ b/Source/System/Image/WS/OSGImage.cpp @@ -99,6 +99,7 @@ UInt32 Image::_formatDic[][2] = { OSG_RGBA_DXT1, 4 }, { OSG_RGBA_DXT3, 4 }, { OSG_RGBA_DXT5, 4 }, + { OSG_DEPTH_STENCIL_PF, 1 }, { OSG_ALPHA_INTEGER_PF, 1 }, { OSG_RGB_INTEGER_PF, 3 }, { OSG_RGBA_INTEGER_PF, 4 }, @@ -117,7 +118,8 @@ Int32 Image::_typeDic[][2] = { OSG_FLOAT32_IMAGEDATA, 4 }, { OSG_FLOAT16_IMAGEDATA, 2 }, { OSG_INT16_IMAGEDATA, 2 }, - { OSG_INT32_IMAGEDATA, 4 } + { OSG_INT32_IMAGEDATA, 4 }, + { OSG_UINT24_8_IMAGEDATA, 4 } }; /*----------------------------- class specific ----------------------------*/ @@ -234,6 +236,9 @@ void Image::dump( UInt32 , case OSG_RGBA_DXT5: pfStr = "RGBA_DXT5"; break; + case OSG_DEPTH_STENCIL_PF: + pfStr = "DEPTH_STENCIL"; + break; case OSG_ALPHA_INTEGER_PF: pfStr = "ALPHA_INTEGER"; break; @@ -283,6 +288,9 @@ void Image::dump( UInt32 , case OSG_INT32_IMAGEDATA: typeStr = "IMAGEDATA_TYPE INT32"; break; + case OSG_UINT24_8_IMAGEDATA: + typeStr = "IMAGEDATA_TYPE UINT24_8"; + break; default: typeStr = "UNKNOWN_IMAGEDATA_TYPE"; diff --git a/Source/System/Image/WS/OSGImage.h b/Source/System/Image/WS/OSGImage.h index 8ac16f3..21d5bec 100644 --- a/Source/System/Image/WS/OSGImage.h +++ b/Source/System/Image/WS/OSGImage.h @@ -70,6 +70,8 @@ class OSG_SYSTEM_DLLMAPPING Image : public ImageBase OSG_I_PF = GL_INTENSITY, OSG_L_PF = GL_LUMINANCE, OSG_LA_PF = GL_LUMINANCE_ALPHA, + OSG_RGB_PF = GL_RGB, + OSG_RGBA_PF = GL_RGBA, /*** BGR ***/ #if defined(GL_BGR) OSG_BGR_PF = GL_BGR, @@ -115,9 +117,15 @@ class OSG_SYSTEM_DLLMAPPING Image : public ImageBase OSG_RGBA_DXT5 = 0, #endif - OSG_RGB_PF = GL_RGB, - OSG_RGBA_PF = GL_RGBA, - +/*** GL_EXT_packed_depth_stencil ***/ +#if defined(GL_DEPTH_STENCIL_EXT) + OSG_DEPTH_STENCIL_PF = GL_DEPTH_STENCIL_EXT, +#elif defined(GL_DEPTH_STENCIL_NV) + OSG_DEPTH_STENCIL_PF = GL_DEPTH_STENCIL_NV, +#else + OSG_DEPTH_STECIL_PF = 0 +#endif + OSG_ALPHA_INTEGER_PF = GL_ALPHA_INTEGER_EXT, OSG_RGB_INTEGER_PF = GL_RGB_INTEGER_EXT, OSG_RGBA_INTEGER_PF = GL_RGBA_INTEGER_EXT, @@ -136,7 +144,16 @@ class OSG_SYSTEM_DLLMAPPING Image : public ImageBase OSG_FLOAT16_IMAGEDATA = GL_HALF_FLOAT_NV, OSG_FLOAT32_IMAGEDATA = GL_FLOAT, OSG_INT16_IMAGEDATA = GL_SHORT, - OSG_INT32_IMAGEDATA = GL_INT + OSG_INT32_IMAGEDATA = GL_INT, + +/*** GL_EXT_packed_depth_stencil ***/ +#if defined(GL_UNSIGNED_INT_24_8_EXT) + OSG_UINT24_8_IMAGEDATA = GL_UNSIGNED_INT_24_8_EXT +#elif defined(GL_UNSIGNED_INT_24_8_NV) + OSG_UINT24_8_IMAGEDATA = GL_UNSIGNED_INT_24_8_NV +#else + OSG_UINT24_8_IMAGEDATA = GL_NONE +#endif }; enum ResUnit
// OpenSG Tutorial Example: FBO Texture // // This example shows how to use FrameBufferObject and SimpleStage to render // a subtree of the scene graph to a texture and then use that texture // when drawing another part of the scene. // // The scene graph constructed in this example looks like this: // // scene[Group] -+- fboScene[SimpleStage] --- fboScene --- {loaded model + // | light and beacon} // | // +- flagScene[Group] --- {flag and pole} // // If you run this example and zoom in close to the flag or move it to the // edge of the screen the model on it may stop rotating. This happens because // the model actually is positioned about half way up the flag's pole and // get's frustum culled if that part of the scene is outside the camera // frustum. #ifdef OSG_BUILD_ACTIVE // Headers #include <OSGGLUT.h> #include <OSGConfig.h> #include <OSGSimpleGeometry.h> #include <OSGGLUTWindow.h> #include <OSGSimpleSceneManager.h> #include <OSGBaseFunctions.h> #include <OSGTransform.h> #include <OSGComponentTransform.h> #include <OSGSimpleStage.h> #include <OSGPointLight.h> #include <OSGFrameBufferObject.h> #include <OSGTextureBuffer.h> #include <OSGRenderBuffer.h> #include <OSGTextureObjChunk.h> #include <OSGTextureEnvChunk.h> #include <OSGTexGenChunk.h> #include <OSGTwoSidedLightingChunk.h> #include <OSGSceneFileHandler.h> #include <OSGImageFunctions.h> #include <OSGSimpleTexturedMaterial.h> #include <OSGTextureTransformChunk.h> #include <OSGGradientBackground.h> #include <OSGPerspectiveCamera.h> #else // Headers #include <OpenSG/OSGGLUT.h> #include <OpenSG/OSGConfig.h> #include <OpenSG/OSGSimpleGeometry.h> #include <OpenSG/OSGGLUTWindow.h> #include <OpenSG/OSGSimpleSceneManager.h> #include <OpenSG/OSGBaseFunctions.h> #include <OpenSG/OSGTransform.h> #include <OpenSG/OSGComponentTransform.h> #include <OpenSG/OSGSimpleStage.h> #include <OpenSG/OSGPointLight.h> #include <OpenSG/OSGFrameBufferObject.h> #include <OpenSG/OSGTextureBuffer.h> #include <OpenSG/OSGRenderBuffer.h> #include <OpenSG/OSGTextureObjChunk.h> #include <OpenSG/OSGTextureEnvChunk.h> #include <OpenSG/OSGTexGenChunk.h> #include <OpenSG/OSGTwoSidedLightingChunk.h> #include <OpenSG/OSGSceneFileHandler.h> #include <OpenSG/OSGImageFunctions.h> #include <OpenSG/OSGSimpleTexturedMaterial.h> #include <OpenSG/OSGTextureTransformChunk.h> #include <OpenSG/OSGGradientBackground.h> #include <OpenSG/OSGPerspectiveCamera.h> #endif // flag parameters const OSG::Real32 flagHeight = 8.0f; const OSG::Real32 flagWidth = 16.0f; const OSG::UInt32 flagGeoHor = static_cast<OSG::UInt32>(flagWidth * 3); const OSG::UInt32 flagGeoVert = static_cast<OSG::UInt32>(flagHeight / 2); const OSG::Real32 flagWaveDamp = 0.06f; const OSG::Real32 poleHeight = 24.0f; const OSG::Real32 poleDia = poleHeight * 0.01f; // fbo size -- you can increase these values to get a higher resolution image const OSG::UInt32 fboWidth = static_cast<OSG::UInt32>(flagWidth * 32); const OSG::UInt32 fboHeight = static_cast<OSG::UInt32>(flagHeight * 32); // global variables OSG::SimpleSceneManager *mgr; OSG::NodeRefPtr stageCamBeaconN; OSG::TransformRefPtr stageCamBeacon; OSG::NodeRefPtr modelTransN; OSG::TransformRefPtr modelTrans; // forward declaration so we can have the interesting stuff upfront int setupGLUT (int *argc, char *argv[]); OSG::NodeTransitPtr buildFBOScene(int argc, char *argv[]); OSG::NodeTransitPtr buildScene (OSG::TextureObjChunkRefPtr fboTex); /* Construct a scene that uses a Stage to render a subtree to an FBO (making the result available as a texture) and use that in another subtree. */ OSG::NodeTransitPtr buildStage(int argc, char *argv[]) { /* Begin by setting up an FBO with a TextureBuffer, so we can capture and reuse what is being rendered to the FBO. */ OSG::ImageRefPtr fboTexImg = OSG::Image ::create(); OSG::TextureObjChunkRefPtr fboTex = OSG::TextureObjChunk ::create(); OSG::FrameBufferObjectRefPtr fbo = OSG::FrameBufferObject::create(); OSG::TextureBufferRefPtr texBuf = OSG::TextureBuffer ::create(); OSG::ImageRefPtr depthImg = OSG::Image ::create(); OSG::RenderBufferRefPtr depthBuf = OSG::RenderBuffer ::create(); // set up the texture ... fboTexImg->set(OSG::Image::OSG_RGB_PF, fboWidth, fboHeight); fboTex->setImage(fboTexImg); // ... and add it to the texture buffer texBuf->setTexture(fboTex); // add a depth attachment, otherwise there is no depth buffer when // rendering to the FBO bool depthImgAlloc = depthImg->set(OSG::Image::OSG_DEPTH_STENCIL_PF, fboWidth, fboHeight, 1, 1, 1, 0.0, NULL, OSG::Image::OSG_UINT24_8_IMAGEDATA, true, 1); std::cout << "depthImgAlloc: '" << depthImgAlloc << "' editData '" << reinterpret_cast<OSG::UInt32*>(depthImg->editData()) << "'" << std::endl; depthBuf->setReadBack(true); depthBuf->setImage(depthImg); depthBuf->setInternalFormat(OSG::Image::OSG_DEPTH_STENCIL_PF); // make the fbo render to the texture fbo->setColorAttachment (texBuf, 0); fbo->setDepthAttachment (depthBuf ); fbo->setStencilAttachment(depthBuf ); fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); fbo->setWidth (fboWidth ); fbo->setHeight(fboHeight); /* enable post processing for the FBO, this generates mip maps for the texture if a mip map filter is active (the default for minFilter is GL_LINEAR_MIPMAP_LINEAR). Alternatively, one could set the texture filter to one that does not require mip maps, e.g. call fboTex->setMinFilter(GL_LINEAR); */ fbo->setPostProcessOnDeactivate(true); /* Next we set up a Stage, which renders the subtree below it to its render target (the FBO from above). */ OSG::SimpleStageRefPtr stage = OSG::SimpleStage::create(); OSG::NodeRefPtr stageN = OSG::makeNodeFor(stage); // add the scene to be rendered to the fbo as child of the Stage OSG::NodeRefPtr fboSceneN = buildFBOScene(argc, argv); stageN->addChild(fboSceneN); // make the stage render to the FBO instead of the normal framebuffer stage->setRenderTarget(fbo); // use the full size of the target (this is like setting up the viewport // of the stage) stage->setSize(0.0f, 0.0f, 1.0f, 1.0f); // set a different background for things on the stage ... OSG::GradientBackgroundRefPtr gb = OSG::GradientBackground::create(); gb->addLine(OSG::Color3f(0.3f, 0.3f, 0.8f), 0.0f); gb->addLine(OSG::Color3f(0.5f, 0.5f, 0.5f), 1.0f); stage->setBackground(gb); // ... and add a camera OSG::PerspectiveCameraRefPtr stageCam = OSG::PerspectiveCamera::create(); stage->setCamera(stageCam); stageCam->setBeacon(stageCamBeaconN); stageCam->setNear ( 0.1f); stageCam->setFar (1000.0); stageCam->setFov ( 1.5); // add the scene using the fbo OSG::NodeRefPtr sceneN = buildScene(fboTex); // place the stage and the scene using the fbo under a common group OSG::NodeRefPtr rootN = OSG::makeCoredNode<OSG::Group>(); rootN->addChild(stageN); rootN->addChild(sceneN); return OSG::NodeTransitPtr(rootN); } // Initialize GLUT & OpenSG and set up the scene int main(int argc, char **argv) { // OSG init OSG::osgInit(argc,argv); // GLUT init int winid = setupGLUT(&argc, argv); // open a new scope, because the pointers below should go out of scope // before entering glutMainLoop. // Otherwise OpenSG will complain about objects being alive after shutdown. { // the connection between GLUT and OpenSG OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create(); gwin->setGlutId(winid); gwin->init(); OSG::NodeRefPtr scene = buildStage(argc, argv); OSG::commitChanges(); // create the SimpleSceneManager helper mgr = new OSG::SimpleSceneManager; // tell the manager what to manage mgr->setWindow(gwin ); mgr->setRoot (scene); // show the whole scene mgr->showAll(); } // GLUT main loop glutMainLoop(); return 0; } // // GLUT callback functions // // react to size changes void reshape(int w, int h) { mgr->resize(w, h); glutPostRedisplay(); } // react to mouse button presses void mouse(int button, int state, int x, int y) { if (state) mgr->mouseButtonRelease(button, x, y); else mgr->mouseButtonPress(button, x, y); glutPostRedisplay(); } // react to mouse motions with pressed buttons void motion(int x, int y) { mgr->mouseMove(x, y); glutPostRedisplay(); } void update(void) { glutPostRedisplay(); } // redraw the window void display( void ) { static OSG::Real64 t0 = OSG::getSystemTime(); // get the current time OSG::Real64 t = OSG::getSystemTime() - t0; OSG::Matrix m; OSG::Quaternion q; q.setValueAsAxisDeg(0, 1, 0, t * 10.f); m.setRotate(q); modelTrans->setMatrix(m); OSG::commitChangesAndClear(); mgr->redraw(); } // react to keys void keyboard(unsigned char k, int , int ) { switch(k) { case 27: { // clean up global variables delete mgr; stageCamBeaconN = NULL; stageCamBeacon = NULL; modelTransN = NULL; modelTrans = NULL; OSG::osgExit(); exit(0); } break; } } // setup the GLUT library which handles the windows for us int setupGLUT(int *argc, char *argv[]) { glutInit(argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); int winid = glutCreateWindow("OpenSG"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc(keyboard); // call the redraw function whenever there's nothing else to do glutIdleFunc(update); return winid; } /* Loads a model given on the command line or creates a fallback. This scene is rendered to a texture (fboTexture) which is later used on another object, however none of this happens in here, only the scene is constructed. */ OSG::NodeTransitPtr buildFBOScene(int argc, char *argv[]) { OSG::NodeRefPtr modelN; if(argc > 1) modelN = OSG::SceneFileHandler::the()->read(argv[1]); // no argument or loading failed -> use a torus if(modelN == NULL) modelN = OSG::makeTorus(0.3f, 4, 16, 64); OSG::commitChanges(); OSG::Pnt3f bbMin, bbMax; modelN->updateVolume(); modelN->getVolume().getBounds(bbMin, bbMax); OSG::NodeRefPtr fboSceneN = OSG::makeCoredNode<OSG::Group>(); stageCamBeaconN = OSG::makeCoredNode<OSG::Transform>(&stageCamBeacon); modelTransN = OSG::makeCoredNode<OSG::Transform>(&modelTrans); // move the camera back OSG::Real32 bbDia = (bbMax - bbMin).length(); stageCamBeacon->editMatrix().setTranslate(OSG::Vec3f(0.0f, 0.0f, bbDia)); OSG::PointLightRefPtr light; OSG::NodeRefPtr lightN = OSG::makeCoredNode<OSG::PointLight>(&light); light->setBeacon(stageCamBeaconN); fboSceneN->addChild(lightN ); fboSceneN->addChild(stageCamBeaconN); lightN->addChild(modelTransN); modelTransN->addChild(modelN); return OSG::NodeTransitPtr(fboSceneN); } // create a wood texture OSG::SimpleTexturedMaterialTransitPtr createWoodMaterial(void) { OSG::SimpleTexturedMaterialRefPtr mat = OSG::SimpleTexturedMaterial::create(); OSG::ImageRefPtr img = OSG::Image::create(); createNoise(img, OSG::Image::OSG_L_PF, 7, 64); mat->setImage(img); mat->setEnvMode(GL_MODULATE); mat->setDiffuse(OSG::Color3f(0.9f, 0.57f, 0.1f)); mat->setSpecular(OSG::Color3f(0.2f, 0.2f, 0.1f)); OSG::TextureTransformChunkRefPtr ttrans = OSG::TextureTransformChunk::create(); OSG::Matrix m; m.setScale(2.0, 8.0, 2.0); ttrans->setMatrix(m); mat->addChunk(ttrans); return OSG::SimpleTexturedMaterialTransitPtr(mat); } /* Builds a scene with a flag on a pole. The flag is textured with the image of the fbo scene (fboTexture). */ OSG::NodeTransitPtr buildScene(OSG::TextureObjChunkRefPtr fboTex) { OSG::NodeRefPtr flagScene = OSG::makeCoredNode<OSG::Group>(); OSG::GeometryRefPtr flagGeo = OSG::makePlaneGeo(flagWidth, flagHeight, flagGeoHor, flagGeoVert); // disable caching as we will change this geometry every frame flagGeo->setDlistCache(false); OSG::SimpleMaterialRefPtr flagMat = OSG::SimpleMaterial ::create(); OSG::TextureEnvChunkRefPtr fboTexEnv = OSG::TextureEnvChunk::create(); fboTexEnv->setEnvMode(GL_REPLACE); flagMat->addChunk(fboTex ); flagMat->addChunk(fboTexEnv); // add a light glossy effect (environment noise-map) if (0) { OSG::ImageRefPtr noise = OSG::Image::create(); createNoise(noise, OSG::Image::OSG_I_PF, 5, 256); // make noise image darker (as it will be GL_ADDed) for(OSG::UInt32 i = 0; i < noise->getSize(); ++i) noise->editData()[i] >>= 2; // *= 0.125 OSG::TextureObjChunkRefPtr glossObj = OSG::TextureObjChunk::create(); OSG::TextureEnvChunkRefPtr glossEnv = OSG::TextureEnvChunk::create(); glossObj->setImage(noise); glossEnv->setEnvMode(GL_ADD); OSG::TexGenChunkRefPtr envMap = OSG::TexGenChunk::create(); envMap->setGenFuncS(GL_SPHERE_MAP); envMap->setGenFuncT(GL_SPHERE_MAP); // add for use with 2nd texture unit flagMat->addChunk(glossObj, 1); flagMat->addChunk(glossEnv, 1); flagMat->addChunk(envMap, 1); } flagMat->addChunk( OSG::StateChunkRefPtr(OSG::TwoSidedLightingChunk::create())); flagMat->setSpecular(OSG::Color3f(0.4f, 0.4f, 0.4f)); flagMat->setDiffuse (OSG::Color3f(0.7f, 0.7f, 0.7f)); flagGeo->setMaterial(flagMat); // create transform node to hook up the flag to the pole OSG::ComponentTransformRefPtr flagTrans; OSG::NodeRefPtr flagTransN = OSG::makeCoredNode<OSG::ComponentTransform>(&flagTrans); OSG::Vec3f v(0.5f * flagWidth, 0.5f * (poleHeight - flagHeight) , 0.0f); flagTrans->setTranslation(v); // attach flag-geometry to transform-node flagTransN->addChild(OSG::NodeRefPtr(OSG::makeNodeFor(flagGeo))); // build flag pole OSG::GeometryRefPtr pole = OSG::makeCylinderGeo(poleHeight, poleDia, 24, true, true, true); OSG::NodeRefPtr poleN = OSG::makeNodeFor(pole); OSG::MaterialRefPtr woodMat = createWoodMaterial(); pole->setMaterial(woodMat); // attach objects to group node flagScene->addChild(flagTransN); flagScene->addChild(poleN ); return OSG::NodeTransitPtr(flagScene); }
------------------------------------------------------------------------------ Start uncovering the many advantages of virtual appliances and start using them to simplify application deployment and accelerate your shift to cloud computing. http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________ Opensg-users mailing list Opensg-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensg-users