4
\$\begingroup\$

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?

glEnable(GL_TEXTURE_2D);
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

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?

\$\endgroup\$
2
  • \$\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
    Commented Nov 21, 2015 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\$
    – Lucien
    Commented Nov 21, 2015 at 11:22

1 Answer 1

4
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for giving me the answer I wanted as well as the one I needed! \$\endgroup\$
    – Lucien
    Commented Nov 21, 2015 at 17:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .