Takie's picture

debugging calculated vertex normals

I'm trying to make a X3D model viewer with applied smooth shading. The X3D file I'm parsing does not supply vertex normal data (or surface normal data for that matter). I have created a Vector3 array points[] with all my vertices in it and a int array index[] with the indices in it. Based on those two I calculate the vertex normals as follows:

    public void SetVertexNormals() {
        normals = new Vector3[points.Length];
 
        for (int i = 0; i < index.Length; i += 3) {
            Vector3 v0 = points[index[i]];
            Vector3 v1 = points[index[i + 1]];
            Vector3 v2 = points[index[i + 2]];
 
            Vector3 normal = Vector3.Normalize(Vector3.Cross(v2 - v0, v1 - v0));
 
            normals[index[i]] += normal;
            normals[index[i + 1]] += normal;
            normals[index[i + 2]] += normal;
        }
 
        for (int i = 0; i < points.Length; i++) {
            normals[i] = Vector3.Normalize(normals[i]);
        }
    }

So now I have a Vector3 array normals[] with all my vertex normals in it. I use VBO's to send those arrays to the GPU and this is the VBO related code part I use during OnRenderFrame:

	     GL.BindBuffer(BufferTarget.ArrayBuffer, vbo.vertexBufferID);
            GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, 0);
            GL.EnableClientState(ArrayCap.VertexArray);
 
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo.normalBufferID);
            GL.NormalPointer(NormalPointerType.Float, Vector3.SizeInBytes, 0);
            GL.EnableClientState(ArrayCap.NormalArray);
 
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, vbo.indiciesBufferID);
            GL.DrawElements(BeginMode.Triangles, vbo.Index.Length, DrawElementsType.UnsignedInt, 0);

The model is showing nicely, but I also would like to draw my vertex normals to see if they are ok. How do I do this?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jase's picture

For doing these sorts of debug visualisations I fall back to using immediate mode lines.

GL.LineWidth(2f);
GL.Color3(Color.White);
 
GL.Begin(BeginMode.Lines)
 
GL.Vertex3(Vector3.Zero);
GL.Vertex3(Vector3.One);
 
GL.End();

You just need to iterate through your faces/vertices and render each normal. It's slow, but since it's only a debug visualisation there's no need for it to be optimised.

migueltk's picture

You can create a buffer line "GL.DrawElements (BeginMode.Lines ..."and an array of vertices "GL.VertexPointer (3, VertexPointerType.Float ..." where the number of elements will be equal to the number of vertices multiplied by two.

Vector3 v1 = first point of the line
Vector3 v2 = second point of the line
Vector3 vn ​​= normal vector calculated
float debugNormalHeight = constant that determines the height of the line representing the normal

Vector3 v1 = v;
Vector3 v2 = v + (vn * debugNormalHeight)

I hope you find it useful.

P.D: It is interesting to your draft X3D file viewer, do you think share the code?