// --- render a single face --- /// <summary>Renders a face of a face-vertex mesh.</summary> /// <param name="mesh">The face-vertex mesh.</param> /// <param name="faceIndex">The face of the mesh to render.</param> /// <param name="position">The position of the face.</param> /// <param name="orientation">The orientation of the face.</param> /// <param name="state">The current OpenGL state.</param> /// <remarks>This function may change the texture or emissive color in the current OpenGL state.</remarks> private static void RenderFace(OpenBveApi.Geometry.FaceVertexMesh mesh, int faceIndex, OpenBveApi.Math.Vector3 position, OpenBveApi.Math.Orientation3 orientation, ref OpenGlState state) { int material = mesh.Faces[faceIndex].Material; /* * Set the texture. * */ Textures.ApiHandle apiHandle = mesh.Materials[material].DaytimeTexture as Textures.ApiHandle; int textureIndex = apiHandle != null ? apiHandle.TextureIndex : -1; if (textureIndex >= 0 && Textures.RegisteredTextures[textureIndex].Status == Textures.TextureStatus.Loaded) { int openGlTextureIndex = Textures.RegisteredTextures[textureIndex].OpenGlTextureIndex; state.BindTexture(openGlTextureIndex); } else { state.UnbindTexture(); } /* * Begin rendering the face. * */ switch (mesh.Faces[faceIndex].Type) { case OpenBveApi.Geometry.FaceType.Triangles: Gl.glBegin(Gl.GL_TRIANGLES); break; case OpenBveApi.Geometry.FaceType.TriangleStrip: Gl.glBegin(Gl.GL_TRIANGLE_STRIP); break; case OpenBveApi.Geometry.FaceType.TriangleFan: Gl.glBegin(Gl.GL_TRIANGLE_FAN); break; case OpenBveApi.Geometry.FaceType.Quads: Gl.glBegin(Gl.GL_QUADS); break; case OpenBveApi.Geometry.FaceType.QuadStrip: Gl.glBegin(Gl.GL_QUAD_STRIP); break; case OpenBveApi.Geometry.FaceType.Polygon: Gl.glBegin(Gl.GL_POLYGON); break; default: throw new InvalidOperationException(); } /* * Set the emissive color. * */ OpenBveApi.Color.ColorRGB emissiveColor = mesh.Materials[material].EmissiveColor; state.SetEmissiveColor(emissiveColor); /* * Render the vertices of the face. * */ for (int j = 0; j < mesh.Faces[faceIndex].Vertices.Length; j++) { int vertex = mesh.Faces[faceIndex].Vertices[j]; OpenBveApi.Math.Vector3 spatialCoordinates = mesh.Vertices[vertex].SpatialCoordinates; spatialCoordinates.Rotate(orientation); spatialCoordinates.Translate(position); OpenBveApi.Math.Vector3 normal = mesh.Vertices[vertex].Normal; normal.Rotate(orientation); Gl.glColor4f(mesh.Vertices[vertex].ReflectiveColor.R, mesh.Vertices[vertex].ReflectiveColor.G, mesh.Vertices[vertex].ReflectiveColor.B, mesh.Vertices[vertex].ReflectiveColor.A); Gl.glNormal3d(normal.X, normal.Y, normal.Z); Gl.glTexCoord2d(mesh.Vertices[vertex].TextureCoordinates.X, mesh.Vertices[vertex].TextureCoordinates.Y); Gl.glVertex3d(spatialCoordinates.X, spatialCoordinates.Y, spatialCoordinates.Z); } /* * End rendering the face. * */ Gl.glEnd(); }
// --- render specific kinds of objects --- /// <summary>Renders a solid-color polygon from an array of vertices.</summary> /// <param name="vertices">The vertices that describe the polygon.</param> /// <param name="reflectiveColor">The reflective color.</param> /// <param name="emissiveColor">The emissive color.</param> /// <remarks>This function may unbind the texture or change the emissive color in the current OpenGL state.</remarks> internal static void RenderPolygonFromVertices(OpenBveApi.Math.Vector3[] vertices, OpenBveApi.Color.ColorRGB reflectiveColor, OpenBveApi.Color.ColorRGB emissiveColor, ref OpenGlState state) { /* * Begin rendering the polygon. * */ state.UnbindTexture(); Gl.glBegin(Gl.GL_POLYGON); state.SetEmissiveColor(emissiveColor); /* * Render the vertices. * */ OpenBveApi.Math.Vector3 normal; OpenBveApi.Math.Vector3.CreateNormal(vertices[0], vertices[1], vertices[2], out normal); for (int i = 0; i < vertices.Length; i++) { Gl.glColor3f(reflectiveColor.R, reflectiveColor.G, reflectiveColor.B); Gl.glNormal3d(normal.X, normal.Y, normal.Z); Gl.glVertex3d(vertices[i].X, vertices[i].Y, vertices[i].Z); } /* * End rendering the polygon. * */ Gl.glEnd(); }