PDA

View Full Version : glDisableVertexAttribArray not working?



RedPuma
03-11-2012, 09:08 AM
Hi,
I have a Vertex shader which has two "in" vertex attributes:

in vec3 iv_Vertex;
in vec2 iv_UvCoord;

Normally I call glGetAttribLocation() on both and set glEnableVertexAttribArray() and glVertexAttribPointer() with the returned value.

I now want to draw some debug lines with the same shader so I dont need the uv-coordinates. I simply disabled the attribute via glDisableVertexAttribArray(), however glDrawArrays() crashes with an Access Violation at 0x0000000.
Some further investigation showed that my vertex shader always has two active Attributes, even right after the call to glDisableVertexAttribArray().

This is my investigation function:

DLL void init_vertexbuffer_vars_pos( void *buffer )
{
CShader *pShd = GetShaderManager()->GetActiveShader();

int attrib1 = pShd->GetAttribLoc( SHADER_VERTEX ); //This is always 1
glEnableVertexAttribArray( attrib1 );
glVertexAttribPointer( attrib1, 3, GL_FLOAT, GL_FALSE, 0, ((char*)buffer) + 0 );

int attrib2 = pShd->GetAttribLoc( SHADER_UVCOORD ); //This is always 0
if( attrib2 != -1 )
glDisableVertexAttribArray( attrib2 );

GLint active_attribs;
glGetProgramiv(pShd->m_iProgram, GL_ACTIVE_ATTRIBUTES, &active_attribs);

for( UINT i = 0; i < active_attribs; i++ )
{
GLchar var[32];
GLint size;
GLenum type;
glGetActiveAttrib( pShd->m_iProgram, i, 32, NULL, &amp;size, &amp;type, var );
ConsoleMessage( "Active Attribute: %s, program attrib nr. %i", var, i );
}
}

This function ALWAYS outputs the following:
] Active Attribute: iv_UvCoord, program attrib nr. 0
] Active Attribute: iv_Vertex, program attrib nr. 1

So my UvCoord-Attribute does not get disabled. How is that possible?

Dan Bartlett
03-11-2012, 09:41 AM
Active attributes are just ones that haven't been optimized away by the compiler (if they have been optimised away, then querying their location would give -1), nothing to do with whether they are enabled or not.
To query if an attribute is enabled, use http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml

RedPuma
03-11-2012, 10:01 AM
Ok I understand, but I still dont know why glDrawElements crashes when I dont input the uv-coords. Shouldn't OGL set the iv_UvCoord to a default value when I call glDisableVertexAttribArray( <iv_UvCoord> ) before or do I really need to supply the Vertex Shader with data for every attribute with an "in" qualifier?

malexander
03-11-2012, 08:30 PM
in_UvCoord is probably in attribute location 0, which is special - you can't disable it. Nvidia seems to assign them in the order you declare them, while AMD alphabetizes attributes before assigning locations (meaning that in_UvCoord would be assign location zero). I'm guessing that you may not have anything bound to in_UvCoord and it is assigned to location 0, and that's causing the crash.

RedPuma
03-14-2012, 06:48 AM
Thanks guys. Explicitly binding iv_Vertex to attribute position 0 solved the issue. Just to give a complete solution, heres the modified code of my compile-shader-function:

...
glAttachShader( m_iProgram, m_iVertexShader );
glAttachShader( m_iProgram, m_iFragmentShader );

glBindAttribLocation( m_iProgram, 0, "iv_Vertex" ); //Added

glLinkProgram( m_iProgram );
...

Note that hard coding the attribute name isn't a good practice ;)