Improved handling of osg::Image copying.

This commit is contained in:
Robert Osfield
2005-11-01 15:23:03 +00:00
parent a4275fb8d7
commit 4509232792
2 changed files with 98 additions and 38 deletions

View File

@@ -214,45 +214,64 @@ FrameBufferAttachment::FrameBufferAttachment(TextureRectangle* 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)
if (texture)
{
_ximpl = new Pimpl(Pimpl::TEXTURE2D, attachment._level);
_ximpl->textureTarget = texture2D;
return;
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::Texture3D* texture3D = dynamic_cast<osg::Texture3D*>(texture);
if (texture3D)
osg::Image* image = attachment._image.get();
if (image)
{
_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;
if (image->s()>0 && image->t()>0 && image->getPixelFormat()>0)
{
_ximpl = new Pimpl(Pimpl::RENDERBUFFER);
_ximpl->renderbufferTarget = new osg::RenderBuffer(image->s(), image->t(), image->getPixelFormat());
}
else
{
osg::notify(osg::WARN)<<"Error: FrameBufferAttachment::FrameBufferAttachment(CameraNode::Attachment&) passed an empty osg::Image, image must be allocated first."<<std::endl;
}
return;
}

View File

@@ -161,8 +161,31 @@ void RenderStage::runCameraSetUp(osg::State& state)
itr != bufferAttachements.end();
++itr)
{
// if one exist attach image to the RenderToTextureStage.
if (itr->second._image.valid()) setImage(itr->second._image.get());
// if one exist attach image to the RenderStage.
if (itr->second._image.valid())
{
osg::Image* image = itr->second._image.get();
GLenum pixelFormat = image->getPixelFormat();
GLenum dataType = image->getDataType();
if (image->data()==0)
{
if (pixelFormat==0) pixelFormat = itr->second._internalFormat;
if (pixelFormat==0) pixelFormat = _imageReadPixelFormat;
if (pixelFormat==0) pixelFormat = GL_RGBA;
if (dataType==0) dataType = _imageReadPixelDataType;
if (dataType==0) dataType = GL_UNSIGNED_BYTE;
image->allocateImage(_viewport->width(), _viewport->height(), 1, pixelFormat, dataType);
}
_imageReadPixelFormat = pixelFormat;
_imageReadPixelDataType = dataType;
setImage(itr->second._image.get());
}
}
if (renderTargetImplemntation==osg::CameraNode::FRAME_BUFFER_OBJECT)
@@ -182,7 +205,7 @@ void RenderStage::runCameraSetUp(osg::State& state)
osg::notify(osg::INFO)<<"Setting up osg::CameraNode::FRAME_BUFFER_OBJECT"<<std::endl;
_fbo = new osg::FrameBufferObject;
setDrawBuffer(GL_BACK);
setReadBuffer(GL_BACK);
@@ -196,6 +219,7 @@ void RenderStage::runCameraSetUp(osg::State& state)
osg::CameraNode::BufferComponent buffer = itr->first;
osg::CameraNode::Attachment& attachment = itr->second;
switch(buffer)
{
case(osg::CameraNode::DEPTH_BUFFER):
@@ -496,6 +520,8 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop
copyTexture(state);
}
state.checkGLErrors("before readPixel;");
if (_image.valid())
{
@@ -504,7 +530,17 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop
glReadBuffer(_readBuffer);
}
_image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType);
GLenum pixelFormat = _image->getPixelFormat();
if (pixelFormat==0) pixelFormat = _imageReadPixelFormat;
if (pixelFormat==0) pixelFormat = GL_RGB;
GLenum dataType = _image->getDataType();
if (dataType==0) dataType = _imageReadPixelDataType;
if (dataType==0) dataType = GL_UNSIGNED_BYTE;
_image->readPixels(_viewport->x(), _viewport->y(),
_viewport->width(), _viewport->height(),
pixelFormat, dataType);
}
@@ -514,6 +550,8 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop
(*(_camera->getPostDrawCallback()))(*_camera);
}
state.checkGLErrors("before glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);");
if (fbo_supported)
{
// switch of the frame buffer object
@@ -522,6 +560,9 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop
doCopyTexture = true;
}
state.checkGLErrors("after glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);");
if (fbo_supported && _camera)
{
// now generate mipmaps if they are required.