Hi,

On Mon, 2005-10-10 at 23:42 +0800, Gerrit Voss wrote:
> I'll try to look at the original problem which was rendering to a float
> texture with fbos. I know that it works in principal (we do it without
> OpenSG on nvidia  hardware). So there might be only some parameter
> tweaking needed.

ok, I played with the parameters a little bit and got something
working,  attached a small test program that just dumps some float
values into a texture and reads them back.

Due to older hardware I had to use the nvidia float texture / texture
rect extensions but I give it a try later on and see how to get it
running with the arb floating point texture extension.

The program should just print 10.0 11.0 12.0 13.0 (the values from
the fragment shader). If you use the mouse (right mouse button) you
might see 22 23 24 1 which is the background color.

regards,
  gerrit


#include <OSGConfig.h>

#include <iostream>

#include <OSGGLUT.h>

#include <OSGFieldContainerFactory.h>
#include <OSGSFSysTypes.h>
#include <OSGVector.h>
#include <OSGQuaternion.h>
#include <OSGMatrix.h>
#include <OSGMatrixUtility.h>
#include <OSGBoxVolume.h>
#include <OSGNode.h>
#include <OSGGroup.h>
#include <OSGThread.h>
#include <OSGTransform.h>
#include <OSGAttachment.h>
#include <OSGMFVecTypes.h>
#include <OSGAction.h>
#include <OSGDrawAction.h>
#include <OSGRenderAction.h>
#include <OSGSimpleGeometry.h>
#include <OSGSceneFileHandler.h>
#include <OSGMaterialGroup.h>
#include <OSGSimpleMaterial.h>

#include <OSGDirectionalLight.h>

#include "OSGViewport.h"
#include "OSGCamera.h"
#include "OSGWindow.h"
#include "OSGGLUTWindow.h"
#include "OSGCamera.h"
#include "OSGPerspectiveCamera.h"
#include "OSGSolidBackground.h"
#include "OSGSHLChunk.h"
#include "OSGFBOViewport.h"
#include "OSGTextureChunk.h"
#include "OSGImage.h"

//#include "OSGUniformBackground.h"

#define FBO

#include "OSGTrackball.h"

using namespace OSG;

DrawAction   *ract;
RenderAction *renact;

NodePtr  root;

NodePtr  file;

PerspectiveCameraPtr cam;
#ifdef FBO
FBOViewportPtr vp;
#else 
ViewportPtr vp;
#endif
WindowPtr win;

TransformPtr cam_trans;
TransformPtr scene_trans;

Trackball tball;

bool move_obj = false;

int mouseb = 0;
int lastx=0, lasty=0;

Quaternion oldq;
Vec3f      oldv;

void 
display(void)
{
    Matrix m1, m2, m3;
    Quaternion q1;

    tball.getRotation().getValue(m3);

    q1.setValue(m3);

    m1.setRotate(q1);
    
    m2.setTranslate( tball.getPosition() );
    
    m1.mult( m2 );

    cam_trans->getSFMatrix()->setValue( m1 );

    win->render(renact);

    float szReadback [512 * 512 * 4];

    vp->bind(win.getCPtr());
    glReadBuffer(0x8CE0); //COLOR_ATT_0

    glReadPixels(0, //GLint x,
                 0, //GLint y,
                 10,
                 1,
                 GL_RGBA, //GLenum format,
                 GL_FLOAT, //GLenum type,
                 szReadback); //GLvoid *pixels )

    for(int i = 0; i < 10; ++i)
    {
        fprintf(stderr, "%f %f %f %f\n", 
                szReadback[i * 4],
                szReadback[i * 4 + 1],
                szReadback[i * 4 + 2],
                szReadback[i * 4 + 3]);
    }
}

void reshape( int w, int h )
{
    std::cerr << "Reshape: " << w << "," << h << std::endl;
    win->resize( w, h );
}


void
animate(void)
{
    glutPostRedisplay();
}

// tballall stuff


void
motion(int x, int y)
{   
    Real32 w = win->getWidth(), h = win->getHeight();
    

    Real32  a = -2. * ( lastx / w - .5 ),
                b = -2. * ( .5 - lasty / h ),
                c = -2. * ( x / w - .5 ),
                d = -2. * ( .5 - y / h );

    if ( mouseb & ( 1 << GLUT_LEFT_BUTTON ) )
    {
        tball.updateRotation( a, b, c, d );     
    }
    else if ( mouseb & ( 1 << GLUT_MIDDLE_BUTTON ) )
    {
        tball.updatePosition( a, b, c, d );     
    }
    else if ( mouseb & ( 1 << GLUT_RIGHT_BUTTON ) )
    {
        tball.updatePositionNeg( a, b, c, d );  
    }
    lastx = x;
    lasty = y;
}

void
mouse(int button, int state, int x, int y)
{
    if ( state == 0 )
    {
        switch ( button )
        {
        case GLUT_LEFT_BUTTON:  break;
        case GLUT_MIDDLE_BUTTON:tball.setAutoPosition(true);
                                break;
        case GLUT_RIGHT_BUTTON:     tball.setAutoPositionNeg(true);
                                break;
        }
        mouseb |= 1 << button;
    }
    else if ( state == 1 )
    {
        switch ( button )
        {
        case GLUT_LEFT_BUTTON:  break;
        case GLUT_MIDDLE_BUTTON:tball.setAutoPosition(false);
                                break;
        case GLUT_RIGHT_BUTTON:     tball.setAutoPositionNeg(false);
                                break;
        }       
        mouseb &= ~(1 << button);
    }
    lastx = x;
    lasty = y;
}

void
vis(int visible)
{
    if (visible == GLUT_VISIBLE) 
    {
        glutIdleFunc(animate);
    } 
    else 
    {
        glutIdleFunc(NULL);
    }
}

void key(unsigned char key, int x, int y)
{
    switch ( key )
    {
        case 27:    osgExit(); exit(0);
        case 'a':   glDisable( GL_LIGHTING );
            std::cerr << "Lighting disabled." << std::endl;
            break;
        case 's':   glEnable( GL_LIGHTING );
            std::cerr << "Lighting enabled." << std::endl;
            break;
        case 'z':   glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
            std::cerr << "PolygonMode: Point." << std::endl;
            break;
        case 'x':   glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
            std::cerr << "PolygonMode: Line." << std::endl;
            break;
        case 'c':   glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
            std::cerr << "PolygonMode: Fill." << std::endl;
            break;
        case 'r':   
        {
            std::cerr << "Sending ray through " << x << "," << y << std::endl;
            Line l;
            cam->calcViewRay( l, x, y, *vp );
            std::cerr << "From " << l.getPosition() << ", dir " 
                      << l.getDirection()
                      << std::endl;
        }
        break;

        case ' ':
        {
            Matrix     m;
            Quaternion q;
            Vec3f      v;

            q = oldq;
            v = oldv;

            oldq = tball.getRotation();
            oldv = tball.getPosition();

            move_obj = ! move_obj;
            if ( move_obj )
            {
                puts("moving object");
//                m = scene_trans->getSFMatrix()->getValue();
                tball.setMode( OSG::Trackball::OSGCamera );

            }
            else
            {
                puts("moving camera");
//                m = cam_trans->getSFMatrix()->getValue();
                tball.setMode( OSG::Trackball::OSGObject );
            }
            
//            q.setValue(m);
            tball.setStartPosition( v, true );
            tball.setStartRotation( q, true );

//            std::cout << q << std::endl;
//            std::cout << v << std::endl;

//            std::cout << " " << m[3][0] << " " << m[3][1] << " " << m[3][2] << std::endl;
            
        }
        break;
    }
}


// vertex shader program for bump mapping in surface local coordinates
static std::string _vp_program =
"void main(void)\n"
"{\n"
"    gl_Position = ftransform();\n"
"    gl_TexCoord[0]  = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
"}\n";

// fragment shader program for bump mapping in surface local coordinates
static std::string _fp_program =
"uniform sampler2DRect tex0;\n"
"void main (void)\n"
"{\n"
"    gl_FragColor = vec4(10.0, 11.0, 12.0, 13.0);\n"
"}\n";

int main (int argc, char **argv)
{
    osgInit(argc,argv);

    // GLUT init

    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_ALPHA);
    int winid = glutCreateWindow("OpenSG");
    glutKeyboardFunc(key);
    glutVisibilityFunc(vis);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);       
    glutMouseFunc(mouse);   
    glutMotionFunc(motion); 
    
    glutIdleFunc(display);  

    // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    
    glEnable( GL_DEPTH_TEST );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );

    // OSG

    SceneFileHandler::the().print();

    // create the graph

    // beacon for camera and light  
    NodePtr b1n = Node::create();
    GroupPtr b1 = Group::create();
    beginEditCP(b1n);
    b1n->setCore( b1 );
    endEditCP(b1n);

    // transformation
    NodePtr t1n = Node::create();
    TransformPtr t1 = Transform::create();
    beginEditCP(t1n);
    t1n->setCore( t1 );
    t1n->addChild( b1n );
    endEditCP(t1n);

    cam_trans = t1;

    // light
    
    NodePtr dlight = Node::create();
    DirectionalLightPtr dl = DirectionalLight::create();

    beginEditCP(dlight);
    dlight->setCore( dl );
    endEditCP(dlight);
    
    beginEditCP(dl);
    dl->setAmbient( .3, .3, .3, 1 );
    dl->setDiffuse( 1, 1, 1, 1 );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);
    endEditCP(dl);

    // root
    root = Node::create();
    GroupPtr gr1 = Group::create();
    beginEditCP(root);
    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );
    endEditCP(root);

    // Load the file

    NodePtr file = NullFC;
    NodePtr file1 = NullFC;

    file1 = makePlane( 2, 2, 1, 1 );
    
    file1->updateVolume();

//    file->dump();

//    subRefCP(file);

//    return 0;


    Vec3f min,max;
    file1->getVolume().getBounds( min, max );
    
    std::cout << "Volume: from " << min << " to " << max << std::endl;


    file = Node::create();
    MaterialGroupPtr testMat = MaterialGroup::create();

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


    SimpleMaterialPtr defaultMaterial = SimpleMaterial::create();

    beginEditCP(defaultMaterial);
    defaultMaterial->setDiffuse(Color3f(1,.0,.0));
    defaultMaterial->setAmbient(Color3f(0.1,0.1,0.1));
    defaultMaterial->setSpecular(Color3f(1,1,1));
    defaultMaterial->setShininess(20);
    defaultMaterial->addChunk(shl);
    endEditCP  (defaultMaterial);


    testMat->setMaterial(defaultMaterial);

    beginEditCP(file);
    {
        file->setCore(testMat);
        file->addChild(file1);
    }
    endEditCP  (file);

    beginEditCP(dlight);
    dlight->addChild(file);
    endEditCP(dlight);

    std::cerr << "Tree: " << std::endl;
//  root->dump();

    // Camera
    
    cam = PerspectiveCamera::create();
    cam->setBeacon( b1n );
    cam->setFov( deg2rad( 90 ) );
    cam->setNear( 0.1 );
    cam->setFar( 100000 );

    // Background
    SolidBackgroundPtr bkgnd = SolidBackground::create();
    beginEditCP(bkgnd, SolidBackground::ColorFieldMask);
    bkgnd->setColor(Color3f(22,23,24));
    endEditCP(bkgnd, SolidBackground::ColorFieldMask);

    UInt16 imageWinWidth = 256;
    UInt16 imageWinHeight = 256;

    int size = imageWinWidth * imageWinHeight * 256;
    UChar8 *imgdata = NULL; //new UChar8[size];
    
    ImagePtr plane_img = Image::create();

    beginEditCP(plane_img);
    plane_img->set(Image::OSG_RGBA_PF, 
                   imageWinWidth, 
                   imageWinHeight, 
                   1, 1, 1, 0, imgdata);
    endEditCP(plane_img);

    TextureChunkPtr plane_tex = TextureChunk::create();

    beginEditCP(plane_tex);
        plane_tex->setImage(plane_img);
        plane_tex->setEnvMode(GL_REPLACE);
        plane_tex->setMinFilter(GL_NEAREST);
        plane_tex->setMagFilter(GL_NEAREST);
        plane_tex->setWrapS(GL_CLAMP);
        plane_tex->setWrapT(GL_CLAMP);
        plane_tex->setTarget(GL_TEXTURE_RECTANGLE_NV);
        plane_tex->setInternalFormat(GL_FLOAT_RGBA32_NV);
    endEditCP(plane_tex);
    
#ifdef FBO
    vp = FBOViewport::create();
#else
    vp = Viewport::create();
#endif

    // Viewport
    beginEditCP(vp);
        vp->setCamera( cam );
        vp->setBackground( bkgnd );
        vp->setRoot( root );
        vp->setSize( 0,0, 1,1 );
#ifdef FBO
        vp->setStorageWidth(imageWinWidth);
        vp->setStorageHeight(imageWinHeight);
        vp->getTextures().push_back(plane_tex);
#endif
    endEditCP(vp);

    // Window
    std::cout << "GLUT winid: " << winid << std::endl;

    GLUTWindowPtr gwin;

    GLint glvp[4];
    glGetIntegerv( GL_VIEWPORT, glvp );

    gwin = GLUTWindow::create();
    gwin->setId(winid);
    gwin->setSize( glvp[2], glvp[3] );

    win = gwin;

    win->addPort( vp );

    win->init();

    // Action
    
    ract = DrawAction::create();
    renact = RenderAction::create();

    // tball

    Vec3f pos;
    pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
                  min[1] + ((max[1] - min[1]) * 0.5), 
                  0.5 + max[2] + ( max[2] - min[2] ) * 1.5 );
    
    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
                  min[1] + (max[1] - min[1]) / 2,
                  min[2] + (max[2] - min[2]) / 2);

    tball.setMode( Trackball::OSGObject );
    tball.setStartPosition( pos, true );
    tball.setSum( true );
    tball.setTranslationMode( Trackball::OSGFree );
    tball.setTranslationScale(scale);
    tball.setRotationCenter(tCenter);

    // run...
    
    glutMainLoop();
    
    return 0;
}

Reply via email to