Pipeline input format with glGetActiveAttrib

Hello everyone!

Several days ago I had properly rendered triangle and now I have white screen. It happend after trying to get VAO format directly from shader using glGetActiveAttrib(…) + glGetAttribLocation(…). I correctly got all this info - shader returned GL_FLOAT_VEC3 type id, not GL_FLOAT as I used. Ok, I thought and just changed components count from 3 to 1 (I set attribute properties in myself before this changing and used three GL_FLOATs as format of attributes).

After using GL_FLOAT_VEC3 I got white screen.

I’m stack with it. Please, help, if there are some ideas what the problem may be here.

P.S.: Sorry about my english.

Ok, I just tried to get old solution, where manualy pipeline input data configuration were used. It works and draw colored triangle. The only thing I changed to get white screen was using GL_FLOAT_VEC3 instead GL_FLOAT. Like this:

glVertexAttribPointer(
/*index */ (GLuint)inState.attributeIndex,
/*size */ (GLint)3 - changed to -> 1,
/*type */ (GLenum)GL_FLOAT -changed to -> GL_FLOAT_VEC3,
/*normalized */ (GLboolean)GL_FALSE,
/*stride */ (GLsizei)0,
/*offset / (const GLvoid)0
);

GL_FLOAT_VEC3 is simply not a valid value for glVertexAttribPointer.

You just have to converte the values you get from glGetActiveAttrib to values that glVertexAttribPointer takes.

void getUsableValues(GLenum inputType, GLenum &outputBaseType, int &typeCounter)
{
	switch (inputType)
	{
		case GL_FLOAT:
		{
			outputBaseType = GL_FLOAT;
			typeCounter = 1;
			break;
		}
		case GL_FLOAT_VEC2:
		{
			outputBaseType = GL_FLOAT;
			typeCounter = 2;
			break;
		}
		case GL_FLOAT_VEC3:
		{
			outputBaseType = GL_FLOAT;
			typeCounter = 3;
			break;
		}
		case GL_FLOAT_VEC4:
		{
			outputBaseType = GL_FLOAT;
			typeCounter = 4;
			break;
		}
		//TODO: complete with all types...
	{
}

Thank you for fast answer! I’ll try this (oh, this must work because it worked in this way before changes).

P.S.: In fact, it’s really strange - return from shader attribte input type ids that isn’t valid type ids for the shader input. What the sense for such functionality? The debug purpose only?

You’re making the faulty assumption that the VAO format and the shader inputs are the same. There is absolutely no such guarantee.

A vertex array can contain i.e. two floats, and the corresponding shader input can be a vec4. Any missing components are substituted from [0,0,0,1]. The types of course may also change – bytes to floats, etc.

But why openGL not return from shader the most appropriate type? What is the sense to return incorrect for input type id as input format’s type? The glVertexAttribPointer can return not only attribute type id, but the count of components of this type. Why don’t it return the type GL_FLOAT and the components count (size in this documentation page) - three?

If you’re asking “why is the API the way it is” – I can’t answer that. I agree it isn’t very easy to use.

But if you’re asking “how do I query the format of the VAO” – the answer is to use the appropriate API:

glGetActiveAttrib* is for querying the linked shader inputs. It will give you types like “FLOAT_VEC4”, and also a size. In desktop GL (but not GL ES) the size can be larger than one for attributes declared as arrays in the shader.

glGetVertexAttrib* is for querying the VAO attributes. GL_VERTEX_ATTRIB_ARRAY_TYPE will give you types like “FLOAT”, and GL_VERTEX_ATTRIB_ARRAY_SIZE will give you answers like “4”.

All of the API is well documented.

Again, don’t make any assumptions about the VAO matching the shader inputs. The number of attributes, their types, and sizes can all be different. A single shader can be used with many different VAOs, and vice versa.

Thanks a lot for answer! I’ll do then converting of shader input format in way, presented by Osbios.