3

Hi I have problem while I am trying to create dynamic texture to assign as a background in my ogre window. I want to assign values dynamicly for an each pixel of texture and then I use this texture as a background. I use this code to create dynamic texture.

Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual("BackgroundTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 800, 600, 0, Ogre::PF_R8G8B8, Ogre:: TU_DYNAMIC);

Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("BackgroundMat",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
material->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTex");
material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_COLOUR);

Ogre::Rectangle2D* rect = new Ogre::Rectangle2D(true);
rect->setCorners(-1.0, 1.0, 1.0, -1.0);

rect->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND);
rect->setBoundingBox(Ogre::AxisAlignedBox(-100000.0 * Ogre::Vector3::UNIT_SCALE, 100000.0 * Ogre::Vector3::UNIT_SCALE));

Ogre::SceneNode* node = sceneManager->getRootSceneNode()->createChildSceneNode("BackgroundMat");
node->attachObject(rect);
node->setVisible(true);
rect->setMaterial("BackgroundMat");
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);

for(size_t i=0; i < 600; i++)
{    
   for(size_t j=0; j < 800; j++)
   {    
      *pDest++ = 0;
      *pDest++ = 0;
      *pDest++ = 255;

   }
}

pixelBuffer->unlock();

in this piece of code I assign blue ( R:0 G:0 B:255 ) for each value. I expect to obtain full of blue window but instead of blue background I obtain this background that seen in the picture. enter image description here

Instead of blue background, in the texture that I obtain there are 3 different color types and they are always repeat sequently. Blue pixels are true but the other 2 color would be blue as well. I cant find reason that cause this problem. What can I do? What is a wrong part?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
barzos
  • 837
  • 3
  • 16
  • 25
  • 1
    I don't use ogre but are you allowing for the transparent channel ARGB ? It looks like you need an extra *pDest++ = 0 – Christopher Nov 18 '11 at 13:16
  • @Christopher Seems very probable, especially when looking at the repeating pattern. – Christian Rau Nov 18 '11 at 13:40
  • but at the beginnig I create texture with PF_R8G8B8 so I dont have alpha channel. the first pixel is true that is blue but two followig pixel wrong. goes like that sequently – barzos Nov 18 '11 at 22:26

2 Answers2

2

According to Christopher's comment:

I have no experience with Ogre3D, but can it be that it actually gives you the image data as RGBA (or BGRA, or ARGB) instead of just RGB. So you miss an additional pDest++ (or maybe *pDest++ = 255) and therefore in the first loop interation you get blue, then green, then red and then blue again, ..., which would somehow coincide with your shown image.

EDIT: In your comment you say (if I understood correctly) that you get a completely red image when you add an additional ++pDest in the loop. This at least tells us that you indeed get a 4-component image from Ogre3D, since we now are not out of sync with the colors anymore and have only a single color. But since this color is red, it seems Ogre3D gives you the image data as BGRA. So just set the first component to 255 instead of the third (and of course keep this additional ++pDest in there).

You may have specified the texture as PF_R8G8B8, but it seems Ogre3D has some freedom regarding the layout of the image data in the buffer and actually the graphics driver also has some freedom regarding the memory layout of the textures and often a 32-bit RGBA or BGRA image has some advantages over 24-bit RGB.

It may also depend what underlying graphics API (D3D or GL) is used by Ogre3D and which is the standard there. In GL for example you cannot map texture memory directly and need to use a PBO for this, whose memory layout can in turn be chosen different from the texture. I don't know about D3D, but I think D3D especially likes BGRA layout.

EDIT: You can also check pixelBox.format to see what format the data has.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
  • I set a texture with PF_R8G8B8. As you say, I add an additional pDest++ as a fourth iteration but ı didnt assign any value to fourth pDest++. At this time I obtain full of red image that actually it would be blue image. In this way I get a completely wrong image. What is your advice ? I need a help – barzos Nov 18 '11 at 22:34
  • @barzos Updated my answer. It seems you get the image data as BGRA. – Christian Rau Nov 18 '11 at 23:05
1

I had met the same problem like this.

The texture you have created was in the format of Ogre::PF_R8G8B8, but the actual hardwarebuffer Ogre is using is still Ogre::PF_R8G8B8A8, which means it's 4 bits rather than 3 bits.

You can add another line in your loop:

pDest++;
j0k
  • 22,600
  • 28
  • 79
  • 90
Madwyn
  • 409
  • 3
  • 13