0
votes

My problem is, that I can't read the values, stored in a texture which has only a red component correctly. My first implementation caused a buffer overflow. So I read the openGL reference and it says:

If the selected texture image does not contain four components, the following mappings are applied. Single-component textures are treated as RGBA buffers with red set to the single-component value, green set to 0, blue set to 0, and alpha set to 1. Two-component textures are treated as RGBA buffers with red set to the value of component zero, alpha set to the value of component one, and green and blue set to 0. Finally, three-component textures are treated as RGBA buffers with red set to component zero, green set to component one, blue set to component two, and alpha set to 1.

The first confusing thing is, that the nvidia implementation packs the values tight together. If I have four one byte values I only need four bytes space, not 16. So I read the openGL specification and it told me on page 236 in table 8.18 the same, except that a two component texture stores it second value not in the alpha channel, but in the green channel, which makes also more sense for me. But which definition is correct?

It also says:

If format is a color format then the components are assigned among R, G, B, and A according to table 8.18[...]

So I ask you: "What is a color format?" and "Is my texture data tight packed if the format is not a color format"? My texture is defined like this: type: GL_UNSIGNED_BYTE format: GL_RED internalformat: GL_R8

Another thing is that when my texture has a size of two times two pixels the first two values are being saved in the first two bytes, but the other two values in the fith and sixth bytes of my buffer. The two bytes in between are padding. So I got the "GL_PACK_ALIGNMENT" state and it says four bytes. How can that be?

The GetTexImage call:

std::vector<GLubyte> values(TEXTURERESOLUTION * TEXTURERESOLUTION);

GLvoid *data = &values[0];//values are being passed through a function which does that

glBindTexture(GL_TEXTURE_2D, TEXTUREINDEX);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
1
Can you show your glGetTexImage() call? Particularly the format/type arguments are important.Reto Koradi

1 Answers

0
votes

The first confusing thing is, that the nvidia implementation packs the values tight together.

That is exactly what should to happen. The extension to 2, 3 or 4 components is only relevant when you actually read back with GL_RG, GL_RGB or GL_RGBA formats (and the source texture hass less components. If you just aks for GL_RED you will also only get GL_RED

[...] except that a two component texture stores it second value not in the alpha channel, but in the green channel, which makes also more sense for me. But which definition is correct?

The correct definition is the one in the spec. The reference pages have often small inaccuracies or omissions, unfortunately. In this case, I think the reference is just outdated. The description matches the old and now deprecated GL_LUMINANCE and GL_LUMINANCE_ALPHA formats for one and two channels, repsectively, not the modern GL_RED and GL_RG ones.

So I ask you: "What is a color format?"

A color format is one for color textures, in contrast to non-color formats like GL_DEPTH_COMPONENT or GL_STENCIL_INDEX.

Concerning your problem with GL_PACK_ALIGNMENT: The GL behaves exactly as it is intended to behave. You have a 2x2 texture and GL_PACK_ALIGNMENT of 4, which means that data will be padded at each row so the distance from one row tow the next will be a multiple of 4. So you will get the first row tightly packed, 2 padding bytes, and finally the second row.