I have executed the following command in order to store a texture (PNG) file in a C++ header file: xxd -i Texture.png Texture.h.

How would I go about loading this texture into OpenGL?

GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);

I realise that the function glTexImage2D should be used but am very unsure about which parameters to choose.

The specification describes the parameters as shown below.

void glTexImage2D(GLenum target, // GL_TEXTURE_2D
    GLint level, // 0
    GLint internalFormat, // GL_RGBA
    GLsizei width, // 2048
    GLsizei height, // 2048
    GLint border, // 0
    GLenum format, // What's this?
    GLenum type, // What's this?
    const GLvoid * data);

What are the format and type parameters for and what should they be set to in this case?

  • \$\begingroup\$ PNG is an image file format with headers, compression, etc.; glTexImage2D needs image data (array of color values), not an image file like PNG. You'll need a PNG loading function that can take a PNG file format and convert it into an array of colors. The format/type parameters for glTexImage2D will be the format of that array. \$\endgroup\$ – amitp Nov 21 '15 at 11:02
  • \$\begingroup\$ @amitp, ah, how would I go about pre-converting this into an array? I thought that the xxd command did that but have now found that it's just a hex dump of the file's data. \$\endgroup\$ – Lolums Nov 21 '15 at 11:22

Normally you would load your images on-the-fly from a normal file then pass the decompressed pixels to OpenGL, but I'm also fond of embedding resources into the executable :). For an extreme example, see my PS2 game. The whole thing consists of a single 4 Megabytes executable, all assets built-in.

What I did, and you can also take the same approach if you want, is:

  • Dump the binary contents of an image file (PNG, JPEG, etc) into a C-style array that you can compile with the rest of the application. You can write a simple tool to do that quite easily if you want. I use bin2c, which is pretty good and free.

  • You still need to decompress your image data to raw RGB[A] pixels for OpenGL. A good public domain, single-file library that you can use is STB Image.

  • Then just pass the address of the data array that was embedded with the help of bin2c to STB Image and the library will decompress the data and return a new pointer to the pixels that you can pass to OpenGL.

This is a viable setup for limited amounts of data, but very impractical for larger projects. Each time you change an image you have to do the whole cycle of bin2c -> recompile. It's fun as an experiment, but I can tell from own experience that near half way through the project I mentioned above I was regretting my choice of embedding everything, but in that specific case I had to do it due to external factors.

  • \$\begingroup\$ Thanks for giving me the answer I wanted as well as the one I needed! \$\endgroup\$ – Lolums Nov 21 '15 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.