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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
FrontFace::FrontFace()
|
||||
FrontFace::FrontFace(Mode face)
|
||||
{
|
||||
_mode = COUNTER_CLOCKWISE;
|
||||
_mode = face;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user