我有一个Vertex数据类型,包括position(3),texture(2)和vertex normal(3)。我使用glVertexAttribPointer
将这些传递给vertex shader(请参阅here)。
不幸的是,无论我加载什么模型,它都给了我死星 - 基本上是一个顶点球体,只有当我切换到线框渲染时才能看到它。
我尝试从我的模块中删除一堆顶点,最终得到了部分构造的死星。在这一点上,很明显它正在绘制法线,好像它们是顶点。我不知道顶点是否正在绘制。
我通过drawing two additional triangles确认了我的假设 - 一个代表顶点应该的位置,另一个代表法线。我还将它们缩放到1.1,这样它们就可以与物体本身区分开来。是的,它肯定是绘制法线而不是顶点。
有谁知道为什么?我已经尝试在着色器中切换属性的顺序,但这没有帮助(奇怪)。
Here's the complete minimum working example以及两个测试对象(完整,n20r4_d5.obj;非常局部,test11.obj)。
答案 0 :(得分:4)
您正在使用OpenGL 2.1,因此您必须使用glGetAttribLocation()
来提取属性索引。你不能只希望GLSL编译器将0
和texcoords放在2
上的顶点:
void render(Shader* shader_program = NULL)
{
if (shader_program)
shader_program->bind();
GLint position_loc = glGetAttribLocation( shader_program->id(), "position" );
GLint tex_loc = glGetAttribLocation( shader_program->id(), "tex" );
GLint normal_loc = glGetAttribLocation( shader_program->id(), "normal" );
glEnableVertexAttribArray( position_loc );
glEnableVertexAttribArray( normal_loc );
glEnableVertexAttribArray( tex_loc );
for (size_t i = 0; i < entries.size(); ++i)
{
glBindBuffer(GL_ARRAY_BUFFER, entries[i].vb);
// I think this tells it where to look for the vertex information we've loaded.
glVertexAttribPointer(position_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(normal_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12); // starts at 12 because 3 floats for position before 2 floats for normal
glVertexAttribPointer(tex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20); // makes room for 5 floats
...
在链接着色器之前,你也可以告诉 OpenGL把它们放在哪里(glBindAttribLocation()
),但是你设置的东西会让你有点混乱。
在OpenGL 3.1+中,您可以强制编译器通过layout
qualifier将属性放在特定索引上。