OpenGL ES 2.0顶点数据错误

时间:2013-12-03 06:58:58

标签: rendering opengl-es-2.0 shader vertex-shader vao

我试图在iOS上渲染一些点精灵,但是一些顶点数据似乎总是为0.经过几个小时的调试后,我把它缩小到这个非常简单的例子,试图渲染一个单个粒子

顶点着色器:

uniform mat4 projection;
uniform mat4 modelView;

attribute vec3 position;
attribute vec3 positionEnd;

void main()
{
  vec3 result = position + positionEnd;
  gl_Position = u_projection * u_model_view * vec4(result.x, result.y, result.z, 1.0);
  gl_PointSize = 15.0;
}

Fragment Shader:

uniform sampler2D texture;

void main()
{
  gl_FragColor = texture2D(u_texture, gl_PointCoord);
}

顶点数据上传:

vertices = std::vector<float>(6);
//attribute position
vertices[0] = 0;
vertices[1] = 0;
vertices[2] = 0;
//attribute positionEnd
vertices[3] = 0;
vertices[4] = 0;
vertices[5] = 0;

glGenVertexArraysOES(1, &mVao);
glBindVertexArrayOES(mVao);

glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);

auto positionLocation = glGetAttribLocation(3, "position");
auto positionEndLocation = glGetAttribLocation(3, "positionEnd");

glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid *)0);
glEnableVertexAttribArray(positionEndLocation);
glVertexAttribPointer(positionEndLocation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid *)3);

glBindVertexArrayOES(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

图:

glBindVertexArrayOES(mVao);
glDrawArrays(GL_POINTS, 0, 1);

现在我已将所有顶点设置为零,这会将精灵渲染到屏幕中间,这是完全正常的,但是,如果我将顶点数据更改为

//attribute position
vertices[0] = 20;
vertices[1] = 0;
vertices[2] = 0;
//attribute positionEnd
vertices[3] = -20;
vertices[4] = 0;
vertices[5] = 0;

应该再次在屏幕中间绘制(使用上面的顶点着色器),对吧?除非它不是,而是向右渲染20个单位。我假设positionEnd(因此-20)在顶点着色器中从未正确设置,但我做错了什么?

1 个答案:

答案 0 :(得分:1)

问题是你的缓冲区偏移量(最后一个参数):

glVertexAttribPointer(positionEndLocation, 3, GL_FLOAT, GL_FALSE, 
                      6 * sizeof(float), (GLvoid*)3);

您将其设置为3,因为您可能意味着“稍后启动3个浮动(一个属性)”,但它实际上意味着“以后开始3个字节”< / em>的。那么你实际需要设置步幅的是3个浮点数的字节数,因此3 * sizeof(float)

glVertexAttribPointer(positionEndLocation, 3, GL_FLOAT, GL_FALSE, 
                      6 * sizeof(float), (GLvoid*)(3*sizeof(float)));

或者使用指针算法:

glVertexAttribPointer(positionEndLocation, 3, GL_FLOAT, GL_FALSE, 
                      6 * sizeof(float), (float*)0 + 3);

顺便说一句,你的glGetAttribLocation电话也非常奇怪。作为第一个参数,他们期望一个GLSL程序对象(从glCreateProgram获得的ID)。我从来没有见过有人在那里使用实际的数字(虽然GL对象确实只是外部世界的数字,所以出于调试目的,硬连接它可能是好的,即使非常奇怪)。