Packing/Unpacking vertex information.

I am trying to send this vertex across to the pipeline:


struct Vertex {
	GLuint x : 5;
	GLuint y : 6;
	GLuint z : 5;

	GLuint orient : 3;
	GLuint scale : 5;
	GLuint tex : 8;
};

The size of this vertex is 4 bytes and this snippet returns the contents of x as expected:


Vertex v1;
v1.x = 23;
return ( ( ( *( GLuint * ) &v1 ) >> 0 ) & 31 );

I setup the attribute pointer as such:


glVertexAttribPointer( 0, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof( GLuint ), BUFFER_OFFSET( 0 ) );

Full setup:


glGenVertexArrays( 1, &id_vao );

glGenBuffers( 1, &id_vbo );
glGenBuffers( 1, &id_ibo );
glGenBuffers( 1, &id_cmd );

glGenBuffers( 1, &id_mats_model );
glGenBuffers( 1, &id_mats_norm );

// Some size vars
std::cout << "Size of vertex: " << sizeof( Vertex ) << std::endl;
GLuint size_bytes_vbo = size_vbo_block * num_vbo_blocks * sizeof( Vertex );
printf( "
Size vertices buffer: %f
", size_bytes_vbo / 1024.0f / 1024.0f );
GLuint size_bytes_ibo = size_ibo_block * num_ibo_blocks * sizeof( GLuint );
printf( "
Size indices buffer: %f
", size_bytes_ibo / 1024.0f / 1024.0f );

float size_mb_total = ( size_bytes_ibo + size_bytes_vbo ) / 1024.0f / 1024.0f;

printf( "
Size total: %f
", size_mb_total );

// Allocate Space
glBindBuffer( GL_ARRAY_BUFFER, id_vbo );
glBufferData( GL_ARRAY_BUFFER, size_bytes_vbo, nullptr, GL_STATIC_DRAW );

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, id_ibo );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, size_bytes_ibo, nullptr, GL_STATIC_DRAW );

// Setup the VAO pointers
glBindVertexArray( id_vao );

// Enable attributes
for( GLuint i = 0; i < 9; ++i ) { 
	glEnableVertexAttribArray( i );
}

// Setup vertex buffer pointers
glBindBuffer( GL_ARRAY_BUFFER, id_vbo );

glVertexAttribPointer( 0, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof( GLuint ), BUFFER_OFFSET( 0 ) );

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, id_ibo );

glBindBuffer( GL_DRAW_INDIRECT_BUFFER, id_cmd );

glVertexAttribIPointer( 1, 1, GL_UNSIGNED_INT, sizeof( SMCommand ), BUFFER_OFFSET( 4 * sizeof( GLuint ) ) );
glVertexAttribDivisor( 1, 1 );

glBindBuffer( GL_ARRAY_BUFFER, id_mats_model );
glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 16, BUFFER_OFFSET( 0 ) );
glVertexAttribDivisor( 2, 1 );
glVertexAttribPointer( 3, 4, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 16, BUFFER_OFFSET( sizeof( GLfloat ) * 4 ) );
glVertexAttribDivisor( 3, 1 );
glVertexAttribPointer( 4, 4, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 16, BUFFER_OFFSET( sizeof( GLfloat ) * 8 ) );
glVertexAttribDivisor( 4, 1 );
glVertexAttribPointer( 5, 4, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 16, BUFFER_OFFSET( sizeof( GLfloat ) * 12 ) );
glVertexAttribDivisor( 5, 1 );

glBindBuffer( GL_ARRAY_BUFFER, id_mats_norm );
glVertexAttribPointer( 6, 3, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 9, BUFFER_OFFSET( 0 ) );
glVertexAttribDivisor( 6, 1 );
glVertexAttribPointer( 7, 3, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 9, BUFFER_OFFSET( sizeof( GLfloat ) * 3 ) );
glVertexAttribDivisor( 7, 1 );
glVertexAttribPointer( 8, 3, GL_FLOAT, GL_FALSE, sizeof( GLfloat ) * 9, BUFFER_OFFSET( sizeof( GLfloat ) * 6 ) );
glVertexAttribDivisor( 8, 1 );

glBindVertexArray( 0 );

The vertex shader:


layout( std140 ) uniform mvp_matrices {
	vec4 pos_camera;
	mat4 mat_world;
	mat4 mat_perspective;
	mat4 mat_ortho;
	mat4 mat_view;
	float time_game;
};

layout( location = 0 ) in uint data;
layout( location = 1 ) in uint id;
layout( location = 2 ) in mat4 mat_model;
layout( location = 6 ) in mat3 mat_norm;

//out vec3 frag_uvs;
//out vec4 frag_color;

void main() {
	vec4 pos;
	uint orient;
	uint scale;
	uint tex;

	pos.x = float( ( data.x >> 0 ) & 31 );
	pos.y = float( ( data.x >> 5 ) & 63 );
	pos.z = float( ( data.x >> 11 ) & 31 );
	pos.w = 1;
	 
	gl_Position = mat_perspective * mat_view * mat_model * pos;
}

My triangles are completely messed up… The values I supply to Vertex are within 0-31 for x/z and 0-63 for y.

glVertexAttribPointer is used to feed floating-point attributes. If you want to feed an integer attribute, you must use glVertexAttribIPointer.

Using GL_UNSIGNED_INT, unnormalized, with glVertexAttribPointer tells the system to cast the integer into a float, as if you did it with a C++ cast. So 256 as an integer would become 256.0f. That’s useful on occasion, but that’s not what you’re trying to do here.

WELP. That is embarrassing. Thank you sir. All is working now. Worst part is; two lines down, I use the proper call… I do not even want to admit how long I’ve been messing with this.