LWJGL Forum

Programming => OpenGL => Topic started by: Krux on November 01, 2010, 18:58:26

Title: Interleaved Vertex Normal Array (glDrawArrays)[Solved]
Post by: Krux on November 01, 2010, 18:58:26
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.
      
Title: Re: Interleaved Vertex Normal Array (glDrawArrays)
Post by: Kai on November 01, 2010, 22:08:47
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.
Title: Re: Interleaved Vertex Normal Array (glDrawArrays)
Post by: Krux on November 01, 2010, 23:34:27
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);
Title: Re: Interleaved Vertex Normal Array (glDrawArrays)
Post by: Kai on November 02, 2010, 18:03:49
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 (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.
Title: Re: Interleaved Vertex Normal Array (glDrawArrays)
Post by: Krux on November 02, 2010, 23:14:27
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