From 460c77b7f0b24a2a0e02ab079a0e700d12d0f328 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 11 May 2005 19:14:36 +0000 Subject: [PATCH] From Nathan Monteleone, rewrote the osgpbuffer example so that it uses Producer xplatform support for pbuffer instead of Win32 specific pathways as support before. (with a few code tweaks to simplfy the code, by Robert Osfield). --- Make/makedirdefs | 1 + .../examples/osgpbuffer/osgpbuffer.dsp | 8 - examples/osgpbuffer/GNUmakefile | 18 + examples/osgpbuffer/GNUmakefile.inst | 13 + examples/osgpbuffer/RenderToTextureStage.cpp | 81 --- examples/osgpbuffer/RenderToTextureStage.h | 62 --- examples/osgpbuffer/osgpbuffer.cpp | 490 ++++-------------- examples/osgpbuffer/pbuffer.cpp | 446 ---------------- examples/osgpbuffer/pbuffer.h | 201 ------- 9 files changed, 138 insertions(+), 1182 deletions(-) create mode 100644 examples/osgpbuffer/GNUmakefile create mode 100644 examples/osgpbuffer/GNUmakefile.inst delete mode 100644 examples/osgpbuffer/RenderToTextureStage.cpp delete mode 100644 examples/osgpbuffer/RenderToTextureStage.h delete mode 100644 examples/osgpbuffer/pbuffer.cpp delete mode 100644 examples/osgpbuffer/pbuffer.h diff --git a/Make/makedirdefs b/Make/makedirdefs index ac0033445..ff40460b3 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -212,6 +212,7 @@ EXAMPLE_DIRS = \ osgpagedlod\ osgparticle\ osgparticleeffects\ + osgpbuffer\ osgpick\ osgplanets\ osgpoints\ diff --git a/VisualStudio/examples/osgpbuffer/osgpbuffer.dsp b/VisualStudio/examples/osgpbuffer/osgpbuffer.dsp index 84e7bfdf1..08521581e 100644 --- a/VisualStudio/examples/osgpbuffer/osgpbuffer.dsp +++ b/VisualStudio/examples/osgpbuffer/osgpbuffer.dsp @@ -105,13 +105,5 @@ SOURCE=..\..\..\examples\osgpbuffer\RenderToTextureStage.h SOURCE=..\..\..\examples\osgpbuffer\osgpbuffer.cpp # End Source File -# Begin Source File - -SOURCE=..\..\..\examples\osgpbuffer\pbuffer.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\examples\osgpbuffer\RenderToTextureStage.cpp -# End Source File # End Target # End Project diff --git a/examples/osgpbuffer/GNUmakefile b/examples/osgpbuffer/GNUmakefile new file mode 100644 index 000000000..99ca3242b --- /dev/null +++ b/examples/osgpbuffer/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgpbuffer.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgpbuffer + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgpbuffer/GNUmakefile.inst b/examples/osgpbuffer/GNUmakefile.inst new file mode 100644 index 000000000..8ec358a68 --- /dev/null +++ b/examples/osgpbuffer/GNUmakefile.inst @@ -0,0 +1,13 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgpbuffer.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgpbuffer + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgpbuffer/RenderToTextureStage.cpp b/examples/osgpbuffer/RenderToTextureStage.cpp deleted file mode 100644 index 573170cdf..000000000 --- a/examples/osgpbuffer/RenderToTextureStage.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -//#include - -#include "RenderToTextureStage.h" - -//using namespace osg; -//using namespace osgUtil; - -// register a RenderToTextureStage prototype with the RenderBin prototype list. -//RegisterRenderBinProxy s_registerRenderToTextureStageProxy; - -MyRenderToTextureStage::MyRenderToTextureStage() -{ - _pbuffer = 0L; - _localState = new osg::State; -} - -MyRenderToTextureStage::~MyRenderToTextureStage() -{ -} - -void MyRenderToTextureStage::reset() -{ - RenderStage::reset(); -} - -void MyRenderToTextureStage::draw(osg::State& state, osgUtil::RenderLeaf*& previous) -{ - if (_pbuffer && _texture.valid()) - { - // Create pbuffer texture - const unsigned int contextID = state.getContextID(); - osg::Texture::TextureObject* textureObject = _texture->getTextureObject(contextID); - if (textureObject == 0) - { - // Create dynamic texture, subload callback required. - _texture->apply(state); - } - - HDC hdc = ::wglGetCurrentDC(); - HGLRC hglrc = ::wglGetCurrentContext(); - - // Release pbuffer from "render to texture". - _pbuffer->releaseTexImage(); - - // Make the p-buffer's context current. - _pbuffer->makeCurrent(); - - // Render in p-buffer. - RenderStage::draw(*_localState,previous); - - // restore window's context as current. - if (!::wglMakeCurrent(hdc, hglrc)) - { - assert(0); - } - - if (true /*_isRenderTextureSupported*/) - { - // transfer contents of p-buffer to texture - _pbuffer->bindTexImage(textureObject->_id); - } - else - { -// TODO: -// _pbuffer->copyTexImage(state); - } - - } - else - { - RenderStage::draw(state,previous); - - // now copy the rendered image to attached texture. - if (_texture.valid()) - _texture->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); - - if (_image.valid()) - _image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),GL_RGBA,GL_UNSIGNED_BYTE); - } -} diff --git a/examples/osgpbuffer/RenderToTextureStage.h b/examples/osgpbuffer/RenderToTextureStage.h deleted file mode 100644 index e9ddfbcb3..000000000 --- a/examples/osgpbuffer/RenderToTextureStage.h +++ /dev/null @@ -1,62 +0,0 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. - -#ifndef RENDERTOTEXTURESTAGE -#define RENDERTOTEXTURESTAGE 1 - -#include -#include - -#include - -#include "pbuffer.h" - -// namespace osgUtil { - -/** - * RenderStage which copies the final image to an attached texture or image. - * Generally used as a pre-rendering stage. - */ -class /*OSGUTIL_EXPORT*/ MyRenderToTextureStage : public osgUtil::RenderStage -{ - public: - - - MyRenderToTextureStage(); - - virtual osg::Object* cloneType() const { return new MyRenderToTextureStage(); } - virtual osg::Object* clone(const osg::CopyOp&) const { return new MyRenderToTextureStage(); } // note only implements a clone of type. - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=0L; } - virtual const char* libraryName() const { return ""; } - virtual const char* className() const { return "MyRenderToTextureStage"; } - - inline void setPBuffer(PBuffer* pbuffer) { _pbuffer = pbuffer; } - - virtual void reset(); - - void setTexture(osg::Texture2D* texture) { _texture = texture; } - osg::Texture2D* getTexture() { return _texture.get(); } - - void setImage(osg::Image* image) { _image = image; } - osg::Image* getImage() { return _image.get(); } - - virtual void draw(osg::State& state,osgUtil::RenderLeaf*& previous); - - public: - - - protected: - - virtual ~MyRenderToTextureStage(); - - osg::ref_ptr _texture; - osg::ref_ptr _image; - osg::ref_ptr _localState; - PBuffer* _pbuffer; -}; - -// } - -#endif - diff --git a/examples/osgpbuffer/osgpbuffer.cpp b/examples/osgpbuffer/osgpbuffer.cpp index ae212d198..c3bab8212 100644 --- a/examples/osgpbuffer/osgpbuffer.cpp +++ b/examples/osgpbuffer/osgpbuffer.cpp @@ -12,180 +12,17 @@ #include #include +#include #include #include #include +#include +#include -#include "RenderToTextureStage.h" -#include "pbuffer.h" - -PBuffer* g_pPixelBuffer; - -class MyUpdateCallback : public osg::NodeCallback -{ - public: - - MyUpdateCallback(osg::Node* subgraph): - _subgraph(subgraph) {} - - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) - { - // traverse the subgraph to update any nodes. - if (_subgraph.valid()) _subgraph->accept(*nv); - - // must traverse the Node's subgraph - traverse(node,nv); - } - - osg::ref_ptr _subgraph; -}; - -class MyCullCallback : public osg::NodeCallback -{ - public: - - MyCullCallback(osg::Node* subgraph,osg::Texture2D* texture): - _subgraph(subgraph), - _texture(texture) - { - } - - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) - { - - osgUtil::CullVisitor* cullVisitor = dynamic_cast(nv); - if (cullVisitor && _texture.valid() && _subgraph.valid()) - doPreRender(*node,*cullVisitor); - - // must traverse the subgraph - traverse(node,nv); - } - - void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv); - - osg::ref_ptr _subgraph; - osg::ref_ptr _texture; - osg::ref_ptr _localState; - -}; - - -void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv) -{ - const osg::BoundingSphere& bs = _subgraph->getBound(); - if (!bs.valid()) - { - osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()< rtts = new MyRenderToTextureStage; - rtts->setPBuffer(g_pPixelBuffer); - - // set up lighting. - // currently ignore lights in the scene graph itself.. - // will do later. - osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); - - // set up the background color and clear mask. - rtts->setClearColor(osg::Vec4(0.1f,0.9f,0.3f,1.0f)); - rtts->setClearMask(previous_stage->getClearMask()); - - // set up to charge the same RenderStageLighting is the parent previous stage. - rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); - - - // record the render bin, to be restored after creation - // of the render to text - osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); - - // set the current renderbin to be the newly created stage. - cv.setCurrentRenderBin(rtts.get()); - - float znear = 1.0f*bs.radius(); - float zfar = 3.0f*bs.radius(); - - // 2:1 aspect ratio as per flag geomtry below. - float top = 0.25f*znear; - float right = 0.5f*znear; - - znear *= 0.9f; - zfar *= 1.1f; - - // set up projection. - osg::RefMatrix* projection = new osg::RefMatrix; - projection->makeFrustum(-right,right,-top,top,znear,zfar); - - cv.pushProjectionMatrix(projection); - - osg::RefMatrix* matrix = new osg::RefMatrix; - matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); - - cv.pushModelViewMatrix(matrix); - - if (!_localState) _localState = new osg::StateSet; - - cv.pushStateSet(_localState.get()); - - { - // traverse the subgraph - _subgraph->accept(cv); - } - - cv.popStateSet(); - - // restore the previous model view matrix. - cv.popModelViewMatrix(); - - // restore the previous model view matrix. - cv.popProjectionMatrix(); - - // restore the previous renderbin. - cv.setCurrentRenderBin(previousRenderBin); - - if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) - { - // getting to this point means that all the subgraph has been - // culled by small feature culling or is beyond LOD ranges. - return; - } - - - - int height = 512; - int width = 512; - - - const osg::Viewport& viewport = *cv.getViewport(); - - // offset the impostor viewport from the center of the main window - // viewport as often the edges of the viewport might be obscured by - // other windows, which can cause image/reading writing problems. - int center_x = viewport.x()+viewport.width()/2; - int center_y = viewport.y()+viewport.height()/2; - - osg::Viewport* new_viewport = new osg::Viewport; -// new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); - new_viewport->setViewport(0,0,width,height); - rtts->setViewport(new_viewport); - - _localState->setAttribute(new_viewport); - - // and the render to texture stage to the current stages - // dependancy list. - cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); - - // if one exist attach texture to the RenderToTextureStage. - if (_texture.valid()) rtts->setTexture(_texture.get()); - - // if one exist attach image to the RenderToTextureStage. -// if (_image.valid()) rtts->setImage(_image.get()); - -} - +osg::ref_ptr gPBufferCamera; +osg::ref_ptr gPBufferSceneHandler; // call back which cretes a deformation field to oscilate the model. class MyGeometryCallback : @@ -278,189 +115,25 @@ class MyTextureSubloadCallback : public osg::Texture2D::SubloadCallback { public: - MyTextureSubloadCallback(): - _subloadMode(AUTO), - _textureWidth(0), - _textureHeight(0), - _subloadTextureOffsetX(0), - _subloadTextureOffsetY(0), - _subloadImageOffsetX(0), - _subloadImageOffsetY(0), - _subloadImageWidth(0), - _subloadImageHeight(0) - { - } + MyTextureSubloadCallback() {} - enum SubloadMode { - OFF, - AUTO, - IF_DIRTY - }; - - /** Set the texture subload mode. */ - inline void setSubloadMode(const SubloadMode mode) { _subloadMode = mode; } - - /** Get the texture subload mode. */ - inline const SubloadMode getSubloadMode() const { return _subloadMode; } - - /** Set the texture subload texture offsets. */ - inline void setSubloadTextureOffset(const int x, const int y) - { - _subloadTextureOffsetX = x; - _subloadTextureOffsetY = y; - } - - /** Get the texture subload texture offsets. */ - inline void getSubloadTextureOffset(int& x, int& y) const - { - x = _subloadTextureOffsetX; - y = _subloadTextureOffsetY; - } - - /** Set the texture subload width. If width or height are zero then - * the repsective size value is calculated from the source image sizes. */ - inline void setSubloadTextureSize(const int width, const int height) - { - _textureWidth = width; - _textureHeight = height; - } - - /** Get the texture subload width. */ - inline void getSubloadTextureSize(int& width, int& height) const - { - width = _textureWidth; - height = _textureHeight; - } - - - /** Set the subload image offsets. */ - inline void setSubloadImageOffset(const int x, const int y) - { - _subloadImageOffsetX = x; - _subloadImageOffsetY = y; - } - - /** Get the subload image offsets. */ - inline void getSubloadImageOffset(int& x, int& y) const - { - x = _subloadImageOffsetX; - y = _subloadImageOffsetY; - } - - /** Set the image subload width. If width or height are zero then - * the repsective size value is calculated from the source image sizes. */ - inline void setSubloadImageSize(const int width, const int height) - { - _subloadImageWidth = width; - _subloadImageHeight = height; - } - - /** Get the image subload width. */ - inline void getSubloadImageSize(int& width, int& height) const - { - width = _subloadImageWidth; - height = _subloadImageHeight; - } - - - virtual void load(const osg::Texture2D& texture,osg::State&) const { osg::notify(osg::INFO)<<"doing load"<0)?_subloadImageWidth:texture.getImage()->s(); - GLsizei height = (_subloadImageHeight>0)?_subloadImageHeight:texture.getImage()->t(); - - - bool sizeChanged = false; - if (_textureWidth==0) - { - // need to calculate texture dimension - sizeChanged = true; - _textureWidth = 1; - for (; _textureWidth < (static_cast(_subloadTextureOffsetX) + width); _textureWidth <<= 1) {} - } - - if (_textureHeight==0) - { - // need to calculate texture dimension - sizeChanged = true; - _textureHeight = 1; - for (; _textureHeight < (static_cast(_subloadTextureOffsetY) + height); _textureHeight <<= 1) {} - } - - if (sizeChanged) - { - texture.setTextureSize(_textureWidth, _textureHeight); - } -*/ -#if 0 - // reserve appropriate texture memory - glTexImage2D(GL_TEXTURE_2D, 0, texture.getInternalFormat(), - _textureWidth, _textureHeight, 0, - (GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(), - NULL); - - - glPixelStorei(GL_UNPACK_ROW_LENGTH,texture.getImage()->s()); - - - glTexSubImage2D(GL_TEXTURE_2D, 0, - _subloadTextureOffsetX, _subloadTextureOffsetY, - width, height, - (GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(), - texture.getImage()->data(_subloadImageOffsetX,_subloadImageOffsetY)); - - glPixelStorei(GL_UNPACK_ROW_LENGTH,0); -#else - glTexImage2D( GL_TEXTURE_2D, 0, texture.getInternalFormat(), _textureWidth, _textureHeight, 0, GL_RGB, GL_FLOAT, 0 ); -#endif + glTexImage2D( GL_TEXTURE_2D, 0, texture.getInternalFormat(), texture.getTextureWidth(), texture.getTextureHeight(), 0, GL_RGB, GL_FLOAT, 0 ); } - virtual void subload(const osg::Texture2D& texture,osg::State&) const + virtual void subload(const osg::Texture2D& ,osg::State&) const { osg::notify(osg::INFO)<<"doing subload"<s()); - - glTexSubImage2D(GL_TEXTURE_2D, 0, - _subloadTextureOffsetX, _subloadTextureOffsetY, - (_subloadImageWidth>0)?_subloadImageWidth:texture.getImage()->s(), (_subloadImageHeight>0)?_subloadImageHeight:texture.getImage()->t(), - (GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(), - texture.getImage()->data(_subloadImageOffsetX,_subloadImageOffsetY)); - - glPixelStorei(GL_UNPACK_ROW_LENGTH,0); -#else -#endif + gPBufferCamera->getRenderSurface()->bindPBufferToTexture(Producer::RenderSurface::FrontBuffer); } - - - SubloadMode _subloadMode; - mutable GLsizei _textureWidth, _textureHeight; - GLint _subloadTextureOffsetX, _subloadTextureOffsetY; - GLint _subloadImageOffsetX, _subloadImageOffsetY; - GLsizei _subloadImageWidth, _subloadImageHeight; }; -osg::Node* createPreRenderSubGraph(osg::Node* subgraph) +osg::Node* createTexturedFlag(unsigned int width, unsigned int height) { - if (!subgraph) return 0; - // create the quad to visualize. osg::Geometry* polyGeom = new osg::Geometry(); @@ -470,14 +143,14 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph) osg::Vec3 xAxis(1.0f,0.0f,0.0f); osg::Vec3 yAxis(0.0f,0.0f,1.0f); osg::Vec3 zAxis(0.0f,-1.0f,0.0f); - float height = 100.0f; - float width = 200.0f; + float flag_height = 100.0f; + float flag_width = 200.0f; int noSteps = 20; osg::Vec3Array* vertices = new osg::Vec3Array; osg::Vec3 bottom = origin; - osg::Vec3 top = origin; top.z()+= height; - osg::Vec3 dv = xAxis*(width/((float)(noSteps-1))); + osg::Vec3 top = origin; top.z()+= flag_height; + osg::Vec3 dv = xAxis*(flag_width/((float)(noSteps-1))); osg::Vec2Array* texcoords = new osg::Vec2Array; osg::Vec2 bottom_texcoord(0.0f,0.0f); @@ -514,70 +187,100 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph) // StateSet to contain the Texture StateAttribute. osg::StateSet* stateset = new osg::StateSet; - // set up the texture. -// osg::Image* image = new osg::Image; -// image->setInternalTextureFormat(GL_RGBA); - // Dynamic texture filled with data from pbuffer. osg::Texture2D* texture = new osg::Texture2D; //texture->setSubloadMode(osg::Texture::IF_DIRTY); texture->setInternalFormat(GL_RGB); - texture->setTextureSize(512,512); + texture->setTextureSize(width,height); texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); -texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP); -texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP); + texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP); + texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP); texture->setSubloadCallback(new MyTextureSubloadCallback()); - stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); + stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); polyGeom->setStateSet(stateset); - polyGeom->setUpdateCallback(new MyGeometryCallback(origin,xAxis,yAxis,zAxis,1.0,1.0/width,0.2f)); + polyGeom->setUpdateCallback(new MyGeometryCallback(origin,xAxis,yAxis,zAxis,1.0,1.0/flag_width,0.2f)); osg::Geode* geode = new osg::Geode(); geode->addDrawable(polyGeom); osg::Group* parent = new osg::Group; - - parent->setUpdateCallback(new MyUpdateCallback(subgraph)); - - parent->setCullCallback(new MyCullCallback(subgraph,texture)); - parent->addChild(geode); - + return parent; } -class InitializePbufferCallback : public osgProducer::OsgCameraGroup::RealizeCallback +void InitPBufferCamera(osg::Node* subgraph, unsigned int width, unsigned int height) { - public: - InitializePbufferCallback() {} - - virtual void operator()( osgProducer::OsgCameraGroup&, osgProducer::OsgSceneHandler& sh, const Producer::RenderSurface& ) - { - if (!g_pPixelBuffer) - { - g_pPixelBuffer = new PBuffer(512,512); - g_pPixelBuffer->initialize(); - } + if (!subgraph) return; - // now safe to continue - sh.init(); - } + gPBufferCamera = new Producer::Camera; + gPBufferCamera->getRenderSurface()->setDrawableType( Producer::RenderSurface::DrawableType_PBuffer ); + gPBufferCamera->getRenderSurface()->setWindowRectangle( 0, 0, width, height ); + gPBufferCamera->getRenderSurface()->setRenderToTextureMode(Producer::RenderSurface::RenderToRGBTexture); + + gPBufferSceneHandler = new osgProducer::OsgSceneHandler; + gPBufferSceneHandler->getSceneView()->setDefaults(); + gPBufferSceneHandler->getSceneView()->setSceneData(subgraph); + + gPBufferCamera->setSceneHandler( gPBufferSceneHandler.get()); + + gPBufferCamera->setClearColor( 0.1f,0.9f,0.3f,1.0f ); + + const osg::BoundingSphere& bs = subgraph->getBound(); + if (!bs.valid()) + { + osg::notify(osg::WARN) << "bb invalid"<setViewByLookat( + eye.x(), eye.y(), eye.z(), + bs.center().x(), bs.center().y(), bs.center().z(), + 0.0f, 0.0f, 1.0f); + + + gPBufferCamera->setLensFrustum(-right,right,-top,top,znear,zfar); + + // The Producer PBuffer example says: + // + // "This line is not necessary on glX pbuffer examples, but Windows + // seems to not like rendering to the back buffer on pbuffers" + // + // but I've found that doing this causes a flickering texture. Everything + // works fine for me (on Windows) if I just comment it out. + + //gPBufferSceneHandler->getSceneView()->setDrawBufferValue( GL_FRONT ); +} int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); - + + osg::DisplaySettings::instance()->readCommandLine(arguments); + // set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use pbuffers and render to texture.."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--width ","Set the width of the pbuffer & texture"); + arguments.getApplicationUsage()->addCommandLineOption("--height ","Set the height of the pbuffer & texture"); - // construct the viewer. osgProducer::Viewer viewer(arguments); @@ -586,6 +289,12 @@ int main( int argc, char **argv ) // get details on keyboard and mouse bindings used by the viewer. viewer.getUsage(*arguments.getApplicationUsage()); + + unsigned int width=1024; + unsigned int height=512; + + while (arguments.read("--width",width)) {} + while (arguments.read("--height",height)) {} // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) @@ -609,9 +318,9 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); return 1; } - + // load the nodes from the commandline arguments. - osg::Node* loadedModel = osgDB::readNodeFiles(arguments); + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); if (!loadedModel) @@ -619,28 +328,36 @@ int main( int argc, char **argv ) // write_usage(osg::notify(osg::NOTICE),argv[0]); return 1; } - + // create a transform to spin the model. osg::MatrixTransform* loadedModelTransform = new osg::MatrixTransform; - loadedModelTransform->addChild(loadedModel); + loadedModelTransform->addChild(loadedModel.get()); osg::NodeCallback* nc = new osgUtil::TransformCallback(loadedModelTransform->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0f)); loadedModelTransform->setUpdateCallback(nc); osg::Group* rootNode = new osg::Group(); -// rootNode->addChild(loadedModelTransform); - rootNode->addChild(createPreRenderSubGraph(loadedModelTransform)); + // Create a waving rectangle that will use the pbuffer as a texture. + rootNode->addChild(createTexturedFlag(width,height)); + + // Set up a camera that will render a view of the model to the pbuffer. + InitPBufferCamera(loadedModelTransform,width, height); // set the scene to render viewer.setSceneData(rootNode); - // use a realize callback to create and initialize the PBuffer to ensure it has a valid graphics context. - viewer.setRealizeCallback(new InitializePbufferCallback()); // create the windows and run the threads. viewer.realize(); +#if defined(GLX_VERSION_1_1) + // This determins where Pixel reads occur from. The main Camera will + // set the pBuffer camera's rendersurface as the buffer to read from. + Producer::Camera* camera = viewer.getCamera(0); + camera->getRenderSurface()->setReadDrawable( gPBufferCamera->getRenderSurface()); +#endif + while( !viewer.done() ) { // wait for all cull and draw threads to complete. @@ -648,17 +365,22 @@ int main( int argc, char **argv ) // update the scene by traversing it with the the update visitor which will // call all node update callbacks and animations. + loadedModelTransform->accept(*viewer.getUpdateVisitor()); viewer.update(); - + // fire off the cull and draw traversals of the scene. + // first the pbuffer draw + gPBufferCamera->frame(); + + // then the main view draw. viewer.frame(); - } // wait for all cull and draw threads to complete before exit. viewer.sync(); - delete g_pPixelBuffer; + gPBufferCamera = 0; + gPBufferSceneHandler = 0; return 0; } diff --git a/examples/osgpbuffer/pbuffer.cpp b/examples/osgpbuffer/pbuffer.cpp deleted file mode 100644 index fc2a5ddee..000000000 --- a/examples/osgpbuffer/pbuffer.cpp +++ /dev/null @@ -1,446 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "pbuffer.h" - -namespace osg { - bool isWGLExtensionSupported(const char *extension); -} - - -// WGL_ARB_pbuffer -static WGLCreatePBufferProc wglCreatePBuffer; -static WGLGetPBufferDCProc wglGetPBufferDC; -static WGLReleasePBufferDCProc wglReleasePBufferDC; -static WGLDestroyPBufferProc wglDestroyPBuffer; -static WGLQueryPBufferProc wglQueryPBuffer; - -// WGL_ARB_pixel_format -static WGLGetPixelFormatAttribivProc wglGetPixelFormatAttribiv; -static WGLGetPixelFormatAttribfvProc wglGetPixelFormatAttribfv; -static WGLChoosePixelFormatProc wglChoosePixelFormat; - -// WGL_ARB_render_texture -static WGLBindTexImageProc wglBindTexImage; -static WGLReleaseTexImageProc wglReleaseTexImage; -static WGLSetPbufferAttribProc wglSetPbufferAttrib; - - -#ifdef _WIN32 - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -typedef const char * (WINAPI * WGLGetExtensionsStringProc) (HDC hDC); -#endif - -#endif - -#ifdef _WIN32 -bool osg::isWGLExtensionSupported(const char *extension) -{ - - typedef std::set ExtensionSet; - static ExtensionSet s_extensionSet; - static const char* s_extensions = NULL; - static WGLGetExtensionsStringProc wglGetExtensionsString = (WGLGetExtensionsStringProc)osg::getGLExtensionFuncPtr("wglGetExtensionsStringARB"); - if (wglGetExtensionsString == NULL) return false; - if (s_extensions==NULL) - { - // get the extension list from OpenGL. - s_extensions = (const char*)wglGetExtensionsString(::wglGetCurrentDC()); - if (s_extensions==NULL) return false; - - // insert the ' ' delimiated extensions words into the extensionSet. - const char *startOfWord = s_extensions; - const char *endOfWord; - while ((endOfWord = strchr(startOfWord,' '))!=NULL) - { - s_extensionSet.insert(std::string(startOfWord,endOfWord)); - startOfWord = endOfWord+1; - } - if (*startOfWord!=0) s_extensionSet.insert(std::string(startOfWord)); - - osg::notify(osg::INFO)<<"OpenGL extensions supported by installed OpenGL drivers are:"<~PBuffer(); - initialize(); - } -} - - -// This function actually does the creation of the p-buffer. -// It can only be called once a window has already been created. -void PBuffer::initialize() -{ - setupGLExtenions(); - - HDC hdc = wglGetCurrentDC(); - HGLRC hglrc = wglGetCurrentContext(); - - // Query for a suitable pixel format based on the specified mode. - std::vector iattributes; - std::vector fattributes; - - // P-buffer will be used with OpenGL - iattributes.push_back(WGL_SUPPORT_OPENGL_ARB); - iattributes.push_back(true); - - // Since we are trying to create a pbuffer, the pixel format we - // request (and subsequently use) must be "p-buffer capable". - iattributes.push_back(WGL_DRAW_TO_PBUFFER_ARB); - iattributes.push_back(true); - - // Bind to texture - iattributes.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB); - iattributes.push_back(true); - -//iattributes.push_back(WGL_ACCELERATION_ARB); -//iattributes.push_back(WGL_FULL_ACCELERATION_ARB); - - if (_RGB) - { - iattributes.push_back(WGL_PIXEL_TYPE_ARB); - iattributes.push_back(WGL_TYPE_RGBA_ARB); - - // We require a minimum of 8-bits for each R, G, B, and A. - iattributes.push_back(WGL_RED_BITS_ARB); - iattributes.push_back(8); - iattributes.push_back(WGL_GREEN_BITS_ARB); - iattributes.push_back(8); - iattributes.push_back(WGL_BLUE_BITS_ARB); - iattributes.push_back(8); - if (_minimumNumberAlphaBits > 0) - { - iattributes.push_back(WGL_ALPHA_BITS_ARB); - iattributes.push_back(_minimumNumberAlphaBits); - } - } - else - { - iattributes.push_back(WGL_PIXEL_TYPE_ARB); - iattributes.push_back(WGL_TYPE_COLORINDEX_ARB); - } - - iattributes.push_back(WGL_DOUBLE_BUFFER_ARB); - iattributes.push_back(_doubleBuffer); - - if (_minimumNumberDepthBits > 0) - { - iattributes.push_back(WGL_DEPTH_BITS_ARB); - iattributes.push_back(_minimumNumberDepthBits); - } - - if (_minimumNumberStencilBits > 0) - { - iattributes.push_back(WGL_STENCIL_BITS_ARB); - iattributes.push_back(_minimumNumberStencilBits); - } - - if (_minimumNumberAccumulationBits > 0) - { - iattributes.push_back(WGL_ACCUM_BITS_ARB); - iattributes.push_back(_minimumNumberAccumulationBits); - } - - // Terminate array - iattributes.push_back(0); - - - // Now obtain a list of pixel formats that meet these minimum requirements. - int format; - int pformat[MAX_PFORMATS]; - unsigned int nformats=0; - if ( !wglChoosePixelFormat( hdc, &iattributes.front(), &fattributes.front(), MAX_PFORMATS, pformat, &nformats ) ) - { - osg::notify(osg::FATAL)<< "pbuffer creation error: Couldn't find a suitable pixel format." < pbattr; - - // Texture format - pbattr.push_back(WGL_TEXTURE_FORMAT_ARB); - pbattr.push_back(WGL_TEXTURE_RGBA_ARB); -#if 1 - // Texture target - pbattr.push_back(WGL_TEXTURE_TARGET_ARB); - pbattr.push_back(WGL_TEXTURE_2D_ARB); -#else - // Cubemap - pbattr.push_back(WGL_TEXTURE_TARGET_ARB); - pbattr.push_back(WGL_TEXTURE_CUBE_MAP_ARB); - - // Cubemap face - pbattr.push_back(WGL_CUBE_MAP_FACE_ARB); - pbattr.push_back(WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB); -#endif - // Terminate array - pbattr.push_back(0); - - iattributes[0] = 0; - _hPBuffer = wglCreatePBuffer( hdc, format, _width, _height, &pbattr.front() ); - if ( !_hPBuffer ) - { - DWORD err = GetLastError(); - osg::notify(osg::FATAL)<< "pbuffer creation error: wglCreatePBufferARB() failed\n" < -#include "GL/gl.h" -#include -#include "GL/wglext.h" -#include -*/ - -#include - -#if defined(WIN32) - #define WIN32_LEAN_AND_MEAN - #include -#endif - - -#ifndef WGL_ARB_pbuffer -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif - - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 - -DECLARE_HANDLE(HPBUFFERARB); - -typedef HPBUFFERARB (WINAPI * WGLCreatePBufferProc) ( - HDC hDC, - int iPixelFormat, - int iWidth, - int iHeight, - const int *piAttribList); -typedef HDC (WINAPI * WGLGetPBufferDCProc) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * WGLReleasePBufferDCProc) ( - HPBUFFERARB hPbuffer, - HDC hDC); -typedef BOOL (WINAPI * WGLDestroyPBufferProc) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * WGLQueryPBufferProc) ( - HPBUFFERARB hPbuffer, - int iAttribute, - int *piValue); -#endif - - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -typedef BOOL (WINAPI * WGLGetPixelFormatAttribivProc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * WGLGetPixelFormatAttribfvProc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * WGLChoosePixelFormatProc) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - - - -#ifndef WGL_ARB_render_texture -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -typedef BOOL (WINAPI * WGLBindTexImageProc) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * WGLReleaseTexImageProc) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * WGLSetPbufferAttribProc) (HPBUFFERARB hPbuffer, const int * piAttribList); -#endif - - -#define MAX_PFORMATS 256 -#define MAX_ATTRIBS 32 - - - -class PBuffer -{ - private: - - HDC _hDC; // Handle to a device context. - HGLRC _hGLcontext; // Handle to a GL context. - HPBUFFERARB _hPBuffer; // Handle to a pbuffer. - int _width; - int _height; - - bool _doubleBuffer; - bool _RGB; - bool _shareLists; - unsigned int _minimumNumberDepthBits; - unsigned int _minimumNumberAlphaBits; - unsigned int _minimumNumberStencilBits; - unsigned int _minimumNumberAccumulationBits; - - bool _isPBufferSupported; - bool _isPixelFormatSupported; - bool _isRenderTextureSupported; - - public: - - PBuffer(const int width, const int height ); - ~PBuffer(); - void handleModeSwitch(); - void makeCurrent(); - void initialize(); - void bindTexImage(GLuint textureID); - void releaseTexImage(); - - - protected: - - void setupGLExtenions(); - -}; - -#endif \ No newline at end of file