what works:
shader
#version 330 core
attribute vec3 pos;
attribute vec2 uv;
out vec3 color;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * vec4(pos.xy, sin(10.0*(pos.x + pos.y))/8.0 + 1.0, 1.0);
color = vec3(pos.xy, sin(10.0*(pos.x + pos.y))/8.0);
}
python
vao = glGenVertexArrays(1)
glBindVertexArray(vao)
# [x, y, z]
vertices = vbo.VBO(np.array([[...],[...],...], dtype=np.float32))
def draw():
glUseProgram(program)
glUniformMatrix4fv(projectionLoc, 1, False, perspectiveMatrix)
glUniformMatrix4fv(viewLoc, 1, False, viewMatrix)
vertices.bind()
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, 12, vertices)
glDrawArrays(GL_TRIANGLES, 0, lenVerticesArray)
vertices.unbind()
I would like to either, have a separate array of uv values [x, y] to pass through to the uv attribute, or to append them to the current vertices as [x, y, z, ux, uy] and have those be the uv attribute.
I tried doing the following with the combined [x, y, z, ux, uy]:
glEnableVertexAttribArray(posLoc)
glVertexAttribPointer(posLoc, 3, GL_FLOAT, False, 12, vertices)
glEnableVertexAttribArray(uvLoc)
glVertexAttribPointer(uvLoc, 2, GL_FLOAT, False, 12, vertices+12)
However, this does not work. Everything else I have tried is some variation of this, all of which fails. I cannot seem to understand what to properly do to send the data.
The 5th parameter of glVertexAttribPointer
is the byte offset between consecutive generic vertex attributes.
In your case an attribute tuple consist of 5 floats [x, y, z, ux, uy]. So the offset has to be 5*4 = 20.
If a named buffer object is bound, then the 6th parameter of glVertexAttribPointer
is treated as a byte offset into the buffer object's data store. But anyway the type of the parameter is a pointer (c_void_p
).
So if the offset is 0, then the 5th parameter can either be None
or c_void_p(0)
else the offset has to be caste to c_void_p
:
glBindVertexArray(vao)
glEnableVertexAttribArray(posLoc)
glEnableVertexAttribArray(uvLoc)
vertices.bind()
glVertexAttribPointer(posLoc, 3, GL_FLOAT, False, 20, None)
glVertexAttribPointer(uvLoc, 2, GL_FLOAT, False, 20, c_void_p(12))
vertices.bind()
is assumed to bind the vertex array object (glBindBuffer(GL_ARRAY_BUFFER, vbo)
).
When glVertexAttribPointer
is called then the specification of the array of generic vertex attributes is stored in the state vector of the current Vertex Array Object. So the VAO has to be bound before (glBindVertexArray(vao)
).
Further a name reference to the currently bound vertex buffer object is stored in the VAO. Each vertex attribute has its own VBO reference. They can all be the same or they can be different for all or some attributes. So the Vertex Buffer Object has to be bound before, too.