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;
}