I'm trying to do something utterly simple and I'm getting incredibly frustrated. I've set up a trivial vertex shader since apparently you need one to get OpenGL to do anything nowadays or the dreaded deprecation gods frown at you or something:
#version 110
uniform mat4 scene_matrix;
attribute vec4 a_position;
void main()
{
gl_Position = scene_matrix * a_position;
}
Wonderful. After mucking around for 10 hours to create a suitable matrix I pass it into the shader with glUniformMatrix4
and it works gloriously. That is, until I want to render more than one THING.
So my goal is: For each object in the scene, I calculate the appropriate world matrix based on the coordinates of the object, call glUniformMatrix4
to tell the vertex shader about the matrix, call glBegin()
, then draw the stupid object, and call glEnd()
. Unfortunately it's pathetically drawing all the objects in the same stupid place (the place of the last object). Clearly it's lazily buffering things and not running the vertex shader until the end, when it has forgotten all about the previous matrices. But how do I tell it not to do that?
FloatBuffer matrixBuf = ByteBuffer.allocateDirect(16 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
for (int i = 0; i < 500; i++) {
matrixBuf.rewind();
matrices.world.translate(0.1, 0.1, 0.5);
matrices.calc();
matrices.combined.put(matrixBuf);
matrixBuf.rewind();
glUniformMatrix4(glGetUniformLocation(programId, "scene_matrix"), false, matrixBuf);
glBegin(GL_TRIANGLES);
{
//final int T = 1;
final float z = 0f;
final float R = 0.5f;
//glVertexAttrib2f(T, 0, 1);
glVertex3f(-R, -R, z);
//glVertexAttrib2f(T, 1, 0);
glVertex3f(R, R, z);
//glVertexAttrib2f(T, 0, 0);
glVertex3f(-R, R, z);
/*//glVertexAttrib2f(T, 0, 1);
glVertex3f(-R, -R, z);
//glVertexAttrib2f(T, 1, 1);
glVertex3f(R, -R, z);
//glVertexAttrib2f(T, 1, 0);
glVertex3f(R, R, z);*/
}
glEnd();
//glFlush(); // without this, all the triangles are in the same place
}
I discovered that calling glFlush()
after every glEnd()
solves the problem. However, this is causing a performance problem. I'm drawing only 500 objects (each a single pitiful triangle) and it is already maxing out the CPU and there is capacitor whine coming out of the computer. It feels wrong. I'm sure glFlush()
must be overkill.
I found that relinking the program with glLinkProgram(programId);
after every glUniformMatrix4
can also solve the problem, but it's an order of magnitude slower still.
I've looked everywhere. I just want to know what the name of the function that is used to tell it to get on and run the vertex shader now so then I can reconfigure the uniforms for the next object.
Or is this not what I'm supposed to be doing? Should I give up on the vertex pipeline, do all matrix transformation of vertices on the Java side and pass in already transformed vertices? Should I surrender to the deprecation devil and use the legacy OpenGL matrix stack to see if that's more cooperative? Any help is appreciated.