Hello Thomas, thanks for the example!
On 05/23/2011 02:43 AM, Henn, Thomas wrote:
I don't really think it's a BlendChunk issue, but there might be a problem how MultiPassMaterial handles a mixture of transparent and non-transparent materials. In the test case I attached, at first everything looks good. But if you rotate the scene it looks like the z-buffer test is turned off for both materials, not only for the transparent material...
OpenSG always has the depth test enabled, but disables depth writes for transparent objects. Mixing transparent and non-transparent materials in an MPM is difficult because normally OpenSG sorts objects that are transparent into a draw tree that is processed after all opaque objects. For an object with MPM this would require splitting the passes based on whether they are transparent or not, which conflicts with running the passes in the order specified by the MPM.
One problem in your example is that depth writes are disabled for the blue part, you can fix that by adding a DepthChunk to it (the default settings for it are fine). This will get rid of the issue of the red half shining through the blue one. The other problem is that the red part does not seem to be "on top" of the blue one when viewed from that side of the scene. That is because the depth sorting for transparent objects works on the per-object level not per-polygon/triangle. For this case this can be mostly worked around by making the blue material the first pass in MPM (to ensure opaque is rendered before transparent) and forcing the MPM to be considered transparent (normally it looks at the first pass material to decide this automatically):
DepthChunkPtr dc = DepthChunk::create(); SimpleMaterialPtr blue = SimpleMaterial::create(); beginEditCP(blue); blue->setDiffuse(Color3f(0,0,1)); blue->setTransparency(0.0); // no transparency blue->addChunk(right); blue->addChunk(culling); blue->addChunk(dc); endEditCP(blue); MultiPassMaterialPtr mpm = MultiPassMaterial::create(); beginEditCP(mpm); mpm->setTransparencyMode(Material::TransparencyForceTransparent); mpm->addMaterial(blue); mpm->addMaterial(red); endEditCP(mpm);Please note that the red part still has some issues because there is not triangle level depth sorting. I've attached to modified code.
If you swap red and blue in mpm, the z-buffer test isn't turned off at all.
that's ok, we only want depth writes to be off for transparent objects. Cheers, Carsten
// OpenSG Tutorial Example: Hello World // // Minimalistic OpenSG program // // This is the shortest useful OpenSG program // (if you remove all the comments ;) // // It shows how to use OpenSG together with GLUT to create a little // interactive scene viewer. // // GLUT is used for window handling #include <OpenSG/OSGGLUT.h> // General OpenSG configuration, needed everywhere #include <OpenSG/OSGConfig.h> // Methods to create simple geometry: boxes, spheres, tori etc. #include <OpenSG/OSGSimpleGeometry.h> #include <OpenSG/OSGClipPlaneChunk.h> #include <OpenSG/OSGDepthChunk.h> #include <OpenSG/OSGPolygonChunk.h> #include <OpenSG/OSGMultiPassMaterial.h> #include <OpenSG/OSGSimpleMaterial.h> #include <OpenSG/OSGComponentTransform.h> // The GLUT-OpenSG connection class #include <OpenSG/OSGGLUTWindow.h> // A little helper to simplify scene management and interaction #include <OpenSG/OSGSimpleSceneManager.h> // Activate the OpenSG namespace // This is not strictly necessary, you can also prefix all OpenSG symbols // with OSG::, but that would be a bit tedious for this example OSG_USING_NAMESPACE // The SimpleSceneManager to manage simple applications SimpleSceneManager *mgr; // forward declaration so we can have the interesting stuff upfront int setupGLUT( int *argc, char *argv[] ); // Initialize GLUT & OpenSG and set up the scene int main(int argc, char **argv) { // OSG init osgInit(argc,argv); // GLUT init int winid = setupGLUT(&argc, argv); // the connection between GLUT and OpenSG GLUTWindowPtr gwin= GLUTWindow::create(); gwin->setId(winid); gwin->init(); // create the scene NodePtr torus = makeTorus(.05, .2, 16, 16); //GeometryPtr planeGeo = makePlaneGeo(1,1,1,1); GeometryPtr planeGeo = makeTorusGeo(.05, .2, 16, 16); NodePtr plane = makeNodeFor(planeGeo); ComponentTransformPtr trans = ComponentTransform::create(); beginEditCP(trans); trans->setTranslation(Vec3f(0,0,-0.5)); endEditCP(trans); NodePtr translation = makeNodeFor(trans); beginEditCP(translation); translation->addChild(torus); endEditCP(translation); NodePtr scene = makeCoredNode<Group>(); beginEditCP(scene); scene->addChild(plane); scene->addChild(translation); endEditCP(scene); PolygonChunkPtr culling = PolygonChunk::create(); beginEditCP(culling); culling->setCullFace(GL_BACK); endEditCP(culling); ClipPlaneChunkPtr left = ClipPlaneChunk::create(); beginEditCP(left); left->setEquation(Vec4f(-1,0,0,0)); // left halfspace left->setBeacon(scene); endEditCP(left); ClipPlaneChunkPtr right = ClipPlaneChunk::create(); beginEditCP(right); right->setEquation(Vec4f(1,0,0,0)); // right halfspace right->setBeacon(scene); endEditCP(right); SimpleMaterialPtr red = SimpleMaterial::create(); beginEditCP(red); red->setDiffuse(Color3f(1,0,0)); red->setTransparency(0.5); // some transparency red->addChunk(left); red->addChunk(culling); endEditCP(red); DepthChunkPtr dc = DepthChunk::create(); SimpleMaterialPtr blue = SimpleMaterial::create(); beginEditCP(blue); blue->setDiffuse(Color3f(0,0,1)); blue->setTransparency(0.0); // no transparency blue->addChunk(right); blue->addChunk(culling); blue->addChunk(dc); endEditCP(blue); MultiPassMaterialPtr mpm = MultiPassMaterial::create(); beginEditCP(mpm); mpm->setTransparencyMode(Material::TransparencyForceTransparent); mpm->addMaterial(blue); mpm->addMaterial(red); endEditCP(mpm); beginEditCP(planeGeo); planeGeo->setMaterial(mpm); endEditCP(planeGeo); // create the SimpleSceneManager helper mgr = new 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 // // redraw the window void display(void) { mgr->redraw(); } // 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(); } // react to keys void keyboard(unsigned char k, int x, int y) { switch(k) { case 27: { 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); return winid; }
------------------------------------------------------------------------------ What Every C/C++ and Fortran developer Should Know! Read this article and learn how Intel has extended the reach of its next-generation tools to help Windows* and Linux* C/C++ and Fortran developers boost performance applications - including clusters. http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________ Opensg-users mailing list Opensg-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensg-users