Rendering OpenGL ES 2.0顶点数据错误

Rendering OpenGL ES 2.0顶点数据错误,rendering,opengl-es-2.0,shader,vertex-shader,vao,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_pro

我试图在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;
}
片段着色器:

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);

现在我已经把所有的顶点设置为零,这就使得屏幕中间的精灵出现了,这是非常好的,但是,如果我把顶点数据改为

//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)在顶点着色器中从未正确设置,但我做错了什么?

问题在于缓冲区偏移(最后一个参数):

您可以将其设置为
3
,因为您的意思可能是“稍后开始3个浮动(一个属性)”,但实际上它的意思是“稍后开始3个字节”。因此,您实际上需要将步幅设置为3个浮点的大小,以字节为单位,因此
3*sizeof(float)

或者使用指针算法:

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


顺便说一句,你的
glGetAttribLocation
调用也很奇怪。作为第一个参数,它们需要一个GLSL程序对象(从
glCreateProgram
获得的ID)。我从未见过有人在其中使用实际的数字(尽管GL对象实际上只是外部世界的数字,因此出于调试目的,可以硬连线它,即使非常奇怪)。

问题在于缓冲区偏移量(最后一个参数):

您可以将其设置为
3
,因为您的意思可能是“稍后开始3个浮动(一个属性)”,但实际上它的意思是“稍后开始3个字节”。因此,您实际上需要将步幅设置为3个浮点的大小,以字节为单位,因此
3*sizeof(float)

或者使用指针算法:

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


顺便说一句,你的
glGetAttribLocation
调用也很奇怪。作为第一个参数,它们需要一个GLSL程序对象(从
glCreateProgram
获得的ID)。我从未见过有人在那里使用实际的数字(尽管GL对象实际上只是外部世界的数字,因此出于调试目的,可能可以硬连接它,即使非常奇怪)。

duh,这么简单的东西浪费了这么多时间,谢谢!那里的实际数字就像你说的只是为了调试,因为我知道程序会被分配数字3.duh,这么简单的事情浪费了这么多时间,谢谢!因为我知道程序会被分配数字3,所以实际的数字就是你刚才说的用于调试的数字。
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);