Problems arise when using a VBO compared to a uniform for mat4

I’ve been learning LWJGL and was originally using instancing and using a uniform to send all the mat4 data to the shader for the individual positions. I’m trying to switch to using a VBO for this since I had a batch size limitation of just 128, but have run into a problem with sending the data to the shader. I’ve spend a few days looking over the instancing sections of both https://learnopengl.com/ and https://lwjglgamedev.gitbooks.io/ but haven’t been able to find anything that could be the cause of this.

Nothing was changed aside from the code presented here, the creation of any needed variables, and the conversion from uniform to VBO in the shader itself.

This was the original code using the uniform that worked just fine. First is what was used to actually make the draw calls, and the second part is what was used to pass the mat4s to the shader:

// Prepare shader  GL40.glEnableVertexAttribArray(0); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, vertexID); GL40.glVertexAttribPointer(0, 3, GL40.GL_FLOAT, false, 0, 0);  GL40.glEnableVertexAttribArray(1); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, textureID); GL40.glVertexAttribPointer(1, 2, GL40.GL_FLOAT, false, 0, 0);  GL40.glEnableVertexAttribArray(2); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, normalID); GL40.glVertexAttribPointer(2, 3, GL40.GL_FLOAT, false, 0, 0);  GL40.glEnableVertexAttribArray(3); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, shadeID); GL40.glBufferData(GL40.GL_ARRAY_BUFFER, createFloatBuffer(shade.toArray(new Vector4f[shade.size()])), GL40.GL_STATIC_DRAW); GL40.glVertexAttribPointer(3, 4, GL40.GL_FLOAT, false, 0, 0); GL40.glVertexAttribDivisor(3, 1);  GL40.glBindBuffer(GL40.GL_ELEMENT_ARRAY_BUFFER, indexID); for(int i = 0; i < amount / 128 + 1; i++) {     int draws = Math.min(128, amount - i * 128);     for(int j = 0; j < draws; j ++) {         int loc = i * 128 + j;         shader.setUniform("model[" + j + "]", Matrix4f.transform(position.get(loc), rotation.get(loc), scale.get(loc)));     }     GL40.glDrawElementsInstanced(GL40.GL_TRIANGLES, drawCount, GL11.GL_UNSIGNED_INT, 0, draws); }  GL40.glBindBuffer(GL40.GL_ELEMENT_ARRAY_BUFFER, 0); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, 0);  GL40.glDisableVertexAttribArray(0); GL40.glDisableVertexAttribArray(1); GL40.glDisableVertexAttribArray(2); GL40.glDisableVertexAttribArray(3); 

Setting the mat4 uniform:

public void setUniform(String name, Matrix4f value) {     int location = GL20.glGetUniformLocation(programID, name);     if (location != -1) {         try (MemoryStack stack = MemoryStack.stackPush()) {             final FloatBuffer matrixBuffer = stack.mallocFloat(16);             matrixBuffer.put(value.getAll()).flip();             GL20.glUniformMatrix4fv(location, true, matrixBuffer);         }     } } 

And this is the code that’s been causing issues:

// Prepare shader  GL40.glEnableVertexAttribArray(0); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, vertexID); GL40.glVertexAttribPointer(0, 3, GL40.GL_FLOAT, false, 0, 0);  GL40.glEnableVertexAttribArray(1); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, textureID); GL40.glVertexAttribPointer(1, 2, GL40.GL_FLOAT, false, 0, 0);  GL40.glEnableVertexAttribArray(2); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, normalID); GL40.glVertexAttribPointer(2, 3, GL40.GL_FLOAT, false, 0, 0);  GL40.glEnableVertexAttribArray(3); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, shadeID); GL40.glBufferData(GL40.GL_ARRAY_BUFFER, createFloatBuffer(shade.toArray(new Vector4f[shade.size()])),         GL40.GL_STATIC_DRAW); GL40.glVertexAttribPointer(3, 4, GL40.GL_FLOAT, false, 0, 0); GL40.glVertexAttribDivisor(3, 1);  GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, modelID); GL40.glBufferData(GL40.GL_ARRAY_BUFFER, createFloatBuffer(position.toArray(new Vector3f[position.size()]), rotation.toArray(new Vector3f[rotation.size()]), scale.toArray(new Vector3f[scale.size()])), GL40.GL_STATIC_DRAW);  int size = 4; for (int i = 0; i < 4; i++) {     GL40.glEnableVertexAttribArray(4 + i);     GL40.glVertexAttribPointer(4 + i, 4, GL40.GL_FLOAT, false, 4 * size, i * size);     GL40.glVertexAttribDivisor(4 + i, 1); }  GL40.glBindBuffer(GL40.GL_ELEMENT_ARRAY_BUFFER, indexID); GL40.glDrawElementsInstanced(GL40.GL_TRIANGLES, drawCount, GL11.GL_UNSIGNED_INT, 0, amount);  GL40.glBindBuffer(GL40.GL_ELEMENT_ARRAY_BUFFER, 0); GL40.glBindBuffer(GL40.GL_ARRAY_BUFFER, 0);  GL40.glDisableVertexAttribArray(0); GL40.glDisableVertexAttribArray(1); GL40.glDisableVertexAttribArray(2); GL40.glDisableVertexAttribArray(3); GL40.glDisableVertexAttribArray(4); GL40.glDisableVertexAttribArray(5); GL40.glDisableVertexAttribArray(6); GL40.glDisableVertexAttribArray(7); 

Storing the mat4s into the VBO:

public static FloatBuffer createFloatBuffer(Vector3f[] positions, Vector3f[] rotation, Vector3f[] scales {     FloatBuffer buffer = BufferUtils.createFloatBuffer(positions.length * 16);     for (int i = 0; i < positions.length; i++) {         buffer.put(Matrix4f.transform(positions[i], rotation[i], scales[i]).getAll());     }     buffer.flip();     return buffer; } 

I’ve messed around with this a ton over the past couple days which leads me to believe that it’s not a problem with the data being sent, but rather how the data itself is formatted. That doesn’t make much sense though, since both examples use Matrix4f.transform() to get the needed data. I tried transposing the matrices before adding them to the buffer but to no avail.

And just for reference, here is an example of what Matrix4f.getAll() produces:

[0.5, 0.0, 0.0, -40.0,

0.0, 0.5, 0.0, 12.0,

0.0, 0.0, 0.5, 88.0,

0.0, 0.0, 0.0, 1.0]

Here are two screen shots of what it’s suppose to look like and the results I’m getting from using the VBO approach: enter image description here

enter image description here