Hello Johannes,
On 09/20/2010 03:12 AM, Johannes Brunen wrote:
"Carsten Neumann"<carsten_neum...@gmx.net> schrieb im
Newsbeitrag news:4c96896a.2040...@gmx.net...
there is a colBuf->setReadBack(true) missing, you already enable post
processing on the fbo, but not the actual read back of the color buffer.
I think that this statement is not missing. See in line 260:
fbo->getColorAttachments(0)->setReadBack(true);
yes, sorry I'm blind, for some reason I was only looking for a line that
started with colBuf...
Running the program I get warnings:
WARNING: Viewport::render: no background!
these can be fixed by adding:
stage_viewport->setBackground(vp0->getBackground());
stage_viewport->setCamera (vp0->getCamera());
I'm turning the warnings into FATAL messages, because a missing camera,
background or root node will prevent rendering the viewport.
Fixing that, I get an OpenGL error about the FBO being incomplete, the
reason being that the color attachment is created without specifying a
valid internal format (RenderBuffer does not try to take the value from
the image if it is present and its own internal format field is GL_NONE
- I'm preparing a patch for that).
For now, adding:
colBuf->setInternalFormat(GL_RGBA);
does the trick.
Finally I've moved the line:
win->addPort(stage_viewport);
After the loop over all viewports, because it seemed like you only want
to iterate over previously existing viewports.
With those changes (modified file is attached) the image is not all
black any more, however there is something wrong with the tiling (I get
9 copies of the torus instead of one big one) and it is unlit (because
the light source is part of the internal nodes the SSM places on top of
the user provided scene and therefore is not included when rendering
only the user provided scene into the FBO).
Cheers,
Carsten
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <sstream>
#include <fstream>
// #include <gl/glew.h>
#include <vector>
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGGrabForeground.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSceneFileHandler.h>
#include <OSGAction.h>
#include <OSGFrameBufferObject.h>
#include <OSGRenderBuffer.h>
#include <OSGSimpleStage.h>
#include <OSGPassiveViewport.h>
#include <OSGTileCameraDecorator.h>
#include <OSGTileableBackground.h>
#include <OSGVisitSubTree.h>
using namespace OSG;
static void cleanup(void);
static void display(void);
static void reshape(int w, int h);
static void mouse(int button, int state, int x, int y);
static void motion(int x, int y);
static void keyboard(unsigned char k, int, int);
static void writeHiResScreenShot(const char* name, UInt32 width, UInt32 height);
static void writeHiResScreenShotFBO(const char* name, UInt32 width, UInt32 height);
static bool writePNMImagesHeader(const std::vector<ImageUnrecPtr>& vecImages, UInt32 width, UInt32 height, std::ostream& out);
static bool writePNMImagesData(const std::vector<ImageUnrecPtr>& vecImages, std::ostream& out);
static int setupGLUT(int *argc, char *argv[]);
static int doMain(int argc, char *argv[]);
SimpleSceneManager* mgr;
NodeRefPtr scene;
GLUTWindowRefPtr win;
const char* output_file = "test_normal_grab.png";
const char* output_file_fbo = "test_fbo_grab.png";
int fw = 4;
int fh = 3;
static void cleanup(void)
{
delete mgr;
mgr = NULL;
scene = NULL;
}
static void display(void)
{
commitChanges();
mgr->redraw();
}
static void reshape(int w, int h)
{
mgr->resize(w,h);
glutPostRedisplay();
}
static void mouse(int button, int state, int x, int y)
{
if (state)
mgr->mouseButtonRelease(button, x, y);
else
mgr->mouseButtonPress(button, x, y);
glutPostRedisplay();
}
static void motion(int x, int y)
{
mgr->mouseMove(x, y);
glutPostRedisplay();
}
static void keyboard(unsigned char k, int, int)
{
switch(k)
{
case '1':
{
UInt32 winWidth = win->getWidth();
UInt32 winHeight = win->getHeight();
UInt32 width = fw * winWidth;
UInt32 height = fh * winHeight;
writeHiResScreenShot(output_file, width, height);
}
break;
case '2':
{
UInt32 winWidth = win->getWidth();
UInt32 winHeight = win->getHeight();
UInt32 width = fw * winWidth;
UInt32 height = fh * winHeight;
writeHiResScreenShotFBO(output_file_fbo, width, height);
}
break;
}
glutPostRedisplay();
}
static void writeHiResScreenShot(
const char* name,
UInt32 width,
UInt32 height)
{
UInt32 winWidth = win->getWidth();
UInt32 winHeight = win->getHeight();
if (width < winWidth ) width = winWidth;
if (height < winHeight) height = winHeight;
Real32 a = Real32(winWidth) / Real32(winHeight);
width = UInt32(a*height);
std::ofstream stream(name, std::ios::binary);
if (stream.good() == false)
return;
ImageUnrecPtr grab_image = Image::create();
GrabForegroundUnrecPtr grabber = GrabForeground::create();
grabber->setImage(grab_image);
grabber->setActive(true);
grabber->setAutoResize(false);
size_t num_ports = win->getMFPort()->size();
std::vector<TileCameraDecoratorUnrecPtr> decorators;
decorators.resize(num_ports);
for (size_t i = 0; i < num_ports; ++i) {
Viewport* vp = win->getPort(i);
TileCameraDecoratorUnrecPtr decorator = TileCameraDecorator::create();
decorator->setFullSize(width, height);
decorator->setDecoratee(vp->getCamera());
decorators[i] = decorator;
vp->setCamera(decorator);
TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground());
if (tbg)
tbg->setTile(false);
}
Viewport* vp1 = win->getPort(0);
vp1->addForeground(grabber);
bool write_header = true;
Int32 yPosLast = 0;
for (; yPosLast < height-winHeight; yPosLast += winHeight);
for (Int32 yPos = yPosLast; yPos >= 0; yPos -= winHeight)
{
UInt32 ySize = std::min(winHeight, height - yPos);
std::vector<ImageUnrecPtr> vecColImages;
for (UInt32 xPos = 0; xPos < width; xPos += winWidth)
{
UInt32 xSize = std::min(winWidth, width - xPos);
ImageUnrecPtr col_image = Image::create();
col_image->set(Image::OSG_RGBA_PF, xSize, ySize);
for (size_t i = 0; i < num_ports; ++i) {
Viewport* vp = win->getPort(i);
vp->setSize(0, 0, xSize, ySize);
TileCameraDecorator* decorator = decorators[i];
decorator->setSize( xPos / float(width),
yPos / float(height),
(xPos + xSize) / float(width),
(yPos + ySize) / float(height) );
grab_image->set(Image::OSG_RGBA_PF, xSize, ySize);
}
mgr->redraw();
col_image->setSubData(0, 0, 0, xSize, ySize, 1, grabber->getImage()->getData());
vecColImages.push_back(col_image);
}
if (write_header)
if (!writePNMImagesHeader(vecColImages, width, height, stream)) break;
if (!writePNMImagesData(vecColImages, stream)) break;
vecColImages.clear();
write_header = false;
}
//
// restore window
//
for (size_t i = 0; i < num_ports; ++i) {
Viewport* vp = win->getPort(i);
vp->setCamera(decorators[i]->getDecoratee());
vp->setSize(0, 0, 1, 1);
}
vp1->removeObjFromForegrounds(grabber);
}
static void writeHiResScreenShotFBO(const char* name, UInt32 width, UInt32 height)
{
UInt32 winWidth = win->getWidth();
UInt32 winHeight = win->getHeight();
if (width < winWidth ) width = winWidth;
if (height < winHeight) height = winHeight;
Real32 a = Real32(winWidth) / Real32(winHeight);
width = UInt32(a*height);
std::ofstream stream(name, std::ios::binary);
if (stream.good() == false)
return;
FrameBufferObjectUnrecPtr fbo = FrameBufferObject::create();
RenderBufferUnrecPtr colBuf = RenderBuffer::create();
RenderBufferUnrecPtr dsBuf = RenderBuffer::create();
ImageUnrecPtr buffer_image = Image::create();
buffer_image->set(Image::OSG_RGBA_PF, winWidth, winHeight);
colBuf->setImage(buffer_image);
colBuf->setInternalFormat(GL_RGBA);
dsBuf ->setInternalFormat(GL_DEPTH24_STENCIL8);
fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
fbo->setColorAttachment(colBuf, 0);
fbo->setDepthAttachment(dsBuf);
fbo->setStencilAttachment(dsBuf);
fbo->setWidth (winWidth );
fbo->setHeight(winHeight);
fbo->setPostProcessOnDeactivate(true);
fbo->getColorAttachments(0)->setReadBack(true);
VisitSubTreeUnrecPtr visitor = VisitSubTree::create();
NodeUnrecPtr visit_node = makeNodeFor(visitor);
visitor->setSubTreeRoot(mgr->getRoot());
Viewport* vp0 = win->getPort(0);
SimpleStageUnrecPtr stage = SimpleStage::create();
stage->setCamera(vp0->getCamera());
stage->setBackground(vp0->getBackground());
stage->setRenderTarget(fbo);
NodeUnrecPtr stage_node = makeNodeFor(stage);
stage_node->addChild(visit_node);
NodeUnrecPtr root = makeCoredNode<Group>();
root->addChild(stage_node);
ViewportUnrecPtr stage_viewport = PassiveViewport::create();
stage_viewport->setRoot(root);
stage_viewport->setBackground(vp0->getBackground());
stage_viewport->setCamera (vp0->getCamera());
size_t num_ports = win->getMFPort()->size();
std::vector<TileCameraDecoratorUnrecPtr> decorators;
decorators.resize(num_ports);
for (size_t i = 0; i < num_ports; ++i) {
Viewport* vp = win->getPort(i);
TileCameraDecoratorUnrecPtr decorator = TileCameraDecorator::create();
decorator->setFullSize(width, height);
decorator->setDecoratee(vp->getCamera());
decorators[i] = decorator;
vp->setCamera(decorator);
TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground());
if (tbg)
tbg->setTile(false);
}
win->addPort(stage_viewport);
bool write_header = true;
Int32 yPosLast = 0;
for (; yPosLast < height-winHeight; yPosLast += winHeight);
for (Int32 yPos = yPosLast; yPos >= 0; yPos -= winHeight)
{
UInt32 ySize = std::min(winHeight, height - yPos);
std::vector<ImageUnrecPtr> vecColImages;
for (UInt32 xPos = 0; xPos < width; xPos += winWidth)
{
UInt32 xSize = std::min(winWidth, width - xPos);
ImageUnrecPtr col_image = Image::create();
col_image->set(Image::OSG_RGBA_PF, xSize, ySize);
for (size_t i = 0; i < num_ports; ++i) {
Viewport* vp = win->getPort(i);
vp->setSize(0, 0, xSize, ySize);
TileCameraDecorator* decorator = decorators[i];
decorator->setSize( xPos / float(width),
yPos / float(height),
(xPos + xSize) / float(width),
(yPos + ySize) / float(height) );
}
mgr->redraw();
if (fbo) {
RenderBuffer* grabber = dynamic_cast<RenderBuffer*>(fbo->getColorAttachments(0));
if (grabber)
col_image->setSubData(0, 0, 0, xSize, ySize, 1, grabber->getImage()->getData());
}
vecColImages.push_back(col_image);
}
if (write_header)
if (!writePNMImagesHeader(vecColImages, width, height, stream)) break;
if (!writePNMImagesData(vecColImages, stream)) break;
vecColImages.clear();
write_header = false;
}
//
// restore window
//
for (size_t i = 0; i < num_ports; ++i) {
Viewport* vp = win->getPort(i);
vp->setCamera(decorators[i]->getDecoratee());
vp->setSize(0, 0, 1, 1);
}
win->subPortByObj(stage_viewport);
}
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE);
int winid = glutCreateWindow("OpenSG");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
return winid;
}
static int doMain(int argc, char *argv[])
{
preloadSharedObject("OSGFileIO");
preloadSharedObject("OSGImageFileIO");
preloadSharedObject("OSGContribPLY");
osgInit(argc,argv);
int winid = setupGLUT(&argc, argv);
win = GLUTWindow::create();
win->setGlutId(winid);
win->init();
if(argc < 2)
{
FWARNING(("No file given!\n"));
FWARNING(("Supported file formats:\n"));
std::list<const char*> suffixes;
SceneFileHandler::the()->getSuffixList(suffixes);
for(std::list<const char*>::iterator it = suffixes.begin();
it != suffixes.end();
++it)
{
FWARNING(("%s\n", *it));
}
scene = makeTorus(.5, 2, 16, 16);
}
else
{
scene = SceneFileHandler::the()->read(argv[1]);
}
commitChanges();
mgr = new SimpleSceneManager;
mgr->setWindow(win);
mgr->setRoot (scene);
mgr->showAll();
return 0;
}
int main(int argc, char *argv[])
{
int ret = doMain(argc, argv);
glutMainLoop();
cleanup();
osgExit();
return ret;
}
static bool writePNMImagesHeader(
const std::vector<ImageUnrecPtr>& vecImages,
UInt32 width, UInt32 height,
std::ostream &out)
{
if (vecImages.empty()) return false;
ImageUnrecPtr col_image = vecImages[0];
UInt16 bpp = col_image->getBpp();
switch(bpp)
{
case 1:
case 2:
return false;
case 3:
case 4:
out << "P6" << std::endl;
break;
}
out << "# PNMImageFileType write" << std::endl;
out << width << " " << height << std::endl;
out << "255" << std::endl;
return true;
}
static bool writePNMImagesData(
const std::vector<ImageUnrecPtr>& vecImages,
std::ostream &out)
{
if (vecImages.empty()) return false;
ImageUnrecPtr first = vecImages[0];
UInt16 bpp = first->getBpp();
Int16 width = first->getWidth();
Int16 height = first->getHeight();
std::size_t num_images = vecImages.size();
for(Int16 y = height - 1; y >= 0; y--)
{
for (std::size_t img_idx = 0; img_idx < num_images; img_idx++)
{
ImageUnrecPtr image = vecImages[img_idx];
width = image->getWidth();
height = image->getHeight();
Int16 lineSize = bpp * width;
const UInt8* data = (image->getData() + (lineSize * y));
for(Int16 x = 0; x < width; x++)
{
for(Int16 p = bpp - 1; p--;)
out << *data++;
data++;
}
}
}
return true;
}
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users