получить неправильный RGB при создании динамической текстуры в OGRE - PullRequest
3 голосов
/ 18 ноября 2011

Привет, у меня проблема, когда я пытаюсь создать динамическую текстуру для назначения в качестве фона в моем окне людоедов. Я хочу назначить значения динамически для каждого пикселя текстуры, а затем я использую эту текстуру в качестве фона. Я использую этот код для создания динамической текстуры.

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 ]

1 голос
/ 07 октября 2012

Я встречал такую ​​же проблему, как эта.

Текстура, которую вы создали, была в формате Ogre::PF_R8G8B8, но фактический аппаратный буфер, который использует Ogre, по-прежнему Ogre::PF_R8G8B8A8, что означает, что это 4 бита, а не 3 бита.

Вы можете добавить еще одну строку в ваш цикл:

pDest++;
1 голос
/ 18 ноября 2011

Согласно комментарию Кристофера:

У меня нет опыта работы с Ogre3D, но может быть так, что он на самом деле дает вам данные изображения в виде RGBA (или BGRA, или ARGB) вместо просто RGB. Таким образом, вы пропускаете дополнительные pDest++ (или, может быть, *pDest++ = 255), и, следовательно, в первом взаимодействии цикла вы получаете синий, зеленый, красный, а затем синий, ..., который как-то совпадет с вашим изображением.

РЕДАКТИРОВАТЬ: В своем комментарии вы говорите (если я правильно понял), что вы получаете совершенно красное изображение, когда добавляете в цикл дополнительные ++pDest. По крайней мере, это говорит нам о том, что вы действительно получаете 4-компонентное изображение от Ogre3D, поскольку мы больше не синхронизированы с цветами и имеем только один цвет. Но так как этот цвет красный, кажется, Ogre3D предоставляет вам данные изображения в виде BGRA. Так что просто установите первый компонент на 255 вместо третьего (и, конечно, оставьте там этот дополнительный ++pDest).

Возможно, вы указали текстуру как PF_R8G8B8, но, похоже, у Ogre3D есть некоторая свобода в отношении размещения данных изображения в буфере, и на самом деле графический драйвер также имеет некоторую свободу относительно расположения в памяти текстур и часто 32-битное изображение RGBA или BGRA имеет некоторые преимущества по сравнению с 24-битным RGB.

Это также может зависеть от того, какой базовый графический API (D3D или GL) используется Ogre3D и какой там стандарт. Например, в GL вы не можете напрямую отображать текстурную память и для этого нужно использовать PBO, чья компоновка памяти, в свою очередь, может быть выбрана отличной от текстуры. Я не знаю о D3D, но я думаю, что D3D особенно нравится макет BGRA.

РЕДАКТИРОВАТЬ: Вы также можете проверить pixelBox.format, чтобы увидеть, какой формат имеют данные.

...