Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Normals generator

  1. #1
    Junior Member Newbie
    Join Date
    May 2008
    Posts
    15

    Normals generator

    I have this function that I want to generate normals for on it's own.It work's fine. But Its really ugly and tacky. I just wanna be able to call it and that is it. But I have a function normalise. But I doubt that will determine what way it is supposely be looking at.

    MATH_INLINE void glNormal3d(Vec3& p1, Vec3& p2)
    {
    Vec3 v = Vec3(x, y, z);
    Vec3 v1 = p1 - v;
    Vec3 v2 = p2 - p1;
    Vec3 normal = Vec3(v1.cross(v2));
    normal.normalise();
    normal.printVec3();
    glNormal3dv(normal.ptr());
    }

    glBegin(GL_TRIANGLES);
    verts[0].glNormal3d(verts[1], verts[2]); verts[0].glVertex3d();
    verts[1].glNormal3d(verts[2], verts[0]); verts[1].glVertex3d();
    verts[2].glNormal3d(verts[0], verts[1]); verts[2].glVertex3d();
    glEnd();

  2. #2

    Re: Normals generator

    My 3DS-to-P3D (custom format) converter does something similar and it works. Did you check if yours really works? (you said you're in doubt, right?) Here's the code if you want to check, feel free to adapt it to your work if you want:
    Code :
          u[0] = vertices[polygons[i].vertex[0]].coords[0] -
                 vertices[polygons[i].vertex[1]].coords[0];
          u[1] = vertices[polygons[i].vertex[0]].coords[1] -
                 vertices[polygons[i].vertex[1]].coords[1];
          u[2] = vertices[polygons[i].vertex[0]].coords[2] -
                 vertices[polygons[i].vertex[1]].coords[2];
          v[0] = vertices[polygons[i].vertex[1]].coords[0] -
                 vertices[polygons[i].vertex[2]].coords[0];
          v[1] = vertices[polygons[i].vertex[1]].coords[1] -
                 vertices[polygons[i].vertex[2]].coords[1];
          v[2] = vertices[polygons[i].vertex[1]].coords[2] -
                 vertices[polygons[i].vertex[2]].coords[2];
     
          polygons[i].normal[0] = u[1] * v[2] - u[2] * v[1];
          polygons[i].normal[1] = u[2] * v[0] - u[0] * v[2];
          polygons[i].normal[2] = u[0] * v[1] - u[1] * v[0];
     
          factor = sqrt(polygons[i].normal[0] * polygons[i].normal[0] +
                        polygons[i].normal[1] * polygons[i].normal[1] +
                        polygons[i].normal[2] * polygons[i].normal[2]);

  3. #3
    Junior Member Newbie
    Join Date
    May 2008
    Posts
    15

    Re: Normals generator

    No the code gives me the correct one. but the vector normalise itself. if I was to do

    Vec3d v = Vec3d(3.4, 4.6, -2.0);
    v.normalise();
    glNormal3dv(v.ptr());

  4. #4
    Senior Member OpenGL Pro dletozeun's Avatar
    Join Date
    Jan 2006
    Location
    FRANCE
    Posts
    1,367

    Re: Normals generator

    Quote Originally Posted by Eckos
    No the code gives me the correct one. but the vector normalise itself. if I was to do

    Vec3d v = Vec3d(3.4, 4.6, -2.0);
    v.normalise();
    glNormal3dv(v.ptr());
    Where is the question here?

  5. #5
    Member Regular Contributor
    Join Date
    Jan 2004
    Posts
    314

    Re: Normals generator

    Eckos, if I understand correctly, you think your code should be simpler.
    Since for lighting, any normal needs to be of unit length, I'm pretty certain you'll need to call your normalise function at some point (which I assume makes it a unit vector).

    I see three odd things with your code:
    1. you pass in only two vertices instead of three vertices or two vectors - you seem to use a vertex member function when conceptually you are calculating a triangle normal, not a vertex normal.
    2. you use a Vec3 constructor for v, when you could just use (*this)
    3. the Vec3(v1.cross(v2)) bit seems redundant. Presumably your cross method already returns a Vec3, so you won't need to use a constructor or cast there.

    W.r.t. code structure, it may (may) be more elegant to just do a single glNormal call per triangle, with the three vertices passed into your function. Since direct mode uses a state machine approach, the same normal will be used until a new glNormal call is issued. If you don't want smoothed vertex normals, you can just use one glNormal, followed by the three glVertex calls.

    If you do want smoothed normals, you'll have to set the vertex normals to the average of the connected triangles' normals and then normalise them again. That's more of a preprocessing step I'm afraid (although it shouldn't very long on a modern machine).
    Once you have those stored somewhere, you'll obviously have to do one glNormal per vertex.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •