I have done some stuff with OpenGL and OpenGL ES in the past. I generally tried to stick with fixed function pipeline; I never had good reasons to dig deeply into features provided post-GL1.4 (most of the time, GL1.1) and OpenGL ES 1.x. So the client for an MMORPG I worked on (both the 2D and 3D) did not need anything more. Nor did the simplistic unfinished spacesim. Neither did the zombie squishing game for iPhone.
For a few months now, I’ve had access to one of the “major league” game engines (which shall remain unnamed for now!), so I had to expand my knowledge a bit. I didn’t succeed as much as I should have, but here are a few interesting things I have learned.
They may be obvious, but I’ve only learned about them very recently. And it wasn’t trivial to figure them out exactly, at least based on queries I typed in Google. “What does this OpenGL feature do and how do I put it into OpenGL ES?”
Internal texture formats
We all know the incantation:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
So I knew there was talk about the first
GL_RGBA involving an “internal format”, and the second
GL_UNSIGNED_BYTE specified how the
textureData argument was, well, formatted. If we replaced them with
GL_RGB, we’d drop the alpha from the image. But what did all that mean?
Yesterday I ran into
GL_RGB565, and more. These can be passed as the first argument, and determine how the desktop OpenGL implementation will store the texture. If you pass
GL_RGB, you’re letting the implementation determine the optimal pixel component size in bits. If you get more detailed, you get more strict about the internal format you want the implementation to use for the pixels you passed.
Today I dug into a document I ran into yesterday, from 2007, which discussed that with OpenGL ES the implementation gets to decide, and tries to honor the
internalFormat argument based on the
GL_BGRA is an extension
On desktop, it got promoted to core OpenGL. On OpenGL ES, it’s called
GL_HALF_FLOAT_OES does exist on OpenGL ES.
Protip: you do want to look into headers, especially the extension header (
gl2ext.h or such), whenever you can’t find if something exists and you’re sure it should.
What the hell is
GL_UNSIGNED_INT_8_8_8_8_REV? How does it relate to
This is strictly as far as I understand it! My understanding may be wrong and I would love it if someone clarified this in the comments! (For reference, the APPLE_packed_pixels extension talks about these.)
Once again, I may be wrong. Read the above links.
Alright, so let’s imagine you passed the source format of
GL_BGRA in combination with the above. You’re specifying that the data you have passed has actually not been stored in the
BGRA order — but in the reverse. That’s what
REV means. Reverse. So you’re telling OpenGL you’re actually passing a texture stored in the
Notably, that doesn’t exist in OpenGL ES 2.0, so one may end up using
GL_UNSIGNED_SHORT_4_4_4_4_REV. Without actually playing with that, I suspect that would mean also having to pass data with 16 bits per pixel, which kind of defeats the purpose of not having to convert
ARGB textures. You could bake the data at build time, sure, but still…
Just red, just red and green
GL_R* formats. For example,
GL_R8. Yip yip.
Of course, I learned even more things. And I didn’t dig into everything I want to know (what’s
GL_LUMINANCE_ALPHA as a texture format, and why do I want to use that?).
Less than a week before I start the new job. Looking forward to spending some of the remaining time after my Wednesday trip on studying some of the interesting things such as these OpenGL features…