diff --git a/examples/osgprerender/osgprerender.cpp b/examples/osgprerender/osgprerender.cpp index a44e1c89f..8af3a908e 100644 --- a/examples/osgprerender/osgprerender.cpp +++ b/examples/osgprerender/osgprerender.cpp @@ -253,6 +253,12 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates pre rendering of scene to a texture, and then apply this texture to geometry."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--fbo","Use Frame Buffer Object for render to texture, where supported."); + arguments.getApplicationUsage()->addCommandLineOption("--fb","Use FrameBuffer for render to texture."); + arguments.getApplicationUsage()->addCommandLineOption("--pbuffer","Use Pixel Buffer for render to texture, where supported."); + arguments.getApplicationUsage()->addCommandLineOption("--window","Use a seperate Window for render to texture."); + arguments.getApplicationUsage()->addCommandLineOption("--width","Set the width of the render to texture"); + arguments.getApplicationUsage()->addCommandLineOption("--height","Set the height of the render to texture"); // construct the viewer. osgProducer::Viewer viewer(arguments); diff --git a/examples/osgprerendercubemap/osgprerendercubemap.cpp b/examples/osgprerendercubemap/osgprerendercubemap.cpp index 2cf2f47d3..56110bc19 100644 --- a/examples/osgprerendercubemap/osgprerendercubemap.cpp +++ b/examples/osgprerendercubemap/osgprerendercubemap.cpp @@ -187,14 +187,11 @@ class TexMatCullCallback : public osg::NodeCallback }; -osg::Group* createShadowedScene(osg::Node* reflectedSubgraph, osg::RefNodePath reflectorNodePath, unsigned int unit, const osg::Vec4& clearColor) +osg::Group* createShadowedScene(osg::Node* reflectedSubgraph, osg::RefNodePath reflectorNodePath, unsigned int unit, const osg::Vec4& clearColor, unsigned tex_width, unsigned tex_height, osg::CameraNode::RenderTargetImplementation renderImplementation) { osg::Group* group = new osg::Group; - unsigned int tex_width = 512; - unsigned int tex_height = 512; - osg::TextureCubeMap* texture = new osg::TextureCubeMap; texture->setTextureSize(tex_width, tex_height); @@ -220,7 +217,7 @@ osg::Group* createShadowedScene(osg::Node* reflectedSubgraph, osg::RefNodePath r camera->setRenderOrder(osg::CameraNode::PRE_RENDER); // tell the camera to use OpenGL frame buffer object where supported. - camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); + camera->setRenderTargetImplmentation(renderImplementation); // attach the texture and use it as the color buffer. camera->attach(osg::CameraNode::COLOR_BUFFER, texture, 0, i); @@ -276,6 +273,12 @@ int main(int argc, char** argv) arguments.getApplicationUsage()->setDescription(arguments.getApplicationName() + " is the example which demonstrates using of GL_ARB_shadow extension implemented in osg::Texture class"); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()); arguments.getApplicationUsage()->addCommandLineOption("-h or --help", "Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--fbo","Use Frame Buffer Object for render to texture, where supported."); + arguments.getApplicationUsage()->addCommandLineOption("--fb","Use FrameBuffer for render to texture."); + arguments.getApplicationUsage()->addCommandLineOption("--pbuffer","Use Pixel Buffer for render to texture, where supported."); + arguments.getApplicationUsage()->addCommandLineOption("--window","Use a seperate Window for render to texture."); + arguments.getApplicationUsage()->addCommandLineOption("--width","Set the width of the render to texture"); + arguments.getApplicationUsage()->addCommandLineOption("--height","Set the height of the render to texture"); // construct the viewer. osgProducer::Viewer viewer(arguments); @@ -292,6 +295,19 @@ int main(int argc, char** argv) arguments.getApplicationUsage()->write(std::cout); return 1; } + + unsigned tex_width = 512; + unsigned tex_height = 512; + while (arguments.read("--width", tex_width)) {} + while (arguments.read("--height", tex_height)) {} + + osg::CameraNode::RenderTargetImplementation renderImplementation = osg::CameraNode::FRAME_BUFFER_OBJECT; + + while (arguments.read("--fbo")) { renderImplementation = osg::CameraNode::FRAME_BUFFER_OBJECT; } + while (arguments.read("--pbuffer")) { renderImplementation = osg::CameraNode::PIXEL_BUFFER; } + while (arguments.read("--fb")) { renderImplementation = osg::CameraNode::FRAME_BUFFER; } + while (arguments.read("--window")) { renderImplementation = osg::CameraNode::SEPERATE_WINDOW; } + // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); @@ -309,7 +325,8 @@ int main(int argc, char** argv) ref_ptr reflectedSubgraph = _create_scene(); if (!reflectedSubgraph.valid()) return 1; - ref_ptr reflectedScene = createShadowedScene(reflectedSubgraph.get(),createReflector(),0, viewer.getClearColor()); + ref_ptr reflectedScene = createShadowedScene(reflectedSubgraph.get(), createReflector(), 0, viewer.getClearColor(), + tex_width, tex_height, renderImplementation); scene->addChild(reflectedScene.get()); diff --git a/include/osg/TextureCubeMap b/include/osg/TextureCubeMap index 22a6d8622..c62720178 100644 --- a/include/osg/TextureCubeMap +++ b/include/osg/TextureCubeMap @@ -17,7 +17,16 @@ #include #ifndef GL_TEXTURE_CUBE_MAP -#define GL_TEXTURE_CUBE_MAP 0x8513 + #define GL_TEXTURE_CUBE_MAP 0x8513 + #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A + #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B + #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #endif namespace osg { @@ -110,6 +119,16 @@ class OSG_EXPORT TextureCubeMap : public Texture /** Get the number of mip map levels the the texture has been created with. */ unsigned int getNumMipmapLevels() const { return _numMipmapLevels; } + /** Copies a two-dimensional texture subimage, as per + * glCopyTexSubImage2D. Updates a portion of an existing OpenGL + * texture object from the current OpenGL background framebuffer + * contents at position \a x, \a y with width \a width and height + * \a height. Loads framebuffer data into the texture using offsets + * \a xoffset and \a yoffset. \a width and \a height must be powers + * of two. */ + void copyTexSubImageCubeMap(State& state, int face, int xoffset, int yoffset, int x, int y, int width, int height ); + + /** On first apply (unless already compiled), create the mipmapped * texture and bind it. Subsequent apply will simple bind to texture. */ diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index b52168aa4..5d24cc0be 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -22,69 +22,15 @@ using namespace osg; - -// include/osg/TextureCubeMap defines GL_TEXTURE_CUBE_MAP to be -// 0x8513 which is the same as GL_TEXTURE_CUBE_MAP_ARB & _EXT. -// assume its the same as what OpenGL 1.3 defines. - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif - - -#ifndef GL_EXT_texture_cube_map -#define GL_EXT_texture_cube_map 1 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#endif - - -#ifdef GL_ARB_texture_cube_map -# define CUBE_MAP_POSITIVE_X GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB -# define CUBE_MAP_NEGATIVE_X GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB -# define CUBE_MAP_POSITIVE_Y GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB -# define CUBE_MAP_NEGATIVE_Y GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB -# define CUBE_MAP_POSITIVE_Z GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB -# define CUBE_MAP_NEGATIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB -#elif GL_EXT_texture_cube_map -# define CUBE_MAP_POSITIVE_X GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT -# define CUBE_MAP_NEGATIVE_X GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT -# define CUBE_MAP_POSITIVE_Y GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT -# define CUBE_MAP_NEGATIVE_Y GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT -# define CUBE_MAP_POSITIVE_Z GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT -# define CUBE_MAP_NEGATIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -#endif - - -# if GL_EXT_texture_cube_map || GL_ARB_texture_cube_map static GLenum faceTarget[6] = { - CUBE_MAP_POSITIVE_X, - CUBE_MAP_NEGATIVE_X, - CUBE_MAP_POSITIVE_Y, - CUBE_MAP_NEGATIVE_Y, - CUBE_MAP_POSITIVE_Z, - CUBE_MAP_NEGATIVE_Z + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; -#endif TextureCubeMap::TextureCubeMap(): @@ -330,6 +276,74 @@ void TextureCubeMap::apply(State& state) const } } +void TextureCubeMap::copyTexSubImageCubeMap(State& state, int face, int xoffset, int yoffset, int x, int y, int width, int height ) +{ + const unsigned int contextID = state.getContextID(); + const Extensions* extensions = getExtensions(contextID,true); + + if (!extensions->isCubeMapSupported()) + return; + + if (_internalFormat==0) _internalFormat=GL_RGBA; + + // get the texture object for the current contextID. + TextureObject* textureObject = getTextureObject(contextID); + + if (!textureObject) + { + // create texture object. + apply(state); + + textureObject = getTextureObject(contextID); + + if (!textureObject) + { + // failed to create texture object + osg::notify(osg::NOTICE)<<"Warning : failed to create TextureCubeMap texture obeject, copyTexSubImageCubeMap abondoned."<bind(); + + applyTexParameters(GL_TEXTURE_CUBE_MAP, state); + + bool needHardwareMipMap = (_min_filter != LINEAR && _min_filter != NEAREST); + bool hardwareMipMapOn = false; + if (needHardwareMipMap) + { + const Texture::Extensions* tex_extensions = Texture::getExtensions(contextID,true); + bool generateMipMapSupported = tex_extensions->isGenerateMipMapSupported(); + + hardwareMipMapOn = _useHardwareMipMapGeneration && generateMipMapSupported; + + if (!hardwareMipMapOn) + { + // have to swtich off mip mapping + notify(NOTICE)<<"Warning: TextureCubeMap::copyTexImage2D(,,,,) switch of mip mapping as hardware support not available."< > BufferedExtensions; static BufferedExtensions s_extensions; diff --git a/src/osgProducer/GraphicsContextImplementation.cpp b/src/osgProducer/GraphicsContextImplementation.cpp index 90cc0e748..ad5230409 100644 --- a/src/osgProducer/GraphicsContextImplementation.cpp +++ b/src/osgProducer/GraphicsContextImplementation.cpp @@ -12,7 +12,8 @@ */ #include -#include +#include +#include using namespace osgProducer; @@ -50,22 +51,69 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) if (traits->_pbuffer) { - _rs->setDrawableType( Producer::RenderSurface::DrawableType_PBuffer ); + _rs->setDrawableType(Producer::RenderSurface::DrawableType_PBuffer); + + if (traits->_target) + { + + _rs->setRenderToTextureOptions(Producer::RenderSurface::RenderToTextureOptions_Default); + _rs->setRenderToTextureMipMapLevel(traits->_level); + _rs->setRenderToTextureMode(traits->_alpha>0 ? Producer::RenderSurface::RenderToRGBATexture : + Producer::RenderSurface::RenderToRGBTexture); + + switch(traits->_target) + { + case(GL_TEXTURE_1D) : + _rs->setRenderToTextureTarget(Producer::RenderSurface::Texture1D); + break; + case(GL_TEXTURE_2D) : + _rs->setRenderToTextureTarget(Producer::RenderSurface::Texture2D); + break; + case(GL_TEXTURE_3D) : + // not supported. + // _rs->setRenderToTextureTarget(Producer::RenderSurface::Texture3D); + break; + case(GL_TEXTURE_RECTANGLE) : + // not supported. + // _rs->setRenderToTextureTarget(Producer::RenderSurface::TextureRectangle); + break; + case(GL_TEXTURE_CUBE_MAP_POSITIVE_X) : + case(GL_TEXTURE_CUBE_MAP_NEGATIVE_X) : + case(GL_TEXTURE_CUBE_MAP_POSITIVE_Y) : + case(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : + case(GL_TEXTURE_CUBE_MAP_POSITIVE_Z) : + case(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) : + _rs->setRenderToTextureTarget(Producer::RenderSurface::TextureCUBE); + _rs->setRenderToTextureFace( Producer::RenderSurface::CubeMapFace(traits->_target - GL_TEXTURE_CUBE_MAP_POSITIVE_X)); + break; + } + + } - if (traits->_alpha>0) - { - _rs->setRenderToTextureMode(Producer::RenderSurface::RenderToRGBATexture); - } - else - { - _rs->setRenderToTextureMode(Producer::RenderSurface::RenderToRGBTexture); - } } - setState(new osg::State); - getState()->setContextID(1); + GraphicsContextImplementation* sharedContext = dynamic_cast(traits->_sharedContext); + + if (sharedContext) + { + // different graphics context so we have our own state. + setState(new osg::State); + + // but we share texture objects etc. so we also share the same contextID + getState()->setContextID( sharedContext->getState() ? sharedContext->getState()->getContextID() : 1 ); - _rs->realize(); + _rs->realize(0, sharedContext->_rs->getGLContext()); + } + else + { + static int count = 1; + + // need to do something here.... + setState(new osg::State); + getState()->setContextID(count++); + + _rs->realize(); + } } diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index e78920e5e..5eeb69747 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1148,7 +1148,7 @@ void CullVisitor::apply(osg::CameraNode& camera) ++itr) { // assign the texture... pro - if (itr->second._texture.valid()) rtts->setTexture(itr->second._texture.get()); + if (itr->second._texture.valid()) rtts->setTexture(itr->second._texture.get(), itr->second._level, itr->second._face); // if one exist attach image to the RenderToTextureStage. if (itr->second._image.valid()) rtts->setImage(itr->second._image.get()); diff --git a/src/osgUtil/RenderToTextureStage.cpp b/src/osgUtil/RenderToTextureStage.cpp index f6f2313f8..fd2c4ba54 100644 --- a/src/osgUtil/RenderToTextureStage.cpp +++ b/src/osgUtil/RenderToTextureStage.cpp @@ -48,6 +48,8 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous) if (_stageDrawnThisFrame) return; + state.checkGLErrors("beginning of RenderToTextureStage::draw()"); + //cout << "begining RTTS draw "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<(_texture.get())) != 0) { // need to implement - // textureCubeMap->copyTexImageCubeMap(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); + textureCubeMap->copyTexSubImageCubeMap(state, _face, 0, 0, _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); } } @@ -144,5 +146,7 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous) glReadBuffer(GL_BACK); } + state.checkGLErrors("end of RenderToTextureStage::draw()"); + }