/// <summary> /// This function generates normals for every vertex. /// </summary> /// <param name="parent">The parent polygon.</param> public void GenerateNormals(Polygon parent) { if (Indices.Count >= 3) { foreach (Index index in Indices) { // Do we have enough vertices for a normal? if (Indices.Count >= 3) { // Create a normal. Vertex vNormal = GetSurfaceNormal(parent); vNormal.UnitLength(); // Add it to the normals, setting the index for next time. if (index.Normal != -1) { parent.Normals.RemoveAt(index.Normal); } index.Normal = parent.Normals.Add(new Normal(vNormal)); } } } }
/// <summary> /// Render to the provided instance of OpenGL. /// </summary> /// <param name="gl">The OpenGL instance.</param> /// <param name="renderMode">The render mode.</param> public virtual void Render(OpenGL gl, RenderMode renderMode) { // If we're frozen, use the helper. if (freezableHelper.IsFrozen) { freezableHelper.Render(gl); return; } // Go through each face. foreach (Face face in faces) { // If the face has its own material, push it. if (face.Material != null) { face.Material.Push(gl); } // Begin drawing a polygon. if (face.Indices.Count == 2) { gl.Begin(OpenGL.GL_LINES); } else { gl.Begin(OpenGL.GL_POLYGON); } foreach (Index index in face.Indices) { // Set a texture coord (if any). if (index.UV != -1) { gl.TexCoord(uvs[index.UV]); } // Set a normal, or generate one. if (index.Normal != -1) { gl.Normal(normals[index.Normal]); } else { // Do we have enough vertices for a normal? if (face.Indices.Count >= 3) { // Create a normal. Vertex vNormal = face.GetSurfaceNormal(this); vNormal.UnitLength(); // todo use auto smoothing instead // Add it to the normals, setting the index for next time. normals.Add(vNormal); index.Normal = normals.Count - 1; gl.Normal(vNormal); } } // Set the vertex. gl.Vertex(vertices[index.Vertex]); } gl.End(); // If the face has its own material, pop it. if (face.Material != null) { face.Material.Pop(gl); } } // Draw normals if we have to. if (drawNormals) { // Set the colour to red. gl.PushAttrib(OpenGL.GL_ALL_ATTRIB_BITS); gl.Color(1, 0, 0, 1); gl.Disable(OpenGL.GL_LIGHTING); // Go through each face. foreach (Face face in faces) { // Go though each index. foreach (Index index in face.Indices) { // Make sure it's got a normal, and a vertex. if (index.Normal != -1 && index.Vertex != -1) { // Get the vertex. Vertex vertex = vertices[index.Vertex]; // Get the normal vertex. Vertex normal = normals[index.Normal]; Vertex vertex2 = vertex + normal; gl.Begin(OpenGL.GL_LINES); gl.Vertex(vertex); gl.Vertex(vertex2); gl.End(); } } } // Restore the attributes. gl.PopAttrib(); } }