我有一个顶点着色器:
#version 430
in vec4 position;
void main(void)
{
//gl_Position = position; => works in ALL cases
gl_Position = vec4(0,0,0,1);
}
如果我这样做:
m_program.setAttributeArray(0, m_vertices.constData());
m_program.enableAttributeArray(0);
一切正常。但是,如果我这样做:
m_program.setAttributeArray("position", m_vertices.constData());
m_program.enableAttributeArray("position");
注意:m_program.attributeLocation("position");
返回-1。
然后,我得到一个空窗口。
Qt帮助页面状态:
void QGLShaderProgram :: setAttributeArray(int location,const QVector3D * values,int stride = 0)
在此着色器程序中的位置属性上设置3D顶点值数组。步幅表明了 顶点之间的字节数。默认步幅值为零 表示顶点密集在值中。
调用enableAttributeArray()时,数组将变为活动状态 那个地点。否则使用setAttributeValue()指定的值 将使用位置。
和
void QGLShaderProgram :: setAttributeArray(const char * name,const QVector3D *值,int stride = 0)
这是一个重载功能。
在此属性中为名为name的属性设置3D顶点值数组 着色器程序。步幅表示之间的字节数 顶点。默认步幅值为零表示顶点 密集的价值观。
调用enableAttributeArray()时,数组将变为活动状态 名称。否则使用setAttributeValue()为name指定的值 将被使用。
那么为什么在使用“int
版本”时才有效,而在使用“const char *
版本”时呢?
答案 0 :(得分:1)
返回 -1 ,因为您在着色器中注释了实际使用position
的唯一一行。
这不是错误,而是误解了如何分配属性位置的结果。在编译和链接所有着色器阶段之后,仅为制服和属性分配位置。如果在活动代码路径中未使用统一或属性,则不会为其分配位置。即使你使用变量做这样的事情:
#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;
}
它实际上甚至比这更远。如果某些内容从顶点着色器输出但未在几何体,曲面细分或片段着色器中使用,则其代码路径将被视为无效。
顺便说一下,顶点属性位置0是隐式顶点位置。它是GLSL规范中唯一的顶点属性。允许别名为固定函数指针函数(例如glVertexPointer (...)
== glVertexAttribPointer (0, ...)
)