Hi,

I'd like to render my scene into a FBO, as
output I'd like to have the color buffer and the
depth buffer into two separated textures. As far
as I understand FBO's that should work. And as
far as I could see from the OpenSG code, it should
work in OpenSG as well ;) So I tried to extend the
29FBOTexture.cpp sample.... 

I created a texture that can hold the depth info
like this:

        TextureChunkPtr fboDepthTexture = TextureChunk::create();
        [...]
    // setup depth texture
    ImagePtr imgDepth = Image::create();
    beginEditCP(imgDepth);
        imgDepth->set(GL_DEPTH_COMPONENT_ARB, ::fboWidth, ::fboHeight);
    endEditCP(imgDepth);
    beginEditCP(fboDepthTexture);
        fboDepthTexture->setMinFilter(GL_LINEAR);
        fboDepthTexture->setMagFilter(GL_LINEAR);
        fboDepthTexture->setTarget(GL_TEXTURE_2D);
        fboDepthTexture->setInternalFormat(GL_DEPTH_COMPONENT_ARB);
        fboDepthTexture->setExternalFormat(GL_DEPTH_COMPONENT_ARB);
        fboDepthTexture->setImage(imgDepth);
    endEditCP(fboDepthTexture);

then I attached the texture to the fbo:

[...]
        ::fboVP->getTextures().push_back(fboTexture);
        ::fboVP->getTextures().push_back(fboDepthTexture);
[...]

I add a plane, apply the depth texture and this shader:

static std::string _fp_program =
"uniform sampler2D tex0;\n"
"\n"
"void main(void)\n"
"{\n"
"       vec4 texture = texture2D(tex0, gl_TexCoord[0].xy);\n"
" float depth = texture2D(tex0, gl_TexCoord[0].xy).r;\n"
" if ( depth == 1.0 )\n"
"               gl_FragColor = vec4(1,0,0,1);\n"
"  else \n"
"     gl_FragColor = vec4(0,1,0,1);\n"
"}\n";


All I get is a uniform red surface :( I'd expected at least
some green fragments as the depth buffer should be != 1.0
at some points.


The log suggests me that
everything is fine ("INFO:  8cd5: framebuffer complete!")
but the resulting depth texture has only value 1.0
(so it seems!). 


Any suggestions?

I attached the complete code...


Regards,

  Toni

--
Ing. Antonio Bleile
Seac02 S.r.l.
via Avogadro 4
10121 Torino Italia
Tel. +39.011.197.006.52
Fax +39.011.197.006.53
E-mail [EMAIL PROTECTED]
Sito www.seac02.it

Questa E-mail è rivolta unicamente alle persone o enti ai quali è
indirizzata. Essa può contenere informazioni la cui riservatezza è tutelata.
Sono vietati la riproduzione e qualsiasi uso di questa e-mail e/o delle
informazioni in essa contenute in mancanza di autorizzazione del
destinatario. 
This e-mail is intended only for the person or entity to which is addressed.
It may contain information that is privileged, proprietary, confidential,
attorney work product or otherwise exempted from disclosure under applicable
law. Copying, dissemination or use of this e-mail or the information herein
by anyone other than the intended recipient is prohibited. 
// OpenSG FBO example: 29FBOTexture.cpp
//
// Shows how to use the FBOViewport for render-to-texture
//

#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGGLUTWindow.h>
#include <OpenSG/OSGGradientBackground.h>
#include <OpenSG/OSGSceneFileHandler.h>
#include <OpenSG/OSGSimpleGeometry.h>
#include <OpenSG/OSGImage.h>
#include <OpenSG/OSGTextureChunk.h>
#include <OpenSG/OSGFBOViewport.h>
#include <OpenSG/OSGSimpleTexturedMaterial.h>
#include <OpenSG/OSGMatrixUtility.h>
#include <OpenSG/OSGPointLight.h>
#include <OpenSG/OSGQuaternion.h>
#include <OpenSG/OSGGeoFunctions.h>
#include <OpenSG/OSGImageFunctions.h>
#include <OpenSG/OSGTwoSidedLightingChunk.h>
#include <OpenSG/OSGComponentTransform.h>
#include <OpenSG/OSGImageFileType.h>
#include <OpenSG/OSGTextureTransformChunk.h>
#include <OpenSG/OSGSHLChunk.h>
#include <OpenSG/OSGLog.h>
OSG_USING_NAMESPACE

#define GL_DEPTH_COMPONENT16_ARB          0x81A5
#define GL_DEPTH_COMPONENT24_ARB          0x81A6
#define GL_DEPTH_COMPONENT32_ARB          0x81A7
#define GL_TEXTURE_DEPTH_SIZE_ARB         0x884A
#define GL_DEPTH_TEXTURE_MODE_ARB         0x884B
#ifndef GL_DEPTH_COMPONENT_ARB
#   define GL_DEPTH_COMPONENT_ARB            0x1902
#endif
// globals
SimpleSceneManager *mgr          (NULL);
FBOViewportPtr      fboVP        (NullFC);
TransformPtr        fboSceneTrans(NullFC);
NodePtr             fboCamBeacon (NullFC);
GeometryPtr         flagGeo      (NullFC);
GeometryPtr         flagGeoDepth (NullFC);

// flag parameters
const float flagHeight   = 16.0f;
const float flagWidth    = 32.0f;
const int   flagGeoHor   = (int)flagWidth  * 3;
const int   flagGeoVert  = (int)flagHeight / 2;
const float flagWaveDamp = 0.06f;

const float poleHeight   = 24.0f;
const float poleDia      = poleHeight * 0.01f;

// fbo size
const int   fboWidth     = (int)flagWidth  * 32;
const int   fboHeight    = (int)flagHeight * 32;

// forward declarations
Matrix showAll(NodePtr root, PerspectiveCameraPtr cam);
void animateFlag(Real32 t);
void spinFBOScene(Real32 t);
SimpleTexturedMaterialPtr createWoodMaterial();
NodePtr buildFlag(TextureChunkPtr fboTexture, TextureChunkPtr fboDepthTexture, 
const int &flagHor, const int &flagVert);
NodePtr buildFBOScene(int argc, char **argv );
void setupFBO(TextureChunkPtr fboTexture, TextureChunkPtr fboDepthTexture, 
GLUTWindowPtr gwin, NodePtr fboScene );
          




static std::string _fp_program =
"uniform sampler2D tex0;\n"
"\n"
"void main(void)\n"
"{\n"
"       vec4 texture = texture2D(tex0, gl_TexCoord[0].xy);\n"
" float depth = texture2D(tex0, gl_TexCoord[0].xy).r;\n"
" if ( depth == 1.0 )\n"
"               gl_FragColor = vec4(1,0,0,1);\n"
"  else \n"
"     gl_FragColor = vec4(0,1,0,1);\n"
"}\n";


// redraw the window
void display(void)
{
    // get the current time
    Real32 t = OSG::getTimeStampMsecs(OSG::getTimeStamp()) * 0.001f;

        // animate flag
    animateFlag(t);

        // spin the fbo scene
    spinFBOScene(t);

        // get the RenderAction from SimpleSceneManager
        RenderAction *rAct = static_cast<RenderAction*>(::mgr->getAction());

    // render fbo scene
        ::fboVP->render(rAct);

        // render main scene
        ::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, int)
{
    switch(k)
    {
    case 27:    exit(1);
    default:    break;
    }
}


int main(int argc, char **argv)
{
        // OpenSG init
    osgInit(argc,argv);
        OSG::osgLog().setLogLevel(OSG::LOG_DEBUG);
        OSG::osgLog().setLogFile( "osglog.txt" );
    // GLUT init
    glutInit(&argc, argv);
    glutInitWindowSize(800,600);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

    int winid = glutCreateWindow("OpenSG " OSG_VERSION_STRING " FBO example");

    // register GLUT callbacks
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);


        // create a GLUTWindow
    GLUTWindowPtr gwin = GLUTWindow::create();
        beginEditCP(gwin);
                gwin->setId(winid);
                gwin->init();
        endEditCP(gwin);

        // create the SimpleSceneManager helper
        ::mgr = new SimpleSceneManager;
        
        // create the texture that is used as render target by the sub-scene
        // and as texture in the main scene
        TextureChunkPtr fboTexture = TextureChunk::create();
        beginEditCP(fboTexture);
            fboTexture->setEnvMode(GL_MODULATE);
        endEditCP(fboTexture);
        
    TextureChunkPtr fboDepthTexture = TextureChunk::create();
        beginEditCP(fboDepthTexture);
            fboDepthTexture->setEnvMode(GL_MODULATE);
        endEditCP(fboDepthTexture);


        // create the main scene
    NodePtr mainScene = buildFlag(fboTexture, fboDepthTexture, ::flagGeoHor, 
::flagGeoVert);

    // create the fbo scene
    NodePtr fboScene  = buildFBOScene(argc, argv);
    
    // create and setup the FBO
    setupFBO(fboTexture, fboDepthTexture, gwin, fboScene);
        
    // create the window and initial camera/viewport
        ::mgr->setWindow(gwin);

        // tell the manager what to manage
        ::mgr->setRoot(mainScene);

        // show the whole scene
        ::mgr->showAll();

        // set a nicer background
        GradientBackgroundPtr bkg = GradientBackground::create();
        beginEditCP(bkg);
                bkg->addLine(Color3f(0.7, 0.7, 0.8), 0);
                bkg->addLine(Color3f(0.0, 0.1, 0.3), 1);
        endEditCP(bkg);
        gwin->getPort(0)->setBackground(bkg);
        
    // enable logo
    mgr->useOpenSGLogo();
    
    // make sure the window is setup before rendering to the FBO
    mgr->redraw();

    // enter the GLUT main loop
        glutMainLoop();

        return 0;
}

// copied from SimpleSceneManager
Matrix showAll(NodePtr root, PerspectiveCameraPtr cam)
{
    root->updateVolume();

    Vec3f min,max;
    root->getVolume().getBounds( min, max );
    Vec3f d = max - min;

    if(d.length() < Eps) // Nothing loaded? Use a unity box
    {
        min.setValues(-1.f,-1.f,-1.f);
        max.setValues( 1.f, 1.f, 1.f);
        d = max - min;
    }

    Real32 dist = osgMax(d[0],d[1]) / (2 * osgtan(cam->getFov() / 2.f));

    Vec3f up(0,1,0);
    Pnt3f at((min[0] + max[0]) * .5f,(min[1] + max[1]) * .5f,(min[2] + max[2]) 
* .5f);
    Pnt3f from = at;
    from[2]+=(dist+fabs(max[2]-min[2])*0.5f);

    // set the camera to go from 1% of the object to twice its size
    Real32 diag = osgMax(osgMax(d[0], d[1]), d[2]);
    beginEditCP(cam);
        cam->setFar  (10 * diag);
    endEditCP(cam);

    Matrix m;
    MatrixLookAt(m, from, at, up);

    return m;
}

void animateFlag( Real32 t )
{
    // get positions
    GeoPositions3fPtr pos = GeoPositions3fPtr::dcast(::flagGeo->getPositions());
    beginEditCP(pos, GeoPositions3f::GeoPropDataFieldMask);
        Pnt3f offset(-0.5f * flagWidth, 3, 0);
        float t2 = 8.0f * t;
        for(UInt32 i = 0; i < pos->getSize(); ++i)
        {
            Pnt3f p = pos->getValue(i);
            float v = p.dist(offset);
            // the flag geometry is centered at the origin
            // we need to offset the wave calculations
            float x = p[0] - offset.x();
            // make a wave, dampened towards the poleS
            p[2]  = x * flagWaveDamp * osgsin(v-t2);
            pos->setValue(p, i);
        }
    endEditCP(pos, GeoPositions3f::GeoPropDataFieldMask);   
   
    // correct normals
    calcVertexNormals(::flagGeo);
}

void spinFBOScene( Real32 t )
{
    beginEditCP(::fboSceneTrans, Transform::MatrixFieldMask);
        Matrix m;
        Quaternion q;
        q.setValueAsAxisDeg(0, 1, 0, t * 16.66f);
        m.setRotate(q);
        ::fboSceneTrans->setMatrix(m);
    endEditCP(::fboSceneTrans, Transform::MatrixFieldMask);
}


// create a wood texture
SimpleTexturedMaterialPtr createWoodMaterial()
{
    SimpleTexturedMaterialPtr mat = SimpleTexturedMaterial::create();
    beginEditCP(mat);
        ImagePtr img = Image::create();
        createNoise(img, Image::OSG_L_PF, 7, 64);
        mat->setImage(img);
        mat->setEnvMode(GL_MODULATE);
        mat->setDiffuse(Color3f(0.9f, 0.57f, 0.1f));
        mat->setSpecular(Color3f(0.2f, 0.2f, 0.1f));
        TextureTransformChunkPtr ttrans = TextureTransformChunk::create();
        beginEditCP(ttrans);
            Matrix m;
            m.setScale(2.0, 8.0, 2.0);
            ttrans->setMatrix(m);
        endEditCP(ttrans);
        mat->addChunk(ttrans);
    endEditCP(mat);

    return mat;
}

NodePtr buildFlag(TextureChunkPtr fboTexture, TextureChunkPtr fboDepthTexture, 
const int &flagHor, const int &flagVert)
{
    NodePtr flagScene = makeCoredNode<Group>();
    
    ::flagGeo = makePlaneGeo(flagWidth, flagHeight, flagHor, flagVert);
    
    // disable caching as we will change this geometry every frame
    beginEditCP(::flagGeo);
        ::flagGeo->setVbo(false);
        ::flagGeo->setDlistCache(false);
    endEditCP(::flagGeo);

    ::flagGeoDepth = makePlaneGeo(flagWidth, flagHeight, flagHor, flagVert);
    
    // disable caching as we will change this geometry every frame
    beginEditCP(::flagGeoDepth);
        ::flagGeoDepth->setVbo(false);
        ::flagGeoDepth->setDlistCache(false);
    endEditCP(::flagGeoDepth);

    SimpleMaterialPtr fboMaterial = SimpleMaterial::create();
    beginEditCP(fboMaterial);
        fboMaterial->addChunk(fboTexture);
        
        // add a light glossy effect (environment noise-map)
        {
            ImagePtr noise = Image::create();
            createNoise(noise, Image::OSG_I_PF, 5, 256);
            beginEditCP(noise);
                // make noise image darker (as it will be GL_ADDed)
                for(int i = 0; i < noise->getSize(); ++i)
                  noise->getData()[i] >>= 2; // *= 0.125
            endEditCP(noise);
            TextureChunkPtr gloss = TextureChunk::create();
            beginEditCP(gloss);
                gloss->setImage(noise);
                gloss->setEnvMode(GL_ADD);
            endEditCP(gloss);
            TexGenChunkPtr envMap = TexGenChunk::create();
            beginEditCP(envMap);
                envMap->setGenFuncS(GL_SPHERE_MAP);
                envMap->setGenFuncT(GL_SPHERE_MAP);
            endEditCP(envMap);
            // add for use with 2nd texture unit
            fboMaterial->addChunk(gloss, 1);
            fboMaterial->addChunk(envMap, 1);
        }
 
        fboMaterial->addChunk(TwoSidedLightingChunk::create());
        fboMaterial->setSpecular(Color3f(0.7f, 0.7f, 0.7f));
        fboMaterial->setDiffuse(Color3f(0.22f, 0.2f, 0.2f));
    endEditCP(fboMaterial);


    SHLChunkPtr depthShader = SHLChunk::create();
    beginEditCP(depthShader);
        //_shl->setVertexProgram(_vp_program);
        depthShader->setFragmentProgram(_fp_program);
        
  
    endEditCP(depthShader);

        addRefCP( depthShader );


    SimpleMaterialPtr fboDepthMaterial = SimpleMaterial::create();
    beginEditCP(fboDepthMaterial);
        fboDepthMaterial->addChunk(fboDepthTexture, 0);
        fboDepthMaterial->addChunk(depthShader);
    endEditCP(fboDepthMaterial);

    beginEditCP(::flagGeo);
        ::flagGeo->setMaterial(fboMaterial);
    endEditCP(::flagGeo);

    beginEditCP(::flagGeoDepth);
        ::flagGeoDepth->setMaterial(fboDepthMaterial);
    endEditCP(::flagGeoDepth);

    // create transform node to hook up the flag to the pole
    ComponentTransformPtr flagTrans;
    NodePtr flag = makeCoredNode<ComponentTransform>(&flagTrans);
    beginEditCP(flagTrans);
        Vec3f v(0.5f * flagWidth, 0.5f * (poleHeight - flagHeight) , 0.0f);
        flagTrans->setTranslation(v);
    endEditCP(flagTrans);

    // attach flag-geometry to transform-node
    beginEditCP(flag);
        flag->addChild(makeNodeFor(::flagGeo));
        flag->addChild(makeNodeFor(::flagGeoDepth));
    endEditCP(flag);

    // build flag pole
    NodePtr pole = makeCylinder(poleHeight, poleDia, 24, true, true, true);
    MaterialPtr woodMat = createWoodMaterial();
    GeometryPtr cyl = GeometryPtr::dcast(pole->getCore());
    beginEditCP(cyl);
        cyl->setMaterial(woodMat);
    endEditCP(cyl);

    // attach objects to group node
    beginEditCP(flagScene);
        flagScene->addChild(flag);
        flagScene->addChild(pole);
    endEditCP(flagScene);

    return flagScene;
}

NodePtr buildFBOScene( int argc, char ** argv )
{
    PointLightPtr light;
    NodePtr fboRoot = makeCoredNode<PointLight>(&light);
    ::fboCamBeacon = makeNodeFor(Transform::create());

    // attach camera beacon to root node
    beginEditCP(fboRoot);
        fboRoot->addChild(::fboCamBeacon);
    endEditCP(fboRoot);

    // set camera beacon as light beacon (-> headlight)
    beginEditCP(light);
        light->setBeacon(::fboCamBeacon);
        light->setOn(true);
    endEditCP(light);

    // load given model, the cow, or make a torus
    NodePtr scene;
    if(argc >= 2)
        scene = SceneFileHandler::the().read(argv[1]);
    else
        scene = SceneFileHandler::the().read("Data/cow.obj.gz");

    // fallback if loading failed
    if(!scene)
        scene = makeTorus(0.3, 4, 16, 64);

    NodePtr fboScene = makeCoredNode<Transform>(&::fboSceneTrans);
    beginEditCP(fboScene);
    beginEditCP(fboRoot);
        fboScene->addChild(scene);
        fboRoot->addChild(fboScene);
    endEditCP(fboRoot);
    endEditCP(fboScene);

    return fboRoot;
}

void setupFBO( TextureChunkPtr fboTexture, TextureChunkPtr fboDepthTexture, 
GLUTWindowPtr gwin, NodePtr fboScene )
{
    // setup FBO
    ImagePtr img = Image::create();
    beginEditCP(img);
        img->set(Image::OSG_RGBA_PF, ::fboWidth, ::fboHeight);
    endEditCP(img);
    beginEditCP(fboTexture);
        fboTexture->setMinFilter(GL_LINEAR);
        fboTexture->setMagFilter(GL_LINEAR);
        fboTexture->setTarget(GL_TEXTURE_2D);
        fboTexture->setInternalFormat(GL_RGBA8);
        fboTexture->setImage(img);
    endEditCP(fboTexture);

    // setup depth texture
    ImagePtr imgDepth = Image::create();
    beginEditCP(imgDepth);
        imgDepth->set(GL_DEPTH_COMPONENT_ARB, ::fboWidth, ::fboHeight);
    endEditCP(imgDepth);
    beginEditCP(fboDepthTexture);
        fboDepthTexture->setMinFilter(GL_LINEAR);
        fboDepthTexture->setMagFilter(GL_LINEAR);
        fboDepthTexture->setTarget(GL_TEXTURE_2D);
        fboDepthTexture->setInternalFormat(GL_DEPTH_COMPONENT_ARB);
        fboDepthTexture->setExternalFormat(GL_DEPTH_COMPONENT_ARB);
        fboDepthTexture->setImage(imgDepth);
    endEditCP(fboDepthTexture);

    // add background
    GradientBackgroundPtr bg = GradientBackground::create();
    beginEditCP(bg);
        // flag of neutral-moresnet
        bg->addLine(Color3f(0.0, 0.0, 0.8), 0.000);
        bg->addLine(Color3f(0.0, 0.0, 0.8), 0.333);

        bg->addLine(Color3f(0.8, 0.8, 0.8), 0.333);
        bg->addLine(Color3f(0.8, 0.8, 0.8), 0.666);

        bg->addLine(Color3f(0.0, 0.0, 0.0), 0.666);
        bg->addLine(Color3f(0.0, 0.0, 0.0), 1.000);
    endEditCP(bg);


    // setup camera
    PerspectiveCameraPtr fboCam = PerspectiveCamera::create();
    beginEditCP(fboCam);
        // we already compensated aspect ratio with the texture/fbo sizes
        fboCam->setAspect(1.0);
        fboCam->setFov(osgdegree2rad(60));
        fboCam->setNear(0.01);
        fboCam->setFar(100);
        fboCam->setBeacon(::fboCamBeacon);
    endEditCP(fboCam);

    // create FBOViewport
    ::fboVP = FBOViewport::create();
    beginEditCP(::fboVP);
        ::fboVP->setSize(0, 0, ::fboWidth - 1, ::fboHeight - 1);
        ::fboVP->setStorageWidth(::fboWidth);
        ::fboVP->setStorageHeight(::fboHeight);
        ::fboVP->setBackground(bg);
        ::fboVP->setCamera(fboCam);
        ::fboVP->setParent(gwin);
        // attach texture as render target
        ::fboVP->getTextures().push_back(fboTexture);
        ::fboVP->getTextures().push_back(fboDepthTexture);
        ::fboVP->setRoot(fboScene);
    endEditCP(::fboVP);

    // set the fbo camera to show the whole model
    TransformPtr trans = TransformPtr::dcast(::fboCamBeacon->getCore());
    beginEditCP(trans, Transform::MatrixFieldMask);
        trans->setMatrix(showAll(fboScene, fboCam));
    endEditCP(trans, Transform::MatrixFieldMask);
}
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to