在OGRE中创建动态纹理时获取错误的RGB

时间:2011-11-18 12:14:58

标签: c++ textures ogre3d render-to-texture ogre

嗨我在尝试创建动态纹理以在我的食人魔窗口中指定为背景时遇到问题。我想为每个纹理像素动态分配值,然后我将此纹理用作背景。 我使用这段代码来创建动态纹理。

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();

在这段代码中,我为每个值分配蓝色(R:0 G:0 B:255)。我希望获得充满蓝色的窗口,但我获得了图片中所见的背景,而不是蓝色背景。 enter image description here

而不是蓝色背景,在我获得的纹理中有3种不同的颜色类型,它们总是重复。蓝色像素是真实的,但另外2个颜色也是蓝色。我找不到导致这个问题的原因。我能做什么?什么是错误的部分?

2 个答案:

答案 0 :(得分:1)

根据克里斯托弗的评论:

我没有使用Ogre3D的经验,但实际上它可以将图像数据作为RGBA(或BGRA或ARGB)而不仅仅是RGB。所以你错过了一个额外的pDest++(或者*pDest++ = 255),因此在第一个循环中,你会得到蓝色,然后是绿色,然后是红色,然后是蓝色......,这会与你的某些方式重合显示图像。

编辑:在您的评论中,您说(如果我理解正确)当您在循环中添加其他++pDest时,您会获得完全红色的图像。这至少告诉我们你确实从Ogre3D获得了一个4分量的图像,因为我们现在不再与颜色不同步并且只有一种颜色。但由于这种颜色是红色,似乎Ogre3D会将图像数据作为BGRA。因此,只需将第一个组件设置为255而不是第三个组件(当然还要将其中的++pDest保留在其中)。

您可能已将纹理指定为PF_R8G8B8,但似乎Ogre3D对缓冲区中图像数据的布局有一定的自由度,实际上图形驱动程序在纹理的内存布局方面也有一些自由度。通常,32位RGBA或BGRA图像比24位RGB具有一些优势。

它还可能取决于Ogre3D使用的底层图形API(D3D或GL)以及那里的标准。例如,在GL中,您无法直接映射纹理内存,需要使用PBO,其内存布局可以选择与纹理不同。我不知道D3D,但我认为D3D特别喜欢BGRA布局。

编辑:您还可以查看pixelBox.format以查看数据的格式。

答案 1 :(得分:1)

我遇到了同样的问题。

您创建的纹理格式为Ogre::PF_R8G8B8,但Ogre使用的实际硬件缓冲区仍然是Ogre::PF_R8G8B8A8,这意味着它是4位而不是3位。

您可以在循环中添加另一行:

pDest++;