Sign in to follow this  
Palidine

Problem with glDrawElementsInstanced and glVertexAttribDivisor

Recommended Posts

Hey,

 

Long time no posty... Anyway... I have a large grid of items that I'm rendering and want to do instanced rendering. I've obviously mis-set something because the data from my array buffer is coming in mangled. I'm looking for help identifying the problem. Thanks!

 

Setup for the Array Buffer in question:

glGenBuffers(1, &cellVBO.extraID0); // Generate our Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, cellVBO.extraID0); // Bind our Vertex Buffer Object
glBufferData(GL_ARRAY_BUFFER, gridInfo.MaxX*gridInfo.MaxZ*sizeof(uint32_t), NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(ATTRIB_EXTRA0, 1, GL_UNSIGNED_INT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(ATTRIB_EXTRA0);
glVertexAttribDivisor(ATTRIB_EXTRA0, 1);

Per render tick updating of the Array Buffer's Content:

//fill the testCell
glUniform1ui( uniforms[UNIFORM_UINT2], layerStart[0] );

//fill the actual Array Buffer
glBindBuffer( GL_ARRAY_BUFFER, cellVBO.extraID0 );
uint32_t *layerCells = (uint32_t *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy( layerCells, layerDataStart, gridInfo.MaxX*gridInfo.MaxZ*sizeof(uint32_t) );
glUnmapBuffer( GL_ARRAY_BUFFER );

//snip...

glBindVertexArray( cellVBO.vaoID );
glDrawElementsInstanced(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, (GLvoid*)0, gridInfo.MaxX*gridInfo.MaxZ);
glBindVertexArray( 0 );

Vertex Shader:

const GLchar* CellVertexShader_Instanced =
{
	"#version 400\n"\
 
	"layout(location=0) in vec3 in_Position;\n"\
	"layout(location=1) in vec2 in_TexCoord;\n"\
	"layout(location=2) in vec3 in_Normal;\n"\
	"layout(location=3) in uint in_Cell;\n"\

	"uniform mat4 proj_matrix;\n"\
	"uniform mat4 view_matrix;\n"\
	"uniform mat4 model_matrix;\n"\

	"uniform vec3 gridStartPos;\n"\
	"uniform uint layerY;\n"\
	"uniform uint gridMaxX;\n"\

	"uniform uint testCell;\n"\

	"uniform sampler1D uvLookupTexture;\n"\
	
	"out vec2 ex_TexCoord;\n"\
	"out vec3 position_world, normal_world;\n"\
	"out float ex_Invert;\n"\
	"out uint ex_CellContent;\n"\

	"void main(void)\n"\
	"{\n"\
		"	mat4 mvp_matrix = proj_matrix * view_matrix * model_matrix;\n"\

		"	//calculate the cell coortinates\n"\
		"	uint cellCoordZ = gl_InstanceID / gridMaxX;\n"\
		"	uint cellCoordX = gl_InstanceID - cellCoordZ*gridMaxX;\n"\

		"	//extract cell information\n"\
		"	ex_CellContent = testCell >> 24;\n"\ !!!! CORRECT VALUE !!!!
		"	ex_CellContent = in_Cell >> 24;\n"\  !!!! WRONG VALUE !!!! 

I also added a debug uniform, "testCell", that's taking the first element that should be getting copied into the Array Buffer just to make sure the other logic is correct. It is rendering totally correctly if I just leave in the line grabbing the value from testCell.

Edited by Palidine

Share this post


Link to post
Share on other sites

ok, well, found the answer.

 

If you are using glVertexAttribPointer, the data will be converted to a floating point value. For passing unsigned data without information loss, like I'm trying to do, you should use glVertexAttribIPointer. I'm not totally sure why there would be data loss since I would have imagined that it would be a (uint32_t)((float)originalValue) kind of thing, but there you have it. Data is getting into the shader. Happy times!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this