Domanda

I'm trying to render some point sprites on iOS, but some of the vertex data always seems to be 0. After hours of debugging I narrowed it down to this very simple example, trying to just render one single particle.

Vertex Shader:

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

Vertex Data Upload:

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

Drawing:

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

Now I've set all the vertices to zero, which renders the sprite in the middle of the screen, which is perfectly fine, however, if I change the vertex data to

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

It should be drawn in the middle of the screen again (using the above vertex shader), right? Except it's not, but instead rendered 20 units to the right. I assume that positionEnd (and thus the -20) is never set properly in the vertex Shader, but what am I doing wrong?

È stato utile?

Soluzione

The problem is your buffer offset (last parameter):

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

You set it to 3 as you probably mean "start 3 floats (one attribute) later", but what it actually means is "start 3 bytes later". So what you actually need to set the stride to is the size of 3 floats in bytes and thus 3 * sizeof(float)

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

Or alternatively use pointer arithmetic:

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

And by the way, your glGetAttribLocation calls are pretty weird, too. As first parameter they expect a GLSL program object (an ID as obtained from glCreateProgram). I've never seen somebody use an actual number in there (though GL objects are indeed just numbers to the outside world, so for debugging purposes it might be Ok to hardwire it, even if really weird).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top