Really basic problem with glTexImage2D

This works:

unsigned char image_data[4] = {0, 255, 0, 255}; // red
glGenTextures(1, &tex_obj);
glBindTexture(GL_TEXTURE_2D, tex_obj);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);

This does NOT work:

unsigned char image_data[16] = {0, 0, 150, 255, 125, 0, 0, 255, 0, 0, 150, 255, 125, 0, 0, 255};
glGenTextures(1, &tex_obj);
glBindTexture(GL_TEXTURE_2D, tex_obj);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);

It just produces white, as if no texture exists. What has gone wrong? Is 1x1 possible but 2x2 impossible?

Using an incomplete mipmap is a very common mistake.

So how do I fix it? There is no alternate code sample or explanation that I can see…

OpenGL Mipmap Completeness

You have two options here: either specify a complete mipmap chain for your second texture, or disable mipmapping for it.

For a complete mipmap chain, if the top-level mip (level 0) is a 2x2 image, then you need to also specify a level 1 mip at half the resolution, i.e. 1x1.

To disable mipmapping, use glTexParameter with GL_TEXTURE_MIN_FILTER set to one of the values that doesn’t include MIPMAP, or an appropriate sampler object.

So glTexParameri (or f?) with the texture ID and GL_TEXTURE_MIN_FILTER and … what for param?? I m very new with this particular set of parameters, sorry…

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

The third argument could be GL_LINEAR instead, but it can’t be any of the options with _MIPMAP_ in the name unless you’ve defined all of the mipmap levels.

Having the initial setting as GL_NEAREST_MIPMAP_LINEAR was arguably a mistake, but it’s been that way since the beginning so we’re stuck with it.

In OpenGL 3.0 or later, you can use glGenerateMipmap to generate the additional levels automatically. In older versions, you can use gluBuild2DMipmaps instead of glTexImage2D, which automatically generates the mipmap levels and also scales the data to meet system requirements (early versions of OpenGL only supported power-of-two dimensions and didn’t guarantee support for textures larger than 64×64).

GL_NEAREST or GL_LINEAR both still give me plain white polys. Do any of these settings influence it (I tried toggling a few on and off…):
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_TEXTURE_2D); // Enable Texture mapping
glShadeModel(GL_SMOOTH); // Enables Smooth Shading
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Enable Alpha Blending (disable alpha testing)
glEnable(GL_BLEND);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

Did you call glTexParameter while the texture was bound? It affects the texture bound to the specified target (GL_TEXTURE_2D in this case), so if you call it before binding the texture or after unbinding it, it won’t work.

No.

Houston, we have lift-off!

Thanks, the right sequence made it work. Now I just have to put it to good use!

Follow-up qiestion: How do I make the colors not blend together, but form large “pixels”? Right now, no matter what parameter I seem to change, it gives me a very sooth transition between texture pixel colors, and it looks very wrong, for the intended purpose!

Use GL_NEAREST, not GL_LINEAR.

GL_NEAREST uses the colour of the closest texel, GL_LINEAR interpolates between the colours of the 4 closest texels.

I thought so, too, but they seem to do the exact same?

You also need:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Note the difference: GL_TEXTURE_MAG_FILTER specifies the filtering mode to apply when the texture image is magnified, whereas GL_TEXTURE_MIN_FILTER specifies the filtering mode to apply when the texture image is minified. GL_TEXTURE_MIN_FILTER can also, optionally, specify a filtering mode to apply for transitions between miplevels.

It’s common in both sample and production code that if one is set, the other is also set at the same time, and the texture must be bound first.

Thank you, it works! There are some slight color glitches along the edges, but all in all, it works!