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

Reply via email to