4

I would like to save memory and since input data are in range [0,..,255] i don't need 4xFloat but 4xByte is going to be enough. GLSL and gpu don't like bytes so pack and unpack is required. Also no precision loss should occur.

C++ and packing code:

The fastest and simplest solution should be using uint for transfer. GLM has already vector prepared so putting glm::u8vec4(1, 1, 1, 1) into vertex array should be all right. I checked vertex arrays with gDEBugger so i am sure they contains right data. VAP looks like this:

glVertexAttribPointer( 0, 1, // one element GL_UNSIGNED_INT, //transfer data type GL_FALSE, //dont normalize 1 * sizeof(GLuint), // size of one element (void*)0 // offset ); 

GLSL and unpacking:

layout(location = 0) in uint data; vec4 unpack; unpack.x = float((data & uint(0xff000000)) >> 24); unpack.y = float((data & uint(0x00ff0000)) >> 16); unpack.z = float((data & uint(0x0000ff00)) >> 8); unpack.w = float((data & uint(0x000000ff)) >> 0); 

Result should provide hint but it's too much mess. result

Edit:

Even tho my solution is pointless, there are two bugs. First as mentioned below i have to use glVertexAttribIPointer. Second in my case shifts were mirrored(X should be shifted by 0, Y by 8,..).

Proper solution looks like this:

glVertexAttribPointer( 0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4 * sizeof(GLubyte), (void*)0 ); shader: layout(location = 0) in vec4 data; 

2 Answers 2

3

GLSL and gpu don't like bytes so pack and unpack is required. Also no precision loss should occur.

Why do you say that? Using GL_UNSIGNED_BYTE attribute data is well-supported and very common (e.g. for colors). There is no performance issue with that (as long as one adheres to basic alignment rules).

The GL will automatically convert integer attribute data to float. The normalized parameter defines if the data shall be normalized to the [0,1] (or [-1,1] for signed int types) range, or if it shall be converted directly to float, so that (GLubyte)255 will appear as 255.0f in the shader.

Your code fails because you need to use glVertexAttribIPointer() (note the I there) to set up integer attributes. But in your case, it really is a pointless exersice.

Sign up to request clarification or add additional context in comments.

1 Comment

Well thats that. Since i couldn't find byte in shader i assumed... Thanks for glVertexAttribIPointer() and GL_UNSIGNED_BYTE.
1

Your C++ code is correct, but you can also use the glVertexAttribIPointer (I stands for Integer?). The last two values can be zero/nullptr, as there is only one value in the buffer. All parameters are meant for the currently bound buffer, except for the first one which applies to the currently bound VAO.

glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, 0, nullptr); 

The OpenGL shader code should look like:

layout(location = 0) in uint data; out vec4 color // I assume you want this to go 'out'? void main() { color = vec4( data & uint(0xFF000000), data & uint(0x00FF0000), data & uint(0x0000FF00), data & uint(0x000000FF)); } 

Now you can store rgba values in the uint. Such as: 0xRRGGBBAA, supplying you for 256 values for every part.

1 Comment

Don't you also have to bitshift the resulting values from the bitmask? Otherwise your values will be really high.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.