Beispiel #1
0
 /// <summary>Renders the opaque part of a set of specified static objects.</summary>
 /// <param name="objects">The list of static objects.</param>
 /// <param name="count">The number of static objects.</param>
 /// <param name="count">The current OpenGL state.</param>
 /// <remarks>This function may change the texture or emissive color in the current OpenGL state.</remarks>
 internal static void RenderStaticOpaqueObjects(ObjectGrid.StaticOpaqueObject[] objects, int count, ref OpenGlState state)
 {
     /*
      * Count the number of faces.
      * */
     int faceCount = 0;
     for (int i = 0; i < count; i++) {
         OpenBveApi.Geometry.FaceVertexMesh mesh = ObjectLibrary.Library.Objects[objects[i].LibraryIndex] as OpenBveApi.Geometry.FaceVertexMesh;
         if (mesh != null) {
             faceCount += mesh.Faces.Length;
         }
     }
     /*
      * Sort the faces by shared material properties. This will later increase
      * rendering speed as fewer state changes will be involved in OpenGL.
      * */
     Face[] faces = new Face[faceCount];
     long[] keys = new long[faceCount];
     faceCount = 0;
     for (int i = 0; i < count; i++) {
         OpenBveApi.Geometry.FaceVertexMesh mesh = ObjectLibrary.Library.Objects[objects[i].LibraryIndex] as OpenBveApi.Geometry.FaceVertexMesh;
         if (mesh != null) {
             for (int j = 0; j < mesh.Faces.Length; j++) {
                 int material = mesh.Faces[j].Material;
                 long texture =
                     mesh.Materials[material].DaytimeTexture is Textures.ApiHandle ?
                     (long)(((Textures.ApiHandle)mesh.Materials[material].DaytimeTexture).TextureIndex) + 1 :
                     (long)0;
                 long emissive =
                     (long)(255.0f * mesh.Materials[material].EmissiveColor.R) |
                     (long)(255.0f * mesh.Materials[material].EmissiveColor.G) << 8 |
                     (long)(255.0f * mesh.Materials[material].EmissiveColor.B) << 16;
                 faces[faceCount] = new Face(i, j);
                 keys[faceCount] = texture | emissive << 32;
                 faceCount++;
             }
         }
     }
     Array.Sort<long, Face>(keys, faces);
     /*
      * Render the faces.
      * */
     state.SetAlphaFunction(Gl.GL_EQUAL, 1.0f);
     for (int i = 0; i < faceCount; i++) {
         int objectIndex = faces[i].ObjectIndex;
         OpenBveApi.Geometry.FaceVertexMesh mesh = ObjectLibrary.Library.Objects[objects[objectIndex].LibraryIndex] as OpenBveApi.Geometry.FaceVertexMesh;
         if (mesh != null) {
             int material = mesh.Faces[faces[i].FaceIndex].Material;
             if (mesh.Materials[material].BlendMode == OpenBveApi.Geometry.BlendMode.Normal) {
                 RenderFace(mesh, faces[i].FaceIndex, objects[objectIndex].GridPosition, objects[objectIndex].GridOrientation, ref state);
             }
         }
     }
 }
Beispiel #2
0
 // --- 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();
 }
Beispiel #3
0
 // --- 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();
 }