Added support for TextureCubeMap into osgUtil::RenderToTextureStage.

This commit is contained in:
Robert Osfield 2005-07-25 13:05:57 +00:00
parent ee8f7bb756
commit 3c23a42f17
7 changed files with 190 additions and 82 deletions

View File

@ -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);

View File

@ -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<Group> reflectedSubgraph = _create_scene();
if (!reflectedSubgraph.valid()) return 1;
ref_ptr<Group> reflectedScene = createShadowedScene(reflectedSubgraph.get(),createReflector(),0, viewer.getClearColor());
ref_ptr<Group> reflectedScene = createShadowedScene(reflectedSubgraph.get(), createReflector(), 0, viewer.getClearColor(),
tex_width, tex_height, renderImplementation);
scene->addChild(reflectedScene.get());

View File

@ -17,7 +17,16 @@
#include <osg/Texture>
#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.
*/

View File

@ -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."<<std::endl;
return;
}
}
GLenum target = faceTarget[face];
if (textureObject)
{
// we have a valid image
textureObject->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."<<std::endl;
_min_filter = LINEAR;
}
}
if (hardwareMipMapOn) glTexParameteri( target, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
glCopyTexSubImage2D( target , 0, xoffset, yoffset, x, y, width, height);
if (hardwareMipMapOn) glTexParameteri( target, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
// inform state that this texture is the current one bound.
state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);
}
}
typedef buffered_value< ref_ptr<TextureCubeMap::Extensions> > BufferedExtensions;
static BufferedExtensions s_extensions;

View File

@ -12,7 +12,8 @@
*/
#include <osgProducer/GraphicsContextImplementation>
#include <osg/Notify>
#include <osg/TextureRectangle>
#include <osg/TextureCubeMap>
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<GraphicsContextImplementation*>(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();
}
}

View File

@ -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());

View File

@ -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 "<<this<< " "<<_viewport->x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<<std::endl;
osg::State* useState = &state;
@ -115,7 +117,7 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
else if ((textureCubeMap = dynamic_cast<osg::TextureCubeMap*>(_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()");
}