Jump to content
  • Advertisement
Sign in to follow this  
polar01

OpenGL Calculate normals for a polygon - faces problem

This topic is 3230 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to calculate the normals for a set of polygons... but I got a problem. I calculate the normals and when I display theses normals they sounds correct :-( You can see this on the first picture here : http://picasaweb.google.com/viewon01/OpenGL#5391730635084390018 I don't know why my model sounds so "faceted" and that sometimes I got a face that looks strange !! Take a look at : http://picasaweb.google.com/viewon01/OpenGL#5391730633418058914 or http://picasaweb.google.com/viewon01/OpenGL#5380203925050881714 Can you help me please ? You can find my application at http://rs.codeplex.com or ... here is the source code for the normals calculation :
        override public void CalculateNormals()
        {
            base.CalculateNormals();

            if (Indices.Count == 0)
                return;

            Normals.Clear();

            Vector3[] sum = new Vector3[Vertices.Count];
            Vector3 surfaceNormal;
            Vector3 e1;
            Vector3 e2;

            int posInIndices = 0;
            for (int index = 0; index < VerticesPerPolygon.Count; index++)
            {
                int verticesCount = VerticesPerPolygon[index];
                for (int index0 = 0; index0 < verticesCount; index0++)
                {
                    Vector3 vertex = Vector3.Invalid.Clone();
                    Vector3 previousVertex = Vector3.Invalid.Clone();
                    Vector3 nextVertex = Vector3.Invalid.Clone();

                    int indice = Indices[posInIndices];
                    vertex = Vertices[indice];

                    if (index0 == 0)
                    {
                        int previousIndice = Indices[posInIndices + verticesCount - 1];
                        previousVertex = Vertices[previousIndice];

                        int nextIndice = Indices[posInIndices + 1];
                        nextVertex = Vertices[nextIndice];
                    }
                    else if (index0 > 0 && index0 < verticesCount - 1)
                    {
                        int previousIndice = Indices[posInIndices - 1];
                        previousVertex = Vertices[previousIndice];

                        int nextIndice = Indices[posInIndices + 1];
                        nextVertex = Vertices[nextIndice];
                    }
                    else if (index0 == verticesCount - 1)
                    {
                        int previousIndice = Indices[posInIndices - 1];
                        previousVertex = Vertices[previousIndice];

                        int nextIndice = Indices[posInIndices - verticesCount + 1];
                        nextVertex = Vertices[nextIndice];
                    }

                    //---- Calculate the surface normal
                    e1 = previousVertex - vertex;
                    e2 = vertex - nextVertex;

                    surfaceNormal = e1.Cross(e2);
                    surfaceNormal.Normalize();

                    // Sum it at the vertex index
                    sum[indice] += surfaceNormal;

                    //---- next
                    posInIndices++;
                }
            }

            for (int index = 0; index < Vertices.Count; index++)
            {
                sum[index].Normalize();
                Normals.Add(sum[index]);
            }
        }


Share this post


Link to post
Share on other sites
Advertisement
Avoid crossposting. It's only been 15 hours since your last post.

A guess is that perhaps your polygons have bad vertices in them or something. Make sure not to use 3 vertices in a straight line, or 2 vertices with the exact same coordinates, when calculating the normal.

Share this post


Link to post
Share on other sites
Okay, I will...

I have this problem with other models...

Also, I have load theses models with 2 other applications and they sounds correct, but not in my version :-(

Share this post


Link to post
Share on other sites
I'm not 100% sure about what you're doing for non-triangular polygons. Could you try rendering a model that only has triangular faces?

Also, if the problem persists could you post a close up screenshot?

Share this post


Link to post
Share on other sites
Thanks,

This one is composed of triangles only :
http://picasaweb.google.com/viewon01/OpenGL#5380203925050881714

I don't know what is happening, even not sure it is due to the normals !
I have try to play with back-face culling too... but I got no result too :-(

Here is the code for the triangles (based on same concept):


override public void CalculateNormals()
{
base.CalculateNormals();

if (Indices.Count == 0)
return;

Normals.Clear();

//----
Vector3[] sum = new Vector3[Vertices.Count];
for (int jj = 0; jj < Indices.Count / 3; jj++)
{
int indice1 = Indices[jj * 3];
int indice2 = Indices[jj * 3 + 1];
int indice3 = Indices[jj * 3 + 2];

Vector3 v1 = Vertices[indice1];
Vector3 v2 = Vertices[indice2];
Vector3 v3 = Vertices[indice3];

// Calculate the surface normal
Vector3 e1 = Vertices[indice1] - Vertices[indice2];
Vector3 e2 = Vertices[indice2] - Vertices[indice3];

Vector3 surfaceNormal = e1.Cross(e2);
surfaceNormal.Normalize();

// Sum it at the vertex index
sum[indice1] += surfaceNormal;
sum[indice2] += surfaceNormal;
sum[indice3] += surfaceNormal;
}

for (int index = 0; index < Vertices.Count; index++)
{
sum[index].Normalize();
Normals.Add(sum[index]);
}
}

Share this post


Link to post
Share on other sites
Of course,

You can even download the complete source code at :
http://rs.codeplex.com

Here is the OpenGL code to display the polygon (class OGLRenderer.cs):

private void RenderPolygonGeometry(PolygonGeometry polygon)
{
int indiceIndex = 0;
for (int index0 = 0; index0 < polygon.VerticesPerPolygon.Count; index0++)
{
int count = polygon.VerticesPerPolygon[index0];

Gl.glBegin(Gl.GL_POLYGON);
for (int index = 0; index < count; index++)
{
int indice = polygon.Indices[indiceIndex];
Vector3 vertex = polygon.Vertices[indice];
Vector3 normal = polygon.Normals[indice];

Gl.glVertex3d(vertex.x, vertex.y, vertex.z);
Gl.glNormal3d(normal.x, normal.y, normal.z);

indiceIndex++;
}
Gl.glEnd();
}
}



Here is the code that calculate the normals of the polygon (class PolygonGeometry.cs)

override public void UpdateNormals()
{
base.UpdateNormals();

if (Indices.Count == 0 ||
Normals.Count > 0) // Already calculated
return;

Normals.Clear();

Vector3[] sum = new Vector3[Vertices.Count];

int posInIndices = 0;
for (int index = 0; index < VerticesPerPolygon.Count; index++)
{
int verticesCount = VerticesPerPolygon[index];
for (int index0 = 0; index0 < verticesCount; index0++)
{
Vector3 vertex = Vector3.Invalid.Clone();
Vector3 previousVertex = Vector3.Invalid.Clone();
Vector3 nextVertex = Vector3.Invalid.Clone();

int indice = Indices[posInIndices];
vertex = Vertices[indice];

if (index0 == 0)
{
int previousIndice = Indices[posInIndices + verticesCount - 1];
previousVertex = Vertices[previousIndice];

int nextIndice = Indices[posInIndices + 1];
nextVertex = Vertices[nextIndice];
}
else if (index0 > 0 && index0 < verticesCount - 1)
{
int previousIndice = Indices[posInIndices - 1];
previousVertex = Vertices[previousIndice];

int nextIndice = Indices[posInIndices + 1];
nextVertex = Vertices[nextIndice];
}
else if (index0 == verticesCount - 1)
{
int previousIndice = Indices[posInIndices - 1];
previousVertex = Vertices[previousIndice];

int nextIndice = Indices[posInIndices - verticesCount + 1];
nextVertex = Vertices[nextIndice];
}

//---- Calculate the surface normal
Vector3 surfaceNormal = CalculateNormal(previousVertex, vertex, nextVertex);

// Sum it at the vertex index
if (!surfaceNormal.IsInvalid)
{
sum[indice] += surfaceNormal;
}

//---- next
posInIndices++;
}
}

for (int index = 0; index < Vertices.Count; index++)
{
sum[index].Normalize();
Normals.Add(sum[index]);
}
}



Thanks

Share this post


Link to post
Share on other sites
I can't see anything wrong with your code. I think the way forward is to check your assumptions and try to narrow down the problem. A few ideas:

1. make sure it really is the normals that cause the 'faceted' appearence. To do this, I'd try rendering with all the normals set to (1, 0, 0), or something like that, which ought to appear evenly lit.

2. try turning off lighting and textures, and instead colouring the vertices according to some function of 'indice', for example ((indice % 2) * 255, ((indice / 2) % 2) * 255, ((indice / 4) % 2) * 255). We should be able to see if the vertices are being shared correctly.

Does anybody have any other suggestions?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!