Fixed RenderToTexture bug which occured when the viewport dimensions where
different than the texture being written to.
This commit is contained in:
@@ -125,7 +125,14 @@ osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const os
|
||||
camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
||||
|
||||
// set viewport
|
||||
// Both of these methods should produce the same result, but they don't.
|
||||
#if 1
|
||||
camera->setViewport(0,tex_height/2,tex_width,tex_height/2);
|
||||
#else
|
||||
camera->setViewport(0,0,tex_width,tex_height);
|
||||
osg::Viewport* vp = new osg::Viewport(0,tex_height/2,tex_width,tex_height/2);
|
||||
camera->getOrCreateStateSet()->setAttribute(vp);
|
||||
#endif
|
||||
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
|
||||
@@ -256,6 +256,27 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
_face(0),
|
||||
_mipMapGeneration(false) {}
|
||||
|
||||
int width() const
|
||||
{
|
||||
if (_texture.valid()) return _texture->getTextureWidth();
|
||||
if (_image.valid()) return _image->s();
|
||||
return 0;
|
||||
};
|
||||
|
||||
int height() const
|
||||
{
|
||||
if (_texture.valid()) return _texture->getTextureHeight();
|
||||
if (_image.valid()) return _image->t();
|
||||
return 0;
|
||||
};
|
||||
|
||||
int depth() const
|
||||
{
|
||||
if (_texture.valid()) return _texture->getTextureDepth();
|
||||
if (_image.valid()) return _image->r();
|
||||
return 0;
|
||||
};
|
||||
|
||||
GLenum _internalFormat;
|
||||
ref_ptr<Image> _image;
|
||||
ref_ptr<Texture> _texture;
|
||||
|
||||
@@ -220,6 +220,10 @@ class OSG_EXPORT Texture : public osg::StateAttribute
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual int getTextureWidth() const { return 0; }
|
||||
virtual int getTextureHeight() const { return 0; }
|
||||
virtual int getTextureDepth() const { return 0; }
|
||||
|
||||
enum WrapParameter {
|
||||
WRAP_S,
|
||||
WRAP_T,
|
||||
|
||||
@@ -74,7 +74,9 @@ class OSG_EXPORT Texture1D : public Texture
|
||||
inline void setTextureWidth(int width) const { _textureWidth = width; }
|
||||
|
||||
/** Gets the texture width. */
|
||||
inline int getTextureWidth() const { return _textureWidth; }
|
||||
virtual int getTextureWidth() const { return _textureWidth; }
|
||||
virtual int getTextureHeight() const { return 1; }
|
||||
virtual int getTextureDepth() const { return 1; }
|
||||
|
||||
|
||||
class OSG_EXPORT SubloadCallback : public Referenced
|
||||
|
||||
@@ -78,10 +78,11 @@ class OSG_EXPORT Texture2D : public Texture
|
||||
}
|
||||
|
||||
void setTextureWidth(int width) { _textureWidth=width; }
|
||||
int getTextureWidth() const { return _textureWidth; }
|
||||
|
||||
void setTextureHeight(int height) { _textureHeight=height; }
|
||||
int getTextureHeight() const { return _textureHeight; }
|
||||
|
||||
virtual int getTextureWidth() const { return _textureWidth; }
|
||||
virtual int getTextureHeight() const { return _textureHeight; }
|
||||
virtual int getTextureDepth() const { return 1; }
|
||||
|
||||
class OSG_EXPORT SubloadCallback : public Referenced
|
||||
{
|
||||
|
||||
@@ -85,13 +85,12 @@ class OSG_EXPORT Texture3D : public Texture
|
||||
}
|
||||
|
||||
void setTextureWidth(int width) { _textureWidth=width; }
|
||||
int getTextureWidth() const { return _textureWidth; }
|
||||
|
||||
void setTextureHeight(int height) { _textureHeight=height; }
|
||||
int getTextureHeight() const { return _textureHeight; }
|
||||
|
||||
void setTextureDepth(int depth) { _textureDepth=depth; }
|
||||
int getTextureDepth() const { return _textureDepth; }
|
||||
|
||||
virtual int getTextureWidth() const { return _textureWidth; }
|
||||
virtual int getTextureHeight() const { return _textureHeight; }
|
||||
virtual int getTextureDepth() const { return _textureDepth; }
|
||||
|
||||
|
||||
class OSG_EXPORT SubloadCallback : public Referenced
|
||||
|
||||
@@ -86,10 +86,11 @@ class OSG_EXPORT TextureCubeMap : public Texture
|
||||
}
|
||||
|
||||
void setTextureWidth(int width) { _textureWidth=width; }
|
||||
int getTextureWidth() const { return _textureWidth; }
|
||||
|
||||
void setTextureHeight(int height) { _textureHeight=height; }
|
||||
int getTextureHeight() const { return _textureHeight; }
|
||||
|
||||
virtual int getTextureWidth() const { return _textureWidth; }
|
||||
virtual int getTextureHeight() const { return _textureHeight; }
|
||||
virtual int getTextureDepth() const { return 1; }
|
||||
|
||||
class OSG_EXPORT SubloadCallback : public Referenced
|
||||
{
|
||||
|
||||
@@ -85,10 +85,11 @@ class OSG_EXPORT TextureRectangle : public Texture
|
||||
}
|
||||
|
||||
void setTextureWidth(int width) { _textureWidth=width; }
|
||||
int getTextureWidth() const { return _textureWidth; }
|
||||
|
||||
void setTextureHeight(int height) { _textureHeight=height; }
|
||||
int getTextureHeight() const { return _textureHeight; }
|
||||
|
||||
virtual int getTextureWidth() const { return _textureWidth; }
|
||||
virtual int getTextureHeight() const { return _textureHeight; }
|
||||
virtual int getTextureDepth() const { return 1; }
|
||||
|
||||
class SubloadCallback : public Referenced
|
||||
{
|
||||
|
||||
@@ -195,8 +195,25 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
|
||||
osg::CameraNode::BufferAttachmentMap& bufferAttachements = _camera->getBufferAttachmentMap();
|
||||
|
||||
// compute the required dimensions
|
||||
int width = _viewport->x() + _viewport->width();
|
||||
int height = _viewport->y() + _viewport->height();
|
||||
int depth = 1;
|
||||
osg::CameraNode::BufferAttachmentMap::iterator itr;
|
||||
for(itr = bufferAttachements.begin();
|
||||
itr != bufferAttachements.end();
|
||||
++itr)
|
||||
{
|
||||
width = osg::maximum(width,itr->second.width());
|
||||
height = osg::maximum(height,itr->second.height());
|
||||
depth = osg::maximum(depth,itr->second.depth());
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"RenderStage::runCameraSetUp viewport "<<_viewport->x()<<" "<<_viewport->y()<<" "<<_viewport->width()<<" "<<_viewport->height()<<std::endl;
|
||||
// osg::notify(osg::NOTICE)<<"RenderStage::runCameraSetUp computed "<<width<<" "<<height<<" "<<depth<<std::endl;
|
||||
|
||||
// attach an images that need to be copied after the stage is drawn.
|
||||
for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin();
|
||||
for(itr = bufferAttachements.begin();
|
||||
itr != bufferAttachements.end();
|
||||
++itr)
|
||||
{
|
||||
@@ -216,7 +233,7 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
if (dataType==0) dataType = _imageReadPixelDataType;
|
||||
if (dataType==0) dataType = GL_UNSIGNED_BYTE;
|
||||
|
||||
image->allocateImage(_viewport->width(), _viewport->height(), 1, pixelFormat, dataType);
|
||||
image->allocateImage(width, height, 1, pixelFormat, dataType);
|
||||
|
||||
}
|
||||
|
||||
@@ -238,14 +255,14 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
{
|
||||
if (texture1D->getTextureWidth()==0)
|
||||
{
|
||||
texture1D->setTextureWidth(_viewport->width());
|
||||
texture1D->setTextureWidth(width);
|
||||
}
|
||||
}
|
||||
else if (0 != (texture2D = dynamic_cast<osg::Texture2D*>(texture)))
|
||||
{
|
||||
if (texture2D->getTextureWidth()==0 || texture2D->getTextureHeight()==0)
|
||||
{
|
||||
texture2D->setTextureSize(_viewport->width(),_viewport->height());
|
||||
texture2D->setTextureSize(width,height);
|
||||
}
|
||||
}
|
||||
else if (0 != (texture3D = dynamic_cast<osg::Texture3D*>(texture)))
|
||||
@@ -253,21 +270,21 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
if (texture3D->getTextureWidth()==0 || texture3D->getTextureHeight()==0 || texture3D->getTextureDepth()==0 )
|
||||
{
|
||||
// note we dont' have the depth here, so we'll heave to assume that height and depth are the same..
|
||||
texture3D->setTextureSize(_viewport->width(),_viewport->height(),_viewport->height());
|
||||
texture3D->setTextureSize(width,height,height);
|
||||
}
|
||||
}
|
||||
else if (0 != (textureCubeMap = dynamic_cast<osg::TextureCubeMap*>(texture)))
|
||||
{
|
||||
if (textureCubeMap->getTextureWidth()==0 || textureCubeMap->getTextureHeight()==0)
|
||||
{
|
||||
textureCubeMap->setTextureSize(_viewport->width(),_viewport->height());
|
||||
textureCubeMap->setTextureSize(width,height);
|
||||
}
|
||||
}
|
||||
else if (0 != (textureRectangle = dynamic_cast<osg::TextureRectangle*>(texture)))
|
||||
{
|
||||
if (textureRectangle->getTextureWidth()==0 || textureRectangle->getTextureHeight()==0)
|
||||
{
|
||||
textureRectangle->setTextureSize(_viewport->width(),_viewport->height());
|
||||
textureRectangle->setTextureSize(width,height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,12 +341,12 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
|
||||
if (!depthAttached)
|
||||
{
|
||||
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(_viewport->width(), _viewport->height(), GL_DEPTH_COMPONENT24)));
|
||||
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_DEPTH_COMPONENT24)));
|
||||
}
|
||||
|
||||
if (!colorAttached)
|
||||
{
|
||||
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(_viewport->width(), _viewport->height(), GL_RGB)));
|
||||
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_RGB)));
|
||||
}
|
||||
|
||||
fbo->apply(state);
|
||||
@@ -396,8 +413,11 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
// set up the traits of the graphics context that we want
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||
|
||||
traits->_width = _viewport->width();
|
||||
traits->_height = _viewport->height();
|
||||
traits->_width = width;
|
||||
traits->_height = height;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"traits = "<<traits->_width<<" "<<traits->_height<<std::endl;
|
||||
|
||||
traits->_pbuffer = (renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER || renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER_RTT);
|
||||
traits->_windowDecoration = (renderTargetImplemntation==osg::CameraNode::SEPERATE_WINDOW);
|
||||
traits->_doubleBuffer = (renderTargetImplemntation==osg::CameraNode::SEPERATE_WINDOW);
|
||||
@@ -581,6 +601,36 @@ void RenderStage::copyTexture(osg::State& state)
|
||||
osg::TextureRectangle* textureRec = 0;
|
||||
osg::TextureCubeMap* textureCubeMap = 0;
|
||||
|
||||
#if 1
|
||||
// use TexCopySubImage with the offset of the viewport into the texture
|
||||
// note, this path mirrors the pbuffer and fbo means for updating the texture.
|
||||
// Robert Osfield, 3rd August 2006.
|
||||
if ((texture2D = dynamic_cast<osg::Texture2D*>(_texture.get())) != 0)
|
||||
{
|
||||
texture2D->copyTexSubImage2D(state,_viewport->x(),_viewport->y(), _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height());
|
||||
}
|
||||
else if ((textureRec = dynamic_cast<osg::TextureRectangle*>(_texture.get())) != 0)
|
||||
{
|
||||
textureRec->copyTexSubImage2D(state,_viewport->x(),_viewport->y(), _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height());
|
||||
}
|
||||
else if ((texture1D = dynamic_cast<osg::Texture1D*>(_texture.get())) != 0)
|
||||
{
|
||||
// need to implement
|
||||
texture1D->copyTexSubImage1D(state,_viewport->x(), _viewport->x(),_viewport->y(),_viewport->width());
|
||||
}
|
||||
else if ((texture3D = dynamic_cast<osg::Texture3D*>(_texture.get())) != 0)
|
||||
{
|
||||
// need to implement
|
||||
texture3D->copyTexSubImage3D(state, _viewport->x(), _viewport->y(), _face, _viewport->x(), _viewport->y(), _viewport->width(), _viewport->height());
|
||||
}
|
||||
else if ((textureCubeMap = dynamic_cast<osg::TextureCubeMap*>(_texture.get())) != 0)
|
||||
{
|
||||
// need to implement
|
||||
textureCubeMap->copyTexSubImageCubeMap(state, _face, _viewport->x(), _viewport->y(), _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height());
|
||||
}
|
||||
#else
|
||||
// use CopySubImage with the offset set to 0,0
|
||||
// original code path.
|
||||
if ((texture2D = dynamic_cast<osg::Texture2D*>(_texture.get())) != 0)
|
||||
{
|
||||
texture2D->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height());
|
||||
@@ -604,6 +654,7 @@ void RenderStage::copyTexture(osg::State& state)
|
||||
// need to implement
|
||||
textureCubeMap->copyTexSubImageCubeMap(state, _face, 0, 0, _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCopyTexture)
|
||||
|
||||
Reference in New Issue
Block a user