Forum

OpenGL Mistakes - GL_RGB

Discuss programming topics that involve the OpenGL API.

Moderator: InsideQC Admins

OpenGL Mistakes - GL_RGB

Postby mh » Mon Oct 04, 2010 8:50 am

It's common to see use of the GL_RGB format when specifying textures, and I assume that the author's intention is to save memory by not using a fourth component if the texture only needs 3.

But OpenGL doesn't actually work that way.

Let's look at the documentation so that we know what's going on (novel concept, that ;) )

http://www.opengl.org/sdk/docs/man/xhtm ... mage2D.xml
Each element is an RGB triple. The GL converts it to floating point and assembles it into an RGBA element by attaching 1 for alpha.
and
The last three arguments describe how the image is represented in memory; they are identical to the pixel formats used for glDrawPixels.

And glDrawPixels says: http://www.opengl.org/sdk/docs/man/xhtm ... Pixels.xml
Each pixel is a three-component group: red first, followed by green, followed by blue; for GL_BGR, the first component is blue, followed by green and then red. Each component is converted to the internal floating-point format in the same way the red, green, and blue components of an RGBA pixel are. The color triple is converted to an RGBA pixel with alpha set to 1. After this conversion, the pixel is treated as if it had been read as an RGBA pixel.

So the end result of the noble attempt to save memory not only doesn't save memory at all, but actually slows the program down by forcing OpenGL to expand 3 component textures to 4 components before it can use them.

In other words, GL_RGB (or any other 3 component format, for that matter) is evil. Don't do it.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby andrewj » Mon Oct 04, 2010 11:13 am

It seems unlikely to me that 3D cards are going to waste precious texture memory on color channels which are not needed.

Do you have any benchmarks which show that using GL_RGB is actually slower than using GL_RGBA?
andrewj
 
Posts: 133
Joined: Mon Aug 30, 2010 3:29 pm
Location: Australia

Postby Spike » Mon Oct 04, 2010 11:44 am

32bit rgba is bus aligned, rgb is not. that means that if that particular texture is stored in system ram instead of video ram, its much faster to access. keeping things aligned is not only faster, but its also cheaper and more reliable too.
There were benchmarks elsewhere on this site mostly centered on lightmaps.

Actually, its BGRA (by byte) which is fastest. RGBA still requires a conversion.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Mon Oct 04, 2010 1:00 pm

andrewj wrote:It seems unlikely to me that 3D cards are going to waste precious texture memory on color channels which are not needed.

Do you have any benchmarks which show that using GL_RGB is actually slower than using GL_RGBA?

Depends on how you define "waste" - I prefer the word "use" in this kind of scenario. ;)

Even worse to waste precious cycles converting from an unaligned format to an aligned one, isn't it?

Benchmark:
Code: Select all
void R_CheckTexMode (void)
{
   int i;
   GLuint texnums[16];

   glGenTextures (16, texnums);

   glFinish ();
   Uint32 start = SDL_GetTicks ();

   for (i = 0; i < 16; i++)
   {
      glBindTexture (GL_TEXTURE_2D, texnums[i]);
      glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, sibuffer);
   }

   glFinish ();
   Uint32 end = SDL_GetTicks ();
   printf ("GL_RGB: %i ms\n", (end - start));

   glDeleteTextures (16, texnums);
   glGenTextures (16, texnums);

   glFinish ();
   start = SDL_GetTicks ();

   for (i = 0; i < 16; i++)
   {
      glBindTexture (GL_TEXTURE_2D, texnums[i]);
      glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, sibuffer);
   }

   glFinish ();
   end = SDL_GetTicks ();
   printf ("GL_RGBA: %i ms\n", (end - start));

   glDeleteTextures (16, texnums);
   glGenTextures (16, texnums);

   glFinish ();
   start = SDL_GetTicks ();

   for (i = 0; i < 16; i++)
   {
      glBindTexture (GL_TEXTURE_2D, texnums[i]);
      glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, sibuffer);
   }

   glFinish ();
   end = SDL_GetTicks ();
   printf ("GL_BGRA: %i ms\n", (end - start));

   glDeleteTextures (16, texnums);
}

GL_RGBA is between 1.5 and 2.5 times faster than GL_RGB, GL_BGRA is between 5 and 8 times faster than GL_RGB.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby leileilol » Mon Oct 04, 2010 7:52 pm

What about paletted textures?
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Postby mh » Mon Oct 04, 2010 9:29 pm

leileilol wrote:What about paletted textures?


Unlikely to be supported in hardware: http://www.opengl.org/registry/specs/EX ... exture.txt

Intel 810/815.

Mesa.

Microsoft software OpenGL implementation.

Selected NVIDIA GPUs: NV1x (GeForce 256, GeForce2, GeForce4 MX,
GeForce4 Go, Quadro, Quadro2), NV2x (GeForce3, GeForce4 Ti,
Quadro DCC, Quadro4 XGL), and NV3x (GeForce FX 5xxxx, Quadro FX
1000/2000/3000). NV3 (Riva 128) and NV4 (TNT, TNT2) GPUs and NV4x
GPUs do NOT support this functionality (no hardware support).
Future NVIDIA GPU designs will no longer support paletted textures.

S3 ProSavage, Savage 2000.

3Dfx Voodoo3, Voodoo5.

3Dlabs GLINT.

(My emphasis).

They're a completely different case anyway, as is any other 1-component texture (GL_LUMINANCE, etc). I haven't benchmarked them.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby leileilol » Mon Oct 04, 2010 11:13 pm

mh wrote:
leileilol wrote:What about paletted textures?


Unlikely to be supported in hardware

Fortunately, Nvidia hardware isn't everything. They probably GL_RGBA anything indexed on-load anyhow
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Postby mh » Mon Oct 04, 2010 11:18 pm

leileilol wrote:Fortunately, Nvidia hardware isn't everything. They probably GL_RGBA anything indexed on-load anyhow

Nor is a Savage 3D running in a P 90 (with 16 MB RAM). ;)

So try this for size then: http://www.opengl.org/wiki/Common_Mista ... d_textures

Do not use the GL_EXT_paletted_texture extension. Support for it has been dropped by the major GL vendors.


So not supported on either NVIDIA or ATI, which does mean that on the majority of 3D cards that the majority of people have they're not supported.

Of course it's not "everything" still, but at the same time it's close enough to "everything" to be a workable rule of thumb for most practical purposes.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby andrewj » Tue Oct 05, 2010 1:34 am

mh wrote:Even worse to waste precious cycles converting from an unaligned format to an aligned one, isn't it?

Why do you assume a conversion? I don't know anything about how 3D hardware works under the hood, but it seems possible that RGB data could be used directly from texture memory, or the conversion could be done without cost while uploading the image data to the card.

GL_RGBA is between 1.5 and 2.5 times faster than GL_RGB, GL_BGRA is between 5 and 8 times faster than GL_RGB.

Wow that's..... surprising.
andrewj
 
Posts: 133
Joined: Mon Aug 30, 2010 3:29 pm
Location: Australia

Postby mh » Tue Oct 05, 2010 8:46 am

andrewj wrote:
mh wrote:Even worse to waste precious cycles converting from an unaligned format to an aligned one, isn't it?

Why do you assume a conversion?

Because the spec and the documentation says so.

Check the links in my first post for the documentation. The spec for all of the glTexImage functions says:
The selected groups are processed exactly as for DrawPixels, stopping just before final conversion. Each R, G, B, A, or depth value so generated is clamped to [0, 1].

And:
Each group is converted to a group of 4 elements as follows: if a group does not contain an A element, then A is added and set to 1.0. If any of R, G, or B is missing from the group, each missing element is added and assigned a value of 0.0.

andrewj wrote:...the conversion could be done without cost while uploading the image data to the card.

This is pretty much what I mean. There's no runtime impact here for most standard textures, but be aware that the conversion is done and that you're not saving memory at all. It's not without cost though; the trade-off is much slower texture loading, and therefore much slower map loading.

There is however runtime impact if you're subsequently modifying a texture as the conversion will need to be done at runtime too.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Entar » Tue Oct 05, 2010 9:13 pm

I hope there will be more in this "OpenGL Mistakes" series :)
User avatar
Entar
 
Posts: 439
Joined: Fri Nov 05, 2004 7:27 pm
Location: At my computer

Postby frag.machine » Tue Oct 05, 2010 9:27 pm

Entar wrote:I hope there will be more in this "OpenGL Mistakes" series :)


I'd call it "best practices" than "mistakes" :)
But nonetheless, good stuff mh. Bring on it!
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Postby goldenboy » Sat Oct 09, 2010 5:48 pm

Pretty amazing stuff mh.

The inner workings of openGL and how you can extract fps from them.
User avatar
goldenboy
 
Posts: 924
Joined: Fri Sep 05, 2008 11:04 pm
Location: Kiel


Return to OpenGL Programming

Who is online

Users browsing this forum: No registered users and 1 guest