On Thu, 2007-08-30 at 11:29 +0200, [EMAIL PROTECTED] wrote:
> Hi Carsten,
> thanks for the reply! Looking at your code I found that the problem was in
> the line
>
> m_pFBO->setFboOn(false);
oops, that line should not have been in there, it is a leftover from
testing and my attempts to figure out what goes wrong...
> which I hadn't. What this line means?
well, it turns off the usage of FBO's and just emulates the effect by
rendering to the regular framebuffer and copying data to a texture, so
it probably is not what you want.
Anyway, the real fix is not to use the GrabForeground at all (because it
knows nothing of FBOs it can not call glReadBuffer(GL_COLOR_ATTACHMENTx)
to select the right attachment to read back). The FBOViewport should
have the ability to read data back, enabled by m_pFBO->setReadBuffer
(true), but that feature was unimplemented. The attached patch, which
will also go into cvs soon, fixes that. Also attached a new version of
the testing program, note that the GrabForeground is not added to the
FBOViewport and therefore now grabImage.png will be empty while
fboImage.png will show the scene.
Hope it helps,
Carsten
> When I added it the grabforeground started
> working, but shadow maps now have some serious problems.. :)
>
> Thanks for your help,
> Stefano
>
>
> Quoting Carsten Neumann <[EMAIL PROTECTED]>:
>
> > Hi Stefano,
> >
> > On Wed, 2007-08-29 at 17:33 +0200, [EMAIL PROTECTED] wrote:
> > > Hi there!
> > > I'm trying to save the content of an FBO into an image using the
> > > GrabForeground class.. here is the code I use:
> > >
> > > ImagePtr img = Image::create();
> > > beginEditCP(img);
> > > img->setPixelFormat(Image::OSG_RGBA_PF);
> > > endEditCP(img);
> > >
> > > GrabForegroundPtr grabber = GrabForeground::create();
> > > beginEditCP(grabber);
> > > grabber->setImage(img);
> > > grabber->setActive(true);
> > > grabber->setAutoResize(true);
> > > endEditCP(grabber);
> > >
> > > m_pFBO->setBackground(SolidBackground::create());
> > > m_pFBO->setCamera(m_pRenderAgent->getCamera());
> > > m_pFBO->setScene(makeCoredNode<Group>());
> > ^^^^^^^^^^^^^^^^^^
> > I don't have that method in my FBOViewport (there is only setRoot, which
> > probably does the same), but it makes me wonder what version you are
> > using?
> >
> > > m_pFBO->addForeground(grabber);
> > > m_pFBO->render(m_pRenderAgent->getRenderAction());
> >
> > There are two issues here, I believe:
> > 1) You don't add any textures to the FBOViewport, so it does not have
> > any color buffers to render into. I have attached a (crude) test program
> > that basically does what you want, not that it is expected that writing
> > of fboImage fails, but grabImage will contain the image (without
> > lighting though, because the only light is the headlight added by the
> > SimpleSceneManager).
> >
> > 2) Since you do not have a window to which the FBOViewport is attached,
> > you must be careful that there is actually an active OpenGL context for
> > the call to m_pFBO->render(...). That's why the attached program does
> > the actual creation of the screenshot in the display function and not in
> > the keyboard function.
> >
> > Hope it helps,
> > Carsten
> >
> > > // save data
> > > char path[255] = "c:\\temp";
> > > boost::filesystem::path p(path);
> > > p /= ("hithere.png");
> > >
> > > printf("Saving image %s\n", p.string().c_str());
> > > if (!img->write(p.native_file_string().c_str())) {
> > > printf("Error writing screenshot\n");
> > > } else {
> > > printf("Done writing screenshot\n");
> > > }
> > >
> > > img->write() returns me success, an image with the right dimensions gets
> > saved,
> > > but it's full of (0,0,0,0) while I should get a full black image, right?
> > > Is there something wrong? GrabForeground (and glReadPixels) should work
> > > correctly with FBOs as I'm reading on the web... isn't it?
> > >
> > > Thanks a lot,
> > > Stefano Verna
> > >
> > >
> > >
> > > ----------------------------------------------------------------
> > > This message was sent using IMP, the Internet Messaging Program.
> > >
> > > -------------------------------------------------------------------------
> > > This SF.net email is sponsored by: Splunk Inc.
> > > Still grepping through log files to find problems? Stop.
> > > Now Search log events and configuration files using AJAX and a browser.
> > > Download your FREE copy of Splunk now >> http://get.splunk.com/
> > > _______________________________________________
> > > Opensg-users mailing list
> > > [email protected]
> > > https://lists.sourceforge.net/lists/listinfo/opensg-users
> >
>
>
>
>
> ----------------------------------------------------------------
> This message was sent using IMP, the Internet Messaging Program.
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems? Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >> http://get.splunk.com/
> _______________________________________________
> Opensg-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensg-users
? Source/System/Window/testFBOGrabbing.cpp
Index: Source/System/Window/OSGFBOViewport.cpp
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/Window/OSGFBOViewport.cpp,v
retrieving revision 1.10
diff -u -r1.10 OSGFBOViewport.cpp
--- Source/System/Window/OSGFBOViewport.cpp 28 Aug 2007 16:06:59 -0000 1.10
+++ Source/System/Window/OSGFBOViewport.cpp 30 Aug 2007 15:58:38 -0000
@@ -1195,9 +1195,37 @@
}
}
- for (UInt16 fi=0; fi<getForegrounds().size(); fi++)
+ for (UInt16 fi=0; fi < getForegrounds().size(); fi++)
getForegrounds(fi)->draw(action, this);
+ if(getReadBuffer() && !colorTextures.empty())
+ {
+ for (i = 0; i < numBuffers; ++i)
+ {
+ ImagePtr texImg = colorTextures[i]->getImage();
+
+ if((texImg->getWidth () != getStorageWidth ()) ||
+ (texImg->getHeight() != getStorageHeight()) ||
+ (texImg->getData () == NULL ) )
+ {
+ SINFO << "FBOViewport::render: (Re)Allocating image "
+ << "for read-back."
+ << endLog;
+
+ texImg->set(texImg->getPixelFormat(),
+ getStorageWidth(),
+ getStorageHeight() );
+ }
+
+ // select GL_COLORATTACHMENTn and read data into image
+ glReadBuffer(buffers[i]);
+ glReadPixels(0, 0, getStorageWidth(), getStorageHeight(),
+ texImg->getPixelFormat(), texImg->getDataType(),
+ texImg->getData() );
+ glReadBuffer(GL_NONE);
+ }
+ }
+
// deactivate viewport settings
deactivate();
#include <OSGConfig.h>
#include <OSGGLUT.h>
#include <OSGFBOViewport.h>
#include <OSGGrabForeground.h>
#include <OSGGLUTWindow.h>
#include <OSGImage.h>
#include <OSGSimpleGeometry.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSolidBackground.h>
#include <OSGTextureChunk.h>
#include <string>
OSG_USING_NAMESPACE
bool doGrabImage = false;
SimpleSceneManager *mgr;
GLUTWindowPtr gwin;
FBOViewportPtr pFBO;
SolidBackgroundPtr pSB;
NodePtr pScene;
// forward declaration so we can have the interesting stuff upfront
int setupGLUT( int *argc, char *argv[] );
void createScene(void);
int main(int argc, char *argv[])
{
osgInit ( argc, argv);
int winid = setupGLUT(&argc, argv);
createScene();
pFBO = FBOViewport::create();
gwin = GLUTWindow::create();
pSB = SolidBackground::create();
beginEditCP(pSB);
pSB->setColor(Color3f(0.2, 0.2, 0.2));
endEditCP (pSB);
beginEditCP(gwin);
gwin->setId(winid);
gwin->init();
endEditCP (gwin);
// create the SimpleSceneManager helper
mgr = new SimpleSceneManager;
// create the window and initial camera/viewport
mgr->setWindow (gwin );
// tell the manager what to manage
mgr->setRoot (pScene);
mgr->setHeadlight(true );
// show the whole scene
mgr->showAll();
glutPostRedisplay();
// GLUT main loop
glutMainLoop();
return 0;
}
void createScene(void)
{
pScene = makeBox(2,2,2, 1,1,1);
}
void idle(void)
{
//glutPostRedisplay();
}
// redraw the window
void display(void)
{
std::cout << "Rendering frame." << std::endl;
ImagePtr grabImage;
ImagePtr fboImage;
if(doGrabImage)
{
grabImage = Image::create();
beginEditCP(grabImage);
grabImage->setPixelFormat(Image::OSG_RGBA_PF);
endEditCP(grabImage);
GrabForegroundPtr grabber = GrabForeground::create();
beginEditCP(grabber);
grabber->setImage(grabImage);
grabber->setActive(true);
grabber->setAutoResize(true);
endEditCP (grabber);
fboImage = Image::create();
beginEditCP(fboImage);
// fboImage->set(Image::OSG_RGBA_PF, gwin->getWidth(), gwin->getHeight());
fboImage->setPixelFormat(Image::OSG_RGBA_PF);
fboImage->setWidth (gwin->getWidth() );
fboImage->setHeight (gwin->getHeight() );
fboImage->setDimension (2);
endEditCP (fboImage);
TextureChunkPtr fboTex = TextureChunk::create();
beginEditCP(fboTex);
fboTex->setMinFilter(GL_LINEAR);
fboTex->setMagFilter(GL_LINEAR);
fboTex->setTarget(GL_TEXTURE_2D);
fboTex->setInternalFormat(GL_RGBA8);
fboTex->setImage(fboImage);
endEditCP (fboTex);
beginEditCP(pFBO);
pFBO->setSize(0, 0, gwin->getWidth()-1, gwin->getHeight() - 1);
pFBO->setStorageWidth (gwin->getWidth ());
pFBO->setStorageHeight(gwin->getHeight());
pFBO->setBackground(pSB);
pFBO->setCamera(mgr->getCamera());
pFBO->setParent(gwin);
// attach texture as render target
// pFBO->setFboOn(false);
pFBO->getTextures().push_back(fboTex);
// pFBO->addForeground(grabber);
pFBO->setRoot(pScene);
pFBO->setReadBuffer(true);
pFBO->setDirty(true);
endEditCP (pFBO);
pFBO->render(dynamic_cast<RenderAction *>(mgr->getAction()));
}
mgr->redraw();
if(doGrabImage)
{
// save data
std::string imageStr("grabImage.png");
std::cout << "Writing image: " << imageStr << std::endl;
if(!grabImage->write(imageStr.c_str()))
std::cout << "ERROR writing image." << std::endl;
else
std::cout << "Success writing image." << std::endl;
imageStr.assign("fboImage.png");
std::cout << "Writing image: " << imageStr << std::endl;
if(!fboImage->write(imageStr.c_str()))
std::cout << "ERROR writing image." << std::endl;
else
std::cout << "Success writing image." << std::endl;
doGrabImage = false;
}
}
// 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;
case 'r':
{
std::cout << "Scheduling frame render." << std::endl;
glutPostRedisplay();
}
break;
case 's':
{
std::cout << "Scheduling immage grab." << std::endl;
doGrabImage = true;
glutPostRedisplay();
}
break;
}
}
// setup the GLUT library which handles the windows for us
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE);
//Set WindowSize here
glutInitWindowSize(512, 512);
glutInitWindowPosition(0, 0);
int winid = glutCreateWindow("Framebuffer Objects and Grabbing Test");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
return winid;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users