两个问题:
我在使用不同着色器的大型VBO中渲染元素。在GLSL 1.2中我必须使用,如果我是正确的,因为它是OSX上的最新版本不支持统一位置,我认为这意味着属性的位置是编译器决定的位置。有没有办法解决?例如,当我的VBO使用interleaved(x,y,z,nx,ny,nz,texU,texV)时,我需要多个着色器才能在每次相同的位置访问这些属性。然而,我发现编译器给它们不同的位置导致该位置是法线,依此类推。我需要他们的位置与我的VBO属性位置一致。
我刚刚完成了第一次GLSL渲染,看起来我忘了启用各种多边形渲染的深度测试。我启用了深度测试:
glEnable(GL_DEPTH_TEST);
问题仍然存在。是否有不同的方式使用着色器启用它们?我认为深度缓冲区会解决这个问题吗?
问题2解决了。原来是一个SFML问题,我需要在创建窗口时指定OpenGL设置。
答案 0 :(得分:2)
属性位置在3个位置之一中指定,按从最高优先级到最低优先级的顺序排列:
通过使用GLSL 3.30(或更好)或ARB_explicit_attrib_location扩展语法layout(location = #)
,其中#
是属性索引。因此,如果我有一个名为position
的输入,我会像这样给它索引3:
layout(location = 3) in vec4 position;
这是我处理此问题的首选方法。几乎任何仍受支持的硬件(不是英特尔)都可以使用Explicit_attrib_location。
通过glBindVertexAttrib
进行明确关联。在链接程序之前调用此函数。要做到这一点,我们会这样做:
GLuint program = glCreateProgram();
glAttachShader(program, some_shader);
glBindVertexAttrib(program, 3, "position");
glLinkProgram(program);
您可以设置多个属性。实际上,您可以将多个属性名称设置为相同的索引。这个想法是能够自动设置一堆映射,让OpenGL找出哪一个与实际的着色器代码一起工作。所以你可以将“position”和“axis”映射到索引3,只要你没有将着色器放入具有这两个输入的系统中,你就可以了。
请注意,您还可以设置不存在的属性。您可以为“正常”提供未在着色器中指定的属性。 那很好;链接器只关心实际存在的属性。因此,您可以为此类事物建立复杂的约定,并在链接之前运行其上的每个程序:
void AttribConvention(GLuint prog)
{
glBindVertexAttrib(program, 0, "position");
glBindVertexAttrib(program, 1, "color");
glBindVertexAttrib(program, 2, "normal");
glBindVertexAttrib(program, 3, "tangent");
glBindVertexAttrib(program, 4, "bitangent");
glBindVertexAttrib(program, 5, "texCoord");
}
GLuint program = glCreateProgram();
glAttachShader(program, some_shader);
AttribConvention(program);
glLinkProgram(program);
即使某个特定着色器没有所有这些属性,它仍然有效。
让OpenGL分配它。如果不以其他方式之一为属性分配属性索引,则GLSL链接器将为您分配属性索引。您可以使用glGetAttribLocation
获取后链接属性。
我真的不建议这样做,因为OpenGL将任意分配索引 。因此,使用名为position
的属性的每个着色器可能具有不同索引中的位置。我不认为这是个好主意。因此,如果您无法在着色器中明确设置它,那么至少在链接之前在OpenGL代码中明确设置它。这样,你可以有一个关于什么属性索引0意味着什么,索引1意味着什么等的约定。
答案 1 :(得分:1)
在OpenGL 3.3+上你有VAO,当你使用VAO时,你会将VBO绑定到它,你可以按照自定义顺序定义属性:http://www.opengl.org/sdk/docs/man3/xhtml/glEnableVertexAttribArray.xml(记住属性必须是连续的)
可以在XNA上找到一个很好/简单的实现方法:VertexDeclaration,您可能也希望看到所有的Vertex *类型。
有关使v3与SFML一起使用的一些提示: http://en.sfml-dev.org/forums/index.php?topic=6314.0
有关如何创建和使用VAO的示例:http://www.opentk.com/files/issues/HelloGL3.cs
(这是C#,但我猜你会得到它)
更新:
在v2.1上你也有http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml,但是你无法创建VAO。可以实现几乎相同的功能,但是每次都必须绑定属性,因为它将在固定管道上。