1
votes

I have been stuck all day yesterday with this problem and cant figure it out. The code is below but generally i am trying to give a mesh Vertex Attributes for 1.Postions 2.Indices 3.Normals and 4.a single float value. The values are all stored in different VBOs and after binding each vbo i declare the vertexAttribPointer. I cant get both normals and float value working. What im seeing seems like the position of the float value is either the x y or z part of the normals vec3 in the previous vbo.

GL4 gl = GLContext.getCurrentGL().getGL4();

int[] vaoids = new int[1];
gl.glGenVertexArrays(1,vaoids,0);

int[] vboids = new int[4];
gl.glGenBuffers(4,vboids,0);

gl.glBindVertexArray(vaoids[0]);

FloatBuffer verticesBuffer = FloatBuffer.allocate(mesh.vertices.length);
verticesBuffer.put(mesh.vertices);
verticesBuffer.flip();

gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[0]);
gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * 4 ,verticesBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, false, 0, 0);
verticesBuffer.clear();
verticesBuffer = null;

//normal buffer
FloatBuffer normalBuffer = FloatBuffer.allocate(mesh.normals.length);
normalBuffer.put(mesh.normals);
normalBuffer.flip();

gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[2]);
gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * 4 ,normalBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(2);
gl.glVertexAttribPointer(2, 3, gl.GL_FLOAT, false, 0, 0);
normalBuffer.clear();
normalBuffer = null;


//color buffer
float[] colors = new float[mesh.vertices.length/3];
Arrays.fill(colors,255.0f);
FloatBuffer colorBuffer = FloatBuffer.allocate(colors.length);
colorBuffer.put(colors);
colorBuffer.flip();

gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[3]);
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors.length * 4 ,colorBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(3);
gl.glVertexAttribPointer(3, 1, gl.GL_FLOAT,false, 0, 0);
colorBuffer.clear();
colorBuffer = null;

IntBuffer indicesBuffer = IntBuffer.allocate(mesh.indices.length);
indicesBuffer.put(mesh.indices);
indicesBuffer.flip();

gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, vboids[1]);
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * 4 ,indicesBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(1);
gl.glVertexAttribPointer(1, mesh.type.equals(MeshType.TRIANGLE) ? 3 : mesh.type.equals(MeshType.LINE) ? 2 : mesh.type.equals(MeshType.POINT) ? 1:0, gl.GL_UNSIGNED_INT, false, 0, 0);
indicesBuffer.clear();
indicesBuffer = null;

//gl.glBindBuffer(gl.GL_ARRAY_BUFFER,0);
gl.glBindVertexArray(0);

This the code that declares the vao and vbos. I render with glDrawElements and enable the needed VertexAttributeArray Indices before that. In my Shader I access the value as following:

layout (location=0) in vec3 position;
layout (location=2) in vec3 normal;
layout (location=3) in float color;

out vec3 normals;
out vec4 positionWorldSpace;
out flat float vertexColor;

And the fragment shader

in flat float color;

I can get both of them working separate but if i declare both they float values are not correct anymore. The normals seems to be right however. As i said the values in the float seem the be values from the normals. Can there be some sort of overflow from the normal vbo to the float vbo? After hours of looking at the code i just cant spot the error.

1
I am sorry yes it is Java. Should have clarified - Alexander W
The indices are not attributes. The index buffer GL_ELEMENT_ARRAY_BUFFER is stated in the VAO directly. - Rabbid76
I removed the call to pointer after the indices and shifted the remaining attributes to position 0 1 2. But the same problem still occurs. - Alexander W
Ideally i want it to be of type short but for now since i couldn't get it to work i used float to narrow down where the error comes from. Basically it is an index that later tells me what material the part of the mesh is made of. The whole mesh is a triangulated point cloud with a marching cube algorithm. - Alexander W
You can't use short for an attribute, but you can use int. For integral attributes you have to use glVertexAttribIPointer (focus on I in the middle). Anyway, I can't see any obvious issue in your code. - Rabbid76

1 Answers

2
votes

The indices are not attributes. The [Index buffer](Index buffers) (GL_ELEMENT_ARRAY_BUFFER) is stated in the VAO directly. See Vertex Specification.
When you use glDrawArrays then the order vertex coordinates of the vertex coordinates in the array defines the primitives. If you want to use a different order or you want to use vertices for different primitives, then you have to use glDrawElements. When you use glDrawElements, then the primitives are defined by the vertex indices in the GL_ELEMENT_ARRAY_BUFFER buffer:

gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, vboids[1]);
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * 4 ,indicesBuffer,gl.GL_STATIC_DRAW);

// DELETE
//gl.glEnableVertexAttribArray(1);
//gl.glVertexAttribPointer(1, mesh.type.equals(MeshType.TRIANGLE) ? 3 : mesh.type.equals(MeshType.LINE) ? 2 : mesh.type.equals(MeshType.POINT) ? 1:0, gl.GL_UNSIGNED_INT, false, 0, 0);

indicesBuffer.clear();
indicesBuffer = null;

gl.glBindVertexArray(0);
gl.glDrawElements(gl.GL_TRIANGLES, mesh.indices.length, gl.GL_UNSIGNED_INT, null);