PDA

View Full Version : Packing/Unpacking vertex information.



Amani77
09-12-2016, 03:38 AM
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( "\nSize vertices buffer: %f\n", size_bytes_vbo / 1024.0f / 1024.0f );
GLuint size_bytes_ibo = size_ibo_block * num_ibo_blocks * sizeof( GLuint );
printf( "\nSize indices buffer: %f\n", size_bytes_ibo / 1024.0f / 1024.0f );

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

printf( "\nSize total: %f\n", 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.

Alfonse Reinheart
09-12-2016, 05:08 AM
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.

Amani77
09-12-2016, 05:11 AM
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.