Pixel Format overridden when populating Dynamic Texture

Problems building or running the engine, queries about how to use features etc.
Post Reply
pietroro
Gnoblar
Posts: 2
Joined: Thu Mar 25, 2021 11:22 am

Pixel Format overridden when populating Dynamic Texture

Post by pietroro »

Hello everyone,

I have been trying to implement a dynamic texture that displays a series of images on a 2D plane. Images come in very quickly, so my implementation has to be as fast as possible.

What I decided to do is to directly modify the texture's buffer, taking inspiration from the dynamic texture tutorial and these code snippets shared from artoolkit.

This is how I defined my Dynamic texture:

Code: Select all

image_texture_ = texture_manager.createManual("DynamicImageTexture",
        resource_group_name, 
        Ogre::TEX_TYPE_2D,
        width_, height_, 0, 
        Ogre::PF_BYTE_RGB, 
        Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
As you can see I set the Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE and Ogre::HardwareBuffer::HBL_DISCARD flags to make the update as fast as possible.
And this is how I update it, by copying over the section of memory that contains the incoming image:

Code: Select all

{
        Ogre::HardwarePixelBufferSharedPtr buffer = image_texture_->getBuffer(0,0);
        buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
        const Ogre::PixelBox &pb = buffer->getCurrentLock();
        uchar *data = static_cast<uchar*>(pb.data);
        // Copy the data
        memcpy(
            (uchar*)pb.data,
            (uchar*)&image->data[0],
            image->data.size()
            );
        buffer->unlock();
}
However I have to assume that the images might come in with a variable encoding. I set the PF_BYTE_RGB only initially for testing. Eventually I will change it so that the Pixel Format matches the encoding of the image data buffer.

However I have noticed that while Ogre asks you explicitly what kind of format the pixels should have, it completely disregards this information in favor of an internally defined "standard". Encoding detection won't matter if Ogre doesn't listen to me when I try to tell it how to read the data.

In my code I ask for an Ogre::PF_BYTE_RGB pixel format, but when I query the pixel buffer on its format it tells me it's Ogre::PF_A8R8G8B8, no matter what I specify. This behavior is confirmed here and here.

My questions are:
  • How can I avoid the Pixel Format from being overridden and actually correctly interpreting the data I give?
  • Can I do that without loosing much of the performance improvement given by the usage of dynamic textures?
Thank you very much for your time, your help is greatly appreciated.
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: Pixel Format overridden when populating Dynamic Texture

Post by paroj »

pietroro wrote: Thu Mar 25, 2021 12:52 pm How can I avoid the Pixel Format from being overridden and actually correctly interpreting the data I give?
you cant. Quoting the API docs:
The internal format you wish to request; the manager reserves the right to create a different format if the one you select is not available in this context.
which means your hardware does not support BYTE_RGB and your data must be unpacked somewhere.Ogre can do that for you if you use blitFromMemory
see https://ogrecave.github.io/ogre/api/lat ... el-Buffers
pietroro
Gnoblar
Posts: 2
Joined: Thu Mar 25, 2021 11:22 am

Re: Pixel Format overridden when populating Dynamic Texture

Post by pietroro »

Thanks for your swift reply. I was already working on a blitFromMemory-based alternative, but it seems like it's slower than what I had working before.
paroj wrote: Thu Mar 25, 2021 2:46 pm hardware does not support BYTE_RGB
Is it 100% a hardware problem or could it be outdated OpenGL software? Is there a way to get a list of all Pixel Formats supported by the current configuration?
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: Pixel Format overridden when populating Dynamic Texture

Post by paroj »

you have to query each format you are interested in via:
https://ogrecave.github.io/ogre/api/lat ... 6f85b64235

but.. since Ogre 1.10, it PF_BYTE_RGB should always work on OpenGL
but.. it probably is still unpacked along the way by the OpenGL driver
but.. the driver may have a faster implementation than what you or Ogre is doing.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Pixel Format overridden when populating Dynamic Texture

Post by dark_sylinc »

Nearly all GPUs don't support 24-bit RGB.

Sooner or later it must be converted to 32-bit RGBA, whether inside the driver or before. If the (uncompressed) pixel format isn't multiple of 4 bytes (or is 1 or 2 bytes in size) then chances are the format won't be supported by the HW.
pietroro
Gnoblar
Posts: 2
Joined: Thu Mar 25, 2021 11:22 am

Re: Pixel Format overridden when populating Dynamic Texture

Post by pietroro »

I queried most formats and it seems that the only ones that get overridden are indeed the 4-byte ones.

As far as converting the one pixel format to the other I tried both blit-ing the sections of memory and using PixelUltil's bulkPixelConversion function.

Unfortunately they both seem significantly slower than just running OpenCV to create a temporary copy of the source memory. Does that even make sense? I would have guessed that the internal OGRE methods for copying sections of memory would have been a lot faster
paroj wrote: Thu Mar 25, 2021 3:42 pm but.. since Ogre 1.10, it PF_BYTE_RGB should always work on OpenGL
Does that mean there is no way to leverage that Pixel Format?
dark_sylinc wrote: Thu Mar 25, 2021 7:05 pm Sooner or later it must be converted to 32-bit RGBA, whether inside the driver or before
I understand that it might be easier for the GPU to only deal with formats of a certain type. I am fairly convinced however that OpenGL's internal conversions are by far faster than what I (or OGRE for that matter) might implement. Why even allow for an RGB pixel format in that case?

OpenGL mentions how "components not stored by the image format are filled in automatically"
. Does OGRE provide a way for me to tell OpenGL to fill those values automatically?

Again, thanks a lot for your time, I'm just trying to make sense of all this
Last edited by pietroro on Wed Mar 31, 2021 3:27 pm, edited 1 time in total.
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: Pixel Format overridden when populating Dynamic Texture

Post by paroj »

pietroro wrote: Wed Mar 31, 2021 3:26 pm I queried most formats and it seems that the only ones that get overridden are indeed the 4-byte ones.

As far as converting the one pixel format to the other I tried both blit-ing the sections of memory and using PixelUltil's bulkPixelConversion function.

Unfortunately they both seem significantly slower than just running OpenCV to create a temporary copy of the source memory. Does that even make sense? I would have guessed that the internal OGRE methods for copying sections of memory would have been a lot faster
OpenCV provides probably the most optimized pixel conversion routines, even optionally leveraging OpenCL. The Ogre methods on the other hand - while decently optimized - are rather meant as a fallback to get your stuff on the GPU.
pietroro wrote: Wed Mar 31, 2021 3:26 pm
paroj wrote: Thu Mar 25, 2021 3:42 pm but.. since Ogre 1.10, it PF_BYTE_RGB should always work on OpenGL
Does that mean there is no way to leverage that Pixel Format?
not unless you update to Ogre >= 1.10.3.
Post Reply