I used 29FBOTextures.cpp and add OpenGL occlusion query around render
method of FBO. I have attached the source code, anyway I quote the
display() function here:
// 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
glBeginQueryARB(GL_SAMPLES_PASSED_ARB, *_query);
::fboVP->render(rAct);
glEndQueryARB(GL_SAMPLES_PASSED_ARB);
//int available = 0;
//do
//{
// glGetQueryObjectivARB( *_query,
GL_QUERY_RESULT_AVAILABLE_ARB, &available );
//} while( !available );
int pixel = 0;
glGetQueryObjectivARB(*_query, GL_QUERY_RESULT_ARB, &pixel);
printf("%d\n", pixel);
// render main scene
::mgr->redraw();
}
I need to get the number of passed fragments. Do you have clue how can I
do? It seems that occlusion query does not work using a FboViewport,
could you help me?
Thank you very much!
// 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>
OSG_USING_NAMESPACE
// globals
SimpleSceneManager *mgr (NULL);
FBOViewportPtr fboVP (NullFC);
TransformPtr fboSceneTrans(NullFC);
NodePtr fboCamBeacon (NullFC);
GeometryPtr flagGeo (NullFC);
// flag parameters
const float flagHeight = 8.0f;
const float flagWidth = 16.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;
//occlusion query stuff
typedef void ( APIENTRY *PFNGLGENQUERIESARBPROC ) ( GLsizei n, GLuint *ids);
typedef void ( APIENTRY *PFNGLDELETEQUERIESARBPROC ) ( GLsizei n, const GLuint
*ids );
typedef GLboolean ( APIENTRY *PFNGLISQUERYARBPROC ) ( GLuint id );
typedef void ( APIENTRY *PFNGLBEGINQUERYARBPROC ) ( GLenum target, GLuint id );
typedef void ( APIENTRY *PFNGLENDQUERYARBPROC ) ( GLenum target );
typedef void ( APIENTRY *PFNGLGETQUERYIVARBPROC ) ( GLenum target, GLenum
pname, GLint *params );
typedef void ( APIENTRY *PFNGLGETQUERYOBJECTIVARBPROC ) ( GLuint id, GLenum
pname, GLint *params );
typedef void ( APIENTRY *PFNGLGETQUERYOBJECTUIVARBPROC ) ( GLuint id, GLenum
pname, GLuint *params );
PFNGLGENQUERIESARBPROC glGenQueriesARB;
PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB;
PFNGLISQUERYARBPROC glIsQueryARBLL;
PFNGLBEGINQUERYARBPROC glBeginQueryARB;
PFNGLENDQUERYARBPROC glEndQueryARB;
PFNGLGETQUERYIVARBPROC glGetQueryivARB;
PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
GLuint _query[1];
// forward declarations
Matrix showAll(NodePtr root, PerspectiveCameraPtr cam);
void animateFlag(Real32 t);
void spinFBOScene(Real32 t);
SimpleTexturedMaterialPtr createWoodMaterial();
NodePtr buildFlag(TextureChunkPtr fboTexture, const int &flagHor, const int
&flagVert);
NodePtr buildFBOScene(int argc, char **argv );
void setupFBO(TextureChunkPtr fboTexture, GLUTWindowPtr gwin, NodePtr fboScene
);
// 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
glBeginQueryARB(GL_SAMPLES_PASSED_ARB, *_query);
::fboVP->render(rAct);
glEndQueryARB(GL_SAMPLES_PASSED_ARB);
//int available = 0;
//do
//{
// glGetQueryObjectivARB( *_query, GL_QUERY_RESULT_AVAILABLE_ARB,
&available );
//} while( !available );
int pixel = 0;
glGetQueryObjectivARB(*_query, GL_QUERY_RESULT_ARB, &pixel);
printf("%d\n", pixel);
// 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);
// 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;
//setup glext
glGenQueriesARB =
(PFNGLGENQUERIESARBPROC)wglGetProcAddress("glGenQueriesARB");
glDeleteQueriesARB =
(PFNGLDELETEQUERIESARBPROC)wglGetProcAddress("glDeleteQueriesARB");
glBeginQueryARB =
(PFNGLBEGINQUERYARBPROC)wglGetProcAddress("glBeginQueryARB");
glEndQueryARB =
(PFNGLENDQUERYARBPROC)wglGetProcAddress("glEndQueryARB");
glGetQueryivARB =
(PFNGLGETQUERYIVARBPROC)wglGetProcAddress("glGetQueryivARB");
glGetQueryObjectivARB =
(PFNGLGETQUERYOBJECTIVARBPROC)wglGetProcAddress("glGetQueryObjectivARB");
glGetQueryObjectuivARB =
(PFNGLGETQUERYOBJECTUIVARBPROC)wglGetProcAddress("glGetQueryObjectuivARB");
glGenQueriesARB(1, _query);
// 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);
// create the main scene
NodePtr mainScene = buildFlag(fboTexture, ::flagGeoHor, ::flagGeoVert);
// create the fbo scene
NodePtr fboScene = buildFBOScene(argc, argv);
// create and setup the FBO
setupFBO(fboTexture, 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, 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);
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);
beginEditCP(::flagGeo);
::flagGeo->setMaterial(fboMaterial);
endEditCP(::flagGeo);
// 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));
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, 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);
// 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->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);
}
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users