Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

glDrawElements Basic Question

34 views
Skip to first unread message
Message has been deleted

Mitchell Hockley

unread,
Apr 30, 2010, 11:15:27 AM4/30/10
to
I have the following code and it works fine:

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.

fungus

unread,
Apr 30, 2010, 11:21:05 AM4/30/10
to
On Apr 30, 5:15 pm, Mitchell Hockley <mi...@bmtmis.demon.co.uk> wrote:
>
> And indices is an array of unsigned ints in the format
> {1,2,3,4,3,4,2...........}
>
> I have an index array normalIndices which if of the format
> {1,2,4,3,2,1,5,4....)
>

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

Mitchell Hockley

unread,
Apr 30, 2010, 11:50:10 AM4/30/10
to

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?

Wolfgang Draxinger

unread,
Apr 30, 2010, 5:18:31 PM4/30/10
to
Am Fri, 30 Apr 2010 08:50:10 -0700 (PDT)
schrieb Mitchell Hockley <mi...@bmtmis.demon.co.uk>:

> 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

fungus

unread,
Apr 30, 2010, 7:10:10 PM4/30/10
to
On Apr 30, 5:50 pm, Mitchell Hockley <mi...@bmtmis.demon.co.uk> wrote:
>
> So OpenGL will use the values in indices to index into the normals as
> well as the vertices?
>

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.

Mitchell Hockley

unread,
May 1, 2010, 6:50:41 AM5/1/10
to

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.

fungus

unread,
May 1, 2010, 8:10:50 AM5/1/10
to
On May 1, 12:50 pm, Mitchell Hockley <mi...@bmtmis.demon.co.uk> wrote:
>
> Using glDrawElements how can I specify the two normals - one for each
> triangle without incurring an undesirable repetition of vertices in
> m_vertices.
>

You can't do it.


> will I have to duplicate vertices???
>

Yes.

Dave Eberly

unread,
May 1, 2010, 11:25:29 AM5/1/10
to
"fungus" <opengl...@artlum.com> wrote in message
news:f3822c55-58e7-4033...@h9g2000yqm.googlegroups.com...

> On May 1, 12:50 pm, Mitchell Hockley <mi...@bmtmis.demon.co.uk> wrote:
>>
>> Using glDrawElements how can I specify the two normals - one for each
>> triangle without incurring an undesirable repetition of vertices in
>> m_vertices.
>>
>
> 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


0 new messages