Bugfix: AutoRenderingSurface + Linux + AMD
Posted: Mon Dec 03, 2012 03:59
02/12/2012 21:43:37 (Std) ********************************************************************************
02/12/2012 21:43:37 (Std) * -------- START OF ESSENTIAL SECTION TO BE POSTED ON THE FORUM -------- *
02/12/2012 21:43:37 (Std) ********************************************************************************
02/12/2012 21:43:37 (Std) ---- Version 0.7.6 (Build: Nov 6 2012 GNU/Linux g++ 4.6.3 32 bit) ----
02/12/2012 21:43:37 (Std) ---- Renderer module is: CEGUI::OgreRenderer - Official OGRE based 2nd generation renderer module. ----
02/12/2012 21:43:37 (Std) ---- XML Parser module is: CEGUI::TinyXMLParser - Official tinyXML based parser module for CEGUI ----
02/12/2012 21:43:37 (Std) ---- Image Codec module is: OgreImageCodec - Integrated ImageCodec using the Ogre engine. ----
02/12/2012 21:43:37 (Std) ---- Scripting module is: None ----
I'm porting my game to linux. I use the CEGUIOgreRenderer. I noticed some texture corruption in CEGUI.
Examples:
Additional notes:
- This only occurs on linux, using an AMD video card. (Ubuntu 12.04 + Radeon HD 7770)
- There is no texture corruption on windows, nor linux+NVIDIA geforce card
I figured out the corruption only occurred where I was using the AutoRenderingSurface property.
I've added some code to clear the associated texture when it is created, and it fixes the problem on my system.
I wanted to share my solution here.
File: CEGUIOgreTextureTarget.cpp
Function: OgreTextureTarget::declareRenderSize
Code, added to bottom of function:
Code: Select all
// clear the texture
// - appears to be necessary on Linux + AMD Radeon cards or else AutoRenderingSurface textures show corruption
// in areas not drawn to.
Ogre::HardwarePixelBufferSharedPtr pTexBuf = rttTex->getBuffer();
pTexBuf->lock( Ogre::HardwareBuffer::HBL_DISCARD );
memset( pTexBuf->getCurrentLock().data, 0x00, pTexBuf->getSizeInBytes() );
pTexBuf->unlock();
Full function source:
Code: Select all
void OgreTextureTarget::declareRenderSize(const Size& sz)
{
// exit if current size is enough
if ((d_area.getWidth() >= sz.d_width) && (d_area.getHeight() >=sz.d_height))
return;
Ogre::TexturePtr rttTex = Ogre::TextureManager::getSingleton().createManual(
OgreTexture::getUniqueName(),
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, sz.d_width, sz.d_height, 1, 0, Ogre::PF_A8R8G8B8,
Ogre::TU_RENDERTARGET);
d_renderTarget = rttTex->getBuffer()->getRenderTarget();
Rect init_area(
Vector2(0, 0),
Size(d_renderTarget->getWidth(), d_renderTarget->getHeight())
);
setArea(init_area);
// delete viewport and reset ptr so a new one is generated. This is
// required because we have changed d_renderTarget so need a new VP also.
delete d_viewport;
d_viewport = 0;
// because Texture takes ownership, the act of setting the new ogre texture
// also ensures any previous ogre texture is released.
d_CEGUITexture->setOgreTexture(rttTex, true);
clear();
// clear the texture
// - appears to be necessary on Linux + AMD Radeon cards or else AutoRenderingSurface textures show corruption
// in areas not drawn to.
Ogre::HardwarePixelBufferSharedPtr pTexBuf = rttTex->getBuffer();
pTexBuf->lock( Ogre::HardwareBuffer::HBL_DISCARD );
memset( pTexBuf->getCurrentLock().data, 0x00, pTexBuf->getSizeInBytes() );
pTexBuf->unlock();
}