Ported all the render to texture examples across to using the new osg::CameraNode.

Added support for texture cube maps in FBO + CameraNode.
This commit is contained in:
Robert Osfield
2005-07-19 16:30:55 +00:00
parent 5c9bd792a3
commit 8dd013171c
23 changed files with 786 additions and 709 deletions

View File

@@ -23,6 +23,7 @@ CameraNode::CameraNode():
_renderOrder(POST_RENDER),
_renderTargetImplementation(FRAME_BUFFER)
{
setStateSet(new StateSet);
}
CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
@@ -30,6 +31,7 @@ CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
CullSettings(camera),
_clearColor(camera._clearColor),
_clearMask(camera._clearMask),
_colorMask(camera._colorMask),
_viewport(camera._viewport),
_transformOrder(camera._transformOrder),
_projectionMatrix(camera._projectionMatrix),
@@ -37,8 +39,7 @@ CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
_renderOrder(camera._renderOrder),
_renderTargetImplementation(camera._renderTargetImplementation),
_bufferAttachmentMap(camera._bufferAttachmentMap)
{
{
}
@@ -46,6 +47,54 @@ CameraNode::~CameraNode()
{
}
void CameraNode::setColorMask(osg::ColorMask* colorMask)
{
if (_colorMask == colorMask) return;
osg::StateSet* stateset = getOrCreateStateSet();
if (_colorMask.valid() && stateset)
{
stateset->removeAttribute(_colorMask.get());
}
_colorMask = colorMask;
if (_colorMask.valid() && stateset)
{
stateset->setAttribute(_colorMask.get());
}
}
void CameraNode::setColorMask(bool red, bool green, bool blue, bool alpha)
{
if (!_colorMask) setColorMask(new osg::ColorMask);
if (_colorMask.valid()) _colorMask->setMask(red,green,blue,alpha);
}
void CameraNode::setViewport(osg::Viewport* viewport)
{
if (_viewport == viewport) return;
osg::StateSet* stateset = getOrCreateStateSet();
if (_viewport.valid() && stateset)
{
stateset->removeAttribute(_viewport.get());
}
_viewport = viewport;
if (_viewport.valid() && stateset)
{
stateset->setAttribute(_viewport.get());
}
}
void CameraNode::setViewport(int x,int y,int width,int height)
{
if (!_viewport) setViewport(new osg::Viewport);
if (_viewport.valid()) _viewport->setViewport(x,y,width,height);
}
Matrixd CameraNode::getInverseViewMatrix() const
{
Matrixd inverse;

View File

@@ -211,6 +211,55 @@ FrameBufferAttachment::FrameBufferAttachment(TextureRectangle* target)
_ximpl->textureTarget = target;
}
FrameBufferAttachment::FrameBufferAttachment(CameraNode::Attachment& attachment)
{
osg::Texture* texture = attachment._texture.get();
osg::Texture1D* texture1D = dynamic_cast<osg::Texture1D*>(texture);
if (texture1D)
{
_ximpl = new Pimpl(Pimpl::TEXTURE1D, attachment._level);
_ximpl->textureTarget = texture1D;
return;
}
osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(texture);
if (texture2D)
{
_ximpl = new Pimpl(Pimpl::TEXTURE2D, attachment._level);
_ximpl->textureTarget = texture2D;
return;
}
osg::Texture3D* texture3D = dynamic_cast<osg::Texture3D*>(texture);
if (texture3D)
{
_ximpl = new Pimpl(Pimpl::TEXTURE3D, attachment._level);
_ximpl->textureTarget = texture3D;
_ximpl->zoffset = attachment._face;
return;
}
osg::TextureCubeMap* textureCubeMap = dynamic_cast<osg::TextureCubeMap*>(texture);
if (textureCubeMap)
{
_ximpl = new Pimpl(Pimpl::TEXTURECUBE, attachment._level);
_ximpl->textureTarget = textureCubeMap;
_ximpl->cubeMapFace = attachment._face;
return;
}
osg::TextureRectangle* textureRectangle = dynamic_cast<osg::TextureRectangle*>(texture);
if (textureRectangle)
{
_ximpl = new Pimpl(Pimpl::TEXTURERECT);
_ximpl->textureTarget = textureRectangle;
return;
}
osg::notify(osg::WARN)<<"Error: FrameBufferAttachment::FrameBufferAttachment(CameraNode::Attachment&) passed an unrecognised Texture type."<<std::endl;
}
FrameBufferAttachment::~FrameBufferAttachment()
{
delete _ximpl;

View File

@@ -15,9 +15,9 @@
using namespace osg;
FrontFace::FrontFace()
FrontFace::FrontFace(Mode face)
{
_mode = COUNTER_CLOCKWISE;
_mode = face;
}

View File

@@ -90,9 +90,6 @@ void TexGen::apply(State&) const
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
// note, R & Q will be disabled so R&Q settings won't
// have an effect, see above comment in enable(). RO.
}
else if (_mode == EYE_LINEAR)
{
@@ -106,9 +103,6 @@ void TexGen::apply(State&) const
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
// note, R & Q will be disabled so R&Q settings won't
// have an effect, see above comment in enable(). RO.
}
else if (_mode == NORMAL_MAP)
{

View File

@@ -15,6 +15,7 @@
#include <osg/Image>
#include <osg/State>
#include <osg/TextureCubeMap>
#include <osg/Notify>
#include <osg/GLU>
@@ -302,6 +303,26 @@ void TextureCubeMap::apply(State& state) const
}
}
}
else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_internalFormat!=0) )
{
_textureObjectBuffer[contextID] = textureObject = generateTextureObject(
contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);
textureObject->bind();
applyTexParameters(GL_TEXTURE_CUBE_MAP,state);
for (int n=0; n<6; n++)
{
// no image present, but dimensions at set so less create the texture
glTexImage2D( faceTarget[n], 0, _internalFormat,
_textureWidth, _textureHeight, _borderWidth,
_internalFormat,
GL_UNSIGNED_BYTE,
0);
}
}
else
{

View File

@@ -1036,6 +1036,7 @@ void CullVisitor::apply(osg::CameraNode& camera)
StateSet* node_state = camera.getStateSet();
if (node_state) pushStateSet(node_state);
osg::RefMatrix& originalModelView = getModelViewMatrix();
if (camera.getReferenceFrame()==osg::Transform::ABSOLUTE_RF)
{
@@ -1078,17 +1079,28 @@ void CullVisitor::apply(osg::CameraNode& camera)
// will do later.
osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage();
// set the compute near far mode.
ComputeNearFarMode saved_compute_near_far_mode = getComputeNearFarMode();
setComputeNearFarMode( camera.getComputeNearFarMode());
// set up the background color and clear mask.
rtts->setClearColor(camera.getClearColor());
rtts->setClearMask(camera.getClearMask());
osg::Viewport* viewport = camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport();
// set the color mask.
osg::ColorMask* colorMask = camera.getColorMask()!=0 ? camera.getColorMask() : previous_stage->getColorMask();
rtts->setColorMask(colorMask);
// set up the viewport.
osg::Viewport* viewport = camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport();
rtts->setViewport( viewport );
// set up to charge the same RenderStageLighting is the parent previous stage.
//rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
osg::Matrix inhertiedMVtolocalMV;
inhertiedMVtolocalMV.invert(originalModelView);
inhertiedMVtolocalMV.postMult(getModelViewMatrix());
rtts->setInheritedRenderStageLightingMatrix(inhertiedMVtolocalMV);
rtts->setInheritedRenderStageLighting(previous_stage->getRenderStageLighting());
// record the render bin, to be restored after creation
// of the render to text
@@ -1106,6 +1118,10 @@ void CullVisitor::apply(osg::CameraNode& camera)
// restore the previous renderbin.
setCurrentRenderBin(previousRenderBin);
// restore the previous compute near far mode
setComputeNearFarMode(saved_compute_near_far_mode);
if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
{
@@ -1156,9 +1172,49 @@ void CullVisitor::apply(osg::CameraNode& camera)
fbo = new osg::FrameBufferObject;
rtts->setFrameBufferObject(fbo.get());
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(tex));
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_DEPTH_COMPONENT24)));
bool colorAttached = false;
bool depthAttached = false;
bool stencilAttached = false;
for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin();
itr != bufferAttachements.end();
++itr)
{
osg::CameraNode::BufferComponent buffer = itr->first;
osg::CameraNode::Attachment& attachment = itr->second;
switch(buffer)
{
case(osg::CameraNode::DEPTH_BUFFER):
{
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment));
depthAttached = true;
break;
}
case(osg::CameraNode::STENCIL_BUFFER):
{
fbo->setAttachment(GL_STENCIL_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment));
stencilAttached = true;
break;
}
default:
{
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(attachment));
colorAttached = true;
break;
}
}
}
if (!depthAttached)
{
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_DEPTH_COMPONENT24)));
}
if (!colorAttached)
{
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_RGB)));
}
}
}

View File

@@ -177,8 +177,17 @@ void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous)
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// apply the lights.
if (_renderStageLighting.valid()) _renderStageLighting->draw(state,previous);
// apply the positional state.
if (_inheritedRenderStageLighting.valid())
{
_inheritedRenderStageLighting->draw(state, previous, &_inheritedRenderStageLightingMatrix);
}
// apply the positional state.
if (_renderStageLighting.valid())
{
_renderStageLighting->draw(state, previous, 0);
}
// draw the children and local.
RenderBin::drawImplementation(state,previous);

View File

@@ -32,7 +32,7 @@ void RenderStageLighting::reset()
_texAttrListMap.clear();
}
void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous, const osg::Matrix* postMultMatrix)
{
if (previous)
@@ -47,7 +47,18 @@ void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
litr!=_attrList.end();
++litr)
{
state.applyModelViewMatrix((*litr).second.get());
if (postMultMatrix)
{
if ((*litr).second.valid())
state.applyModelViewMatrix(new osg::RefMatrix( (*((*litr).second)) * (*postMultMatrix)));
else
state.applyModelViewMatrix(new osg::RefMatrix( *postMultMatrix));
}
else
{
state.applyModelViewMatrix((*litr).second.get());
}
// apply the light source.
litr->first->apply(state);
@@ -71,7 +82,17 @@ void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
litr!=attrList.end();
++litr)
{
state.applyModelViewMatrix((*litr).second.get());
if (postMultMatrix)
{
if ((*litr).second.valid())
state.applyModelViewMatrix(new osg::RefMatrix( (*((*litr).second)) * (*postMultMatrix)));
else
state.applyModelViewMatrix(new osg::RefMatrix( *postMultMatrix));
}
else
{
state.applyModelViewMatrix((*litr).second.get());
}
// apply the light source.
litr->first->apply(state);

View File

@@ -60,8 +60,11 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
}
if (_image.valid())
{
_image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType);
}
if (fbo_supported)
{
fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);