Interleaved Vertex Normal Array (glDrawArrays)[Solved]

Started by Krux, November 01, 2010, 18:58:26

Previous topic - Next topic

Krux

I have a Buffer that contains interleaved Vertex and Normal Data.

3 Floats vertex coordinate
3 Floats vertex normal
3 Floats vertex coordinate
3 Floats vertex normal
...

i think in C my openGL calls would look like this

glVertexPointer(3,GL_FLOAT,3*sizeof(GL_FLOAT),cubedata);
glNormalPointer(GL_FLOAT,3*sizeof(GL_FLOAT),cubedata+3*sizeof(GL_FLOAT));

glNewList(displayList,GL_COMPILE);
glDrawArrays(GL_TRIANGLES,0,6*3*12);
glEndList();


but Java has no pointer, so I have no idea how i can address my interleaved vertex data correctly.
      

Kai

The NIO ByteBuffer (FloatBuffer, DoubleBuffer, etc.) acts as a pointer in that way.

You can do "pointer arithmetic" via the position(int)-Method of that Buffer. This method sets the "read/write"-cursor of that Buffer to the given position relative to the buffer's absolute start position (where the data in the Buffer begins).

The LWJGL-Methods accepting a Buffer (FloatBuffer, etc.) respect that position, so you can do as follows:

// Stride in bytes
int stride = 3 * 4;

// The buffer
FloatBuffer buffer = ...;

// Set vertex position data
glVertexPointer(3, stride, buffer);

// Offset buffer to first normal
buffer.position(stride);

// Set vertex normal data
glNormalPointer(stride, buffer);


That should do it.

Krux

Thanks

I have this FloatBuffer with the data structure as described above. But somehow I still get Normals coordinates as vertex coordinates and other way round.

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
		
int stride = 3*4;
		
glVertexPointer(3,stride,cubedata);
cubedata.position(stride);
glNormalPointer(stride,cubedata);
	
glDrawArrays(GL_TRIANGLES,0,cubedata.capacity());


this is intended to run as an VBO, but I will only add this VBO code as soon as it works also without it.

btw
these two calls have no difference on the output
glVertexPointer(3, 0,cubedata);

glVertexPointer(3,12,cubedata);

Kai

Sorry, my bad.

The stride needs to be the byte length between the start of one vertex and the start of the next vertex, that is in your case sizeof(float) * 6, as stated in http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml

This is a little bit misleading, since when no stride is used (as with one single vertex attribute per vertex array), the 'stride' parameter needs to be 0 and not the number of bytes per vertex attribute...

So just adjust the stride to be 6 * 4.

Krux

thank you very much
this code finally works
int stride = 6*4; //the offset between vertex and next vertex data given in real byte distance
		
cubedata.position(0);
glVertexPointer(3,stride,cubedata);
cubedata.position(3); //3 is the offset from vertex to normal data given in number of floats
glNormalPointer(stride,cubedata);

glDrawArrays(GL_TRIANGLES,0,54); //54 number of vertices

All those parameters are given in different encodings, this is confusing.
I commented it, maybe someday there will be someone who thiks this could be helpfull