Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glVertexPointer(3, Gl.GL_DOUBLE, 0, m_vertices);
Gl.glDrawElements(Gl.GL_TRIANGLES, indices.Length, Gl.GL_UNSIGNED_INT,
indices);
m_vertices is an array of doubles in the format
{x1,y1,z1,x2,y2,z2.....}
And indices is an array of unsigned ints in the format
{1,2,3,4,3,4,2...........}
So 3 means use vertex x3,y3,z3 etc
No problem.
But, I want to pass normals for lighting. So I change code to:
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glVertexPointer(3, Gl.GL_DOUBLE, 0, m_vertices);
Gl.glNormalPointer(Gl.GL_DOUBLE, 0, m_normals);
Gl.glDrawElements(Gl.GL_TRIANGLES, indices.Length, Gl.GL_UNSIGNED_INT,
indices);
But my it hasn't worked, normals are clearly not right as lighing is
all over the place.
m_normals is an array of doubles of the format {1 0 0, -1 0 0, 0 1 0,
0 0 1, .......}
each triplet unique BUT how do I tell OpenGL how to access this array.
I have an index array normalIndices which if of the format
{1,2,4,3,2,1,5,4....)
so 1 would mean use normal -1,0,0
There is one normal per vertex.
How can I tell OpenGL to access m_normals from normalIndices in just
the same way that I tell it to access m_vertices through indices via
my call to glDrawElements.
Should indices be ammended to somehow contain the vertices and the
normals for each vertex.
Please any help would be appreciated or a link to some code which uses
glDrawElements to render geometry with normals.
Thanks.
You can't have separate indices for normals and
position in OpenGL.
--
<\___/>
/ O O \
\_____/ FTB.
http://www.topaz3d.com/ - 3D editor for real time/simulation
Thanks for your reply,
So OpenGL will use the values in indices to index into the normals as
well as the vertices?
So I can have a normal per vertex? (I read somewhere that I couldn't)
And I should organize my arrays like this -
m_vertices = {x0, y0, z0, x1, y1, z1, x2, y2, z2......... }
indices = {1, 2, 3, 4, 3, 4, 2........... }
m_normals = {N0x, N0y, N0z, N1x, N1y, N1z, N2x, N2y, N2z ....... }
Where the normal (Nnx, Nny, Nnz) corresponds to the vertex (xn, yn,
zn)
And so of course m_normals and m_vertices will be of the same size.
Is that correct?
> So OpenGL will use the values in indices to index into the normals as
> well as the vertices?
>
> So I can have a normal per vertex?
Actually normals are per vertex. A lot of people get fooled by
immediate code examples like
glBegin(GL_TRIANGLES);
glNormalf(...):
glVertex3f(...);
glVertex3f(...);
glVertex3f(...);
glEnd();
Which makes people think, that you can distribute a single normal or
color value among a number of vertices.
However a vertex is a long vector, which contains
/ position \
| normal |
| color |
| texture coordinate 1 |
| texture coordinate 2 |
vertex = | texture coordinate ... |
| texture coordinate n |
| vertex attributes 1 |
| vertex attributes 2 |
| vertex attributes ... |
\ vertex attributes n /
All these form a single vector. And what's supplied by means of vertex
arrays is a vector of vertices (i.e. a vertex vector). glDrawElements
takes a index vector addressing these huge vertex vectors.
So you must get this: A vertex is not just the position, it's the whole
set of attributes.
Now you might ask, why you've to supply the subvectors through a set of
different vectors (glVertexArray, glNormalArray, etc.). The reason is,
that you might want to not supply the longest possible vector, but only
a smaller subset.
> And so of course m_normals and m_vertices will be of the same size.
They must be the same size, because they belong to the very same
vector/-s.
Wolfgang
Yes.
> So I can have a normal per vertex? (I read somewhere that I couldn't)
>
Yes (...in fact you can ONLY have normal per vertex!)
> And I should organize my arrays like this -
>
> m_vertices = {x0, y0, z0, x1, y1, z1, x2, y2, z2......... }
>
> indices = {1, 2, 3, 4, 3, 4, 2........... }
>
> m_normals = {N0x, N0y, N0z, N1x, N1y, N1z, N2x, N2y, N2z ....... }
>
> Where the normal (Nnx, Nny, Nnz) corresponds to the vertex (xn, yn,
> zn)
>
> And so of course m_normals and m_vertices will be of the same size.
>
> Is that correct?
Yes.
Okay,
So lets say I have four vertices
m_vertices = {x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3}
And two triangels
indices = {0,1,2,1,2,3}
Using glDrawElements how can I specify the two normals - one for each
triangle without incurring an undesirable repetition of vertices in
m_vertices.
So I want the normal to {x0,y0,z0,x1,y1,z1,x2,y2,z2} to be one thing
and the normal to {x1,y1,z1,x2,y2,z2,x3,y3,z3} to be another thing.
Morever some vertices belong to more than one triangle and so need
more than one normal.
If I duplicate vertices in my indexed array then I am forced to pass
many more than I would like to.
So will I have to duplicate vertices???
Thanks.
You can't do it.
> will I have to duplicate vertices???
>
Yes.
Write a shader to process the two-triangle mesh. Each vertex in the vertex
buffer has a 3-tuple position and a single number (store as a 1D texture
coordinate): {(x0,y0,z0;0), (x1,y1,z1;1), (x2,y2,z2;1), (x3,y3,z3;2)}. The
number "1" is used for the two vertices of the shared edge of the triangles.
Pass through the texture coordinate for the fragment shader. Specify the
face normals as two uniforms to the fragment shader, face normal of triangle
{0,1,2} first, face normal of triangle {1,3,2} second. In the fragment
shader, test the value of the texture coordinate input. If less or equal to
1, use the first face normal for lighting; otherwise, use the second face
normal.
Not that I would ever do this, but the point is for a two-triangle mesh:
"you can do it" and "no". However, for all practical purposes, the answers
"you can't do it" and "yes" are correct. :)
--
Dave Eberly
http://www.geometrictools.com