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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users