0
votes

I have a vertex shader:

#version 430
in vec4 position;

void main(void)
{
    //gl_Position = position; => works in ALL cases
    gl_Position = vec4(0,0,0,1);
}

if I do:

m_program.setAttributeArray(0, m_vertices.constData());
m_program.enableAttributeArray(0);

everything works fine. However, if I do:

m_program.setAttributeArray("position", m_vertices.constData());
m_program.enableAttributeArray("position");

NOTE: m_program.attributeLocation("position"); returns -1.

then, I get an empty window.

Qt help pages state:

void QGLShaderProgram::setAttributeArray(int location, const QVector3D * values, int stride = 0)

Sets an array of 3D vertex values on the attribute at location in this shader program. The stride indicates the number of bytes between vertices. A default stride value of zero indicates that the vertices are densely packed in values.

The array will become active when enableAttributeArray() is called on the location. Otherwise the value specified with setAttributeValue() for location will be used.

and

void QGLShaderProgram::setAttributeArray(const char * name, const QVector3D * values, int stride = 0)

This is an overloaded function.

Sets an array of 3D vertex values on the attribute called name in this shader program. The stride indicates the number of bytes between vertices. A default stride value of zero indicates that the vertices are densely packed in values.

The array will become active when enableAttributeArray() is called on name. Otherwise the value specified with setAttributeValue() for name will be used.

So why is it working when using the "int version" and not when using the "const char * version"?

1
what do you get from m_program.attributeLocation("position");? - ratchet freak
It returns -1. So it has to do with position attribute not being used and maybe "cleaned" when the shader is compiled. Right? Then why it still works when using int? - Korchkidu
Which driver are you using? NVIDIA often "assigns" default attribute locations regardless of what the shader asks for (we see this a lot on Linux). - radical7
@radical7: windows 7, NVidia Quadro 2000M - Korchkidu

1 Answers

1
votes

It returns -1 because you commented out the only line in your shader that actually uses position.

This is not an error, it is a consequence of a misunderstanding how attribute locations are assigned. Uniforms and attributes are only assigned locations after all shader stages are compiled and linked. If a uniform or attribute is not used in an active code path it will not be assigned a location. Even if you use the variable to do something like this:

#version 130

in vec4 dead_pos; // Location: N/A
in vec4 live_pos; // Location: Probably 0

void main (void)
{
  vec4 not_used = dead_pos; // Not used for vertex shader output, so this is dead.
  gl_Position   = live_pos;
}

It actually goes even farther than this. If something is output from a vertex shader but not used in a geometry, tessellation or fragment shader, then its code path is considered inactive.

Vertex attribute location 0 is implicitly vertex position, by the way. It is the only vertex attribute that the GLSL spec. allows to alias to a fixed-function pointer function (e.g. glVertexPointer (...) == glVertexAttribPointer (0, ...))