Beispiel #1
0
        /// <summary>Renders an object based background</summary>
        /// <param name="data">The background object</param>
        private void RenderBackgroundObject(BackgroundObject data)
        {
            if (renderer.AvailableNewRenderer)
            {
                renderer.DefaultShader.Activate();
                renderer.DefaultShader.SetCurrentProjectionMatrix(renderer.CurrentProjectionMatrix);

                if (data.Object.Mesh.VAO == null)
                {
                    VAOExtensions.CreateVAO(ref data.Object.Mesh, false, renderer.DefaultShader.VertexLayout);
                }
            }

            foreach (MeshFace face in data.Object.Mesh.Faces)
            {
                OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;

                if (data.Object.Mesh.Materials[face.Material].DaytimeTexture != null)
                {
                    if (data.Object.Mesh.Materials[face.Material].WrapMode == null)
                    {
                        foreach (VertexTemplate vertex in data.Object.Mesh.Vertices)
                        {
                            if (vertex.TextureCoordinates.X < 0.0f || vertex.TextureCoordinates.X > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.RepeatClamp;
                            }

                            if (vertex.TextureCoordinates.Y < 0.0f || vertex.TextureCoordinates.Y > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.ClampRepeat;
                            }
                        }

                        data.Object.Mesh.Materials[face.Material].WrapMode = wrap;
                    }
                }

                if (renderer.AvailableNewRenderer)
                {
                    renderer.RenderFace(renderer.DefaultShader, new ObjectState {
                        Prototype = data.Object
                    }, face, Matrix4D.NoTransformation, Matrix4D.Scale(1.0) * renderer.CurrentViewMatrix);
                }
                else
                {
                    renderer.RenderFaceImmediateMode(new ObjectState {
                        Prototype = data.Object
                    }, face, Matrix4D.NoTransformation, Matrix4D.Scale(1.0) * renderer.CurrentViewMatrix);
                }
            }

            if (renderer.AvailableNewRenderer)
            {
                renderer.DefaultShader.Deactivate();
            }
        }
Beispiel #2
0
        /// <summary>Makes an object visible within the world for selection</summary>
        /// <param name="ObjectIndex">The object's index</param>
        private static void ShowObjectSelection(int ObjectIndex)
        {
            if (ObjectManager.Objects[ObjectIndex] == null)
            {
                return;
            }
            if (ObjectManager.Objects[ObjectIndex].RendererIndex == 0)
            {
                if (ObjectCount >= Objects.Length)
                {
                    Array.Resize(ref Objects, Objects.Length << 1);
                }
                Objects[ObjectCount].ObjectIndex = ObjectIndex;
                Objects[ObjectCount].Type        = ObjectType.Overlay;
                int f = ObjectManager.Objects[ObjectIndex].Mesh.Faces.Length;
                Objects[ObjectCount].FaceListReferences = new ObjectListReference[f];
                for (int i = 0; i < f; i++)
                {
                    int k = ObjectManager.Objects[ObjectIndex].Mesh.Faces[i].Material;
                    OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;
                    if (Touch.FaceCount == Touch.Faces.Length)
                    {
                        Array.Resize(ref Touch.Faces, Touch.Faces.Length << 1);
                    }
                    Touch.Faces[Touch.FaceCount] = new ObjectFace
                    {
                        ObjectListIndex = ObjectCount,
                        ObjectIndex     = ObjectIndex,
                        FaceIndex       = i,
                        Wrap            = wrap
                    };

                    // HACK: Let's store the wrapping mode.

                    Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(ObjectListType.Touch, Touch.FaceCount);
                    Touch.FaceCount++;
                }
                ObjectManager.Objects[ObjectIndex].RendererIndex = ObjectCount + 1;
                ObjectCount++;
            }
        }
Beispiel #3
0
        /// <summary>Renders an object based background</summary>
        /// <param name="data">The background object</param>
        private void RenderBackgroundObject(BackgroundObject data)
        {
            if (data.Object.Mesh.VAO == null)
            {
                VAOExtensions.CreateVAO(ref data.Object.Mesh, false);
            }

            foreach (MeshFace face in data.Object.Mesh.Faces)
            {
                OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;

                if (data.Object.Mesh.Materials[face.Material].DaytimeTexture != null)
                {
                    if (data.Object.Mesh.Materials[face.Material].WrapMode == null)
                    {
                        foreach (VertexTemplate vertex in data.Object.Mesh.Vertices)
                        {
                            if (vertex.TextureCoordinates.X < 0.0f || vertex.TextureCoordinates.X > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.RepeatClamp;
                            }

                            if (vertex.TextureCoordinates.Y < 0.0f || vertex.TextureCoordinates.Y > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.ClampRepeat;
                            }
                        }

                        data.Object.Mesh.Materials[face.Material].WrapMode = wrap;
                    }
                }

                renderer.DefaultShader.Activate();
                renderer.ResetShader(renderer.DefaultShader);
                renderer.RenderFace(renderer.DefaultShader, new ObjectState {
                    Prototype = data.Object
                }, face);
                renderer.DefaultShader.Deactivate();
            }
        }
Beispiel #4
0
        internal static void RenderBackground(BackgroundManager.BackgroundObject Object)
        {
            if (!TexturingEnabled)
            {
                GL.Enable(EnableCap.Texture2D);
                TexturingEnabled = true;
            }
            int Mat = -1;

            for (int i = 0; i < Object.ObjectBackground.Mesh.Faces.Length; i++)
            {
                int m = Object.ObjectBackground.Mesh.Faces[i].Material;
                if (m != Mat)
                {
                    OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;
                    for (int v = 0; v < Object.ObjectBackground.Mesh.Vertices.Length; v++)
                    {
                        if (Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.X <0.0f | Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                        {
                            wrap |= OpenGlTextureWrapMode.RepeatClamp;
                        }
                        if (Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.Y <0.0f | Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                        {
                            wrap |= OpenGlTextureWrapMode.ClampRepeat;
                        }
                    }

                    if (Object.ObjectBackground.Mesh.Materials[m].DaytimeTexture != null)
                    {
                        Textures.LoadTexture(Object.ObjectBackground.Mesh.Materials[m].DaytimeTexture, wrap);
                        GL.BindTexture(TextureTarget.Texture2D, Object.ObjectBackground.Mesh.Materials[m].DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                    }
                }
                int FaceType = Object.ObjectBackground.Mesh.Faces[i].Flags & MeshFace.FaceTypeMask;
                switch (FaceType)
                {
                case MeshFace.FaceTypeTriangles:
                    GL.Begin(PrimitiveType.Triangles);
                    break;

                case MeshFace.FaceTypeTriangleStrip:
                    GL.Begin(PrimitiveType.TriangleStrip);
                    break;

                case MeshFace.FaceTypeQuads:
                    GL.Begin(PrimitiveType.Quads);
                    break;

                case MeshFace.FaceTypeQuadStrip:
                    GL.Begin(PrimitiveType.QuadStrip);
                    break;

                default:
                    GL.Begin(PrimitiveType.Polygon);
                    break;
                }

                for (int j = 0; j < Object.ObjectBackground.Mesh.Faces[i].Vertices.Length; j++)
                {
                    GL.Color4(inv255 * (float)Object.ObjectBackground.Mesh.Materials[m].Color.R * 1.0f, inv255 * Object.ObjectBackground.Mesh.Materials[m].Color.G * 1.0f, inv255 * (float)Object.ObjectBackground.Mesh.Materials[m].Color.B * 1.0f, inv255 * (float)Object.ObjectBackground.Mesh.Materials[m].Color.A);
                    VertexTemplate v = Object.ObjectBackground.Mesh.Vertices[Object.ObjectBackground.Mesh.Faces[i].Vertices[j].Index];
                    if (v is ColoredVertex)
                    {
                        ColoredVertex vv = v as ColoredVertex;
                        GL.Color3(vv.Color.R, vv.Color.G, vv.Color.B);
                    }
                    GL.TexCoord2(v.TextureCoordinates.X, v.TextureCoordinates.Y);
                    GL.Vertex3(v.Coordinates.X, v.Coordinates.Y, v.Coordinates.Z);
                }
                GL.End();
            }
        }
Beispiel #5
0
        // --- load texture ---

        /// <summary>Loads the specified texture into OpenGL if not already loaded.</summary>
        /// <param name="handle">The handle to the registered texture.</param>
        /// <param name="wrap">The texture type indicating the clamp mode.</param>
        /// <returns>Whether loading the texture was successful.</returns>
        internal static bool LoadTexture(Texture handle, OpenGlTextureWrapMode wrap)
        {
            if (handle.OpenGlTextures[(int)wrap].Valid)
            {
                return(true);
            }
            else if (handle.Ignore)
            {
                return(false);
            }
            else
            {
                OpenBveApi.Textures.Texture texture;
                if (handle.Origin.GetTexture(out texture))
                {
                    if (texture.BitsPerPixel == 32)
                    {
                        int[] names = new int[1];
                        Gl.glGenTextures(1, names);
                        int error = Gl.glGetError();
                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, names[0]);
                        error = Gl.glGetError();
                        handle.OpenGlTextures[(int)wrap].Name = names[0];
                        handle.Width        = texture.Width;
                        handle.Height       = texture.Height;
                        handle.Transparency = texture.GetTransparencyType();
                        texture             = UpsizeToPowerOfTwo(texture);

//						int newWidth = Math.Min(texture.Width, 256);
//						int newHeight = Math.Min(texture.Height, 256);
//						texture = Resize(texture, newWidth, newHeight);

                        switch (Interface.CurrentOptions.Interpolation)
                        {
                        case Interface.InterpolationMode.NearestNeighbor:
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                            break;

                        case Interface.InterpolationMode.Bilinear:
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                            break;

                        case Interface.InterpolationMode.NearestNeighborMipmapped:
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_NEAREST);
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                            break;

                        case Interface.InterpolationMode.BilinearMipmapped:
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_LINEAR);
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                            break;

                        case Interface.InterpolationMode.TrilinearMipmapped:
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                            break;

                        default:
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                            break;
                        }
                        if ((wrap & OpenGlTextureWrapMode.RepeatClamp) != 0)
                        {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                        }
                        else
                        {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
                        }
                        if ((wrap & OpenGlTextureWrapMode.ClampRepeat) != 0)
                        {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
                        }
                        else
                        {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
                        }
                        if (Interface.CurrentOptions.Interpolation == Interface.InterpolationMode.NearestNeighbor & Interface.CurrentOptions.Interpolation == Interface.InterpolationMode.Bilinear)
                        {
                            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_FALSE);
                        }
                        else
                        {
                            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_TRUE);
                        }
                        if (Interface.CurrentOptions.Interpolation == Interface.InterpolationMode.AnisotropicFiltering)
                        {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, Interface.CurrentOptions.AnisotropicFilteringLevel);
                        }
                        if (handle.Transparency == OpenBveApi.Textures.TextureTransparencyType.Opaque)
                        {
                            /*
                             * If the texture is fully opaque, the alpha channel is not used.
                             * If the graphics driver and card support 24-bits per channel,
                             * it is best to convert the bitmap data to that format in order
                             * to save memory on the card. If the card does not support the
                             * format, it will likely be upconverted to 32-bits per channel
                             * again, and this is wasted effort.
                             * */
                            int    width = texture.Width;
                            int    height = texture.Height;
                            int    stride = (3 * (width + 1) >> 2) << 2;
                            byte[] oldBytes = texture.Bytes;
                            byte[] newBytes = new byte[stride * texture.Height];
                            int    i = 0, j = 0;
                            for (int y = 0; y < height; y++)
                            {
                                for (int x = 0; x < width; x++)
                                {
                                    newBytes[j + 0] = oldBytes[i + 0];
                                    newBytes[j + 1] = oldBytes[i + 1];
                                    newBytes[j + 2] = oldBytes[i + 2];
                                    i += 4;
                                    j += 3;
                                }
                                j += stride - 3 * width;
                            }
                            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB8, texture.Width, texture.Height, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, newBytes);
                        }
                        else
                        {
                            /*
                             * The texture uses its alpha channel, so send the bitmap data
                             * in 32-bits per channel as-is.
                             * */
                            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, texture.Width, texture.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, texture.Bytes);
                        }
                        handle.OpenGlTextures[(int)wrap].Valid = true;
                        return(true);
                    }
                }
            }
            handle.Ignore = true;
            return(false);
        }
Beispiel #6
0
 public override bool LoadTexture(Texture Texture, OpenGlTextureWrapMode wrapMode)
 {
     return(Program.Renderer.TextureManager.LoadTexture(Texture, wrapMode, CPreciseTimer.GetClockTicks(), Interface.CurrentOptions.Interpolation, Interface.CurrentOptions.AnisotropicFilteringLevel));
 }
Beispiel #7
0
 /// <summary>Loads a texture and returns the texture data.</summary>
 /// <param name="texture">Receives the texture.</param>
 /// <param name="wrapMode">The openGL wrap mode</param>
 /// <returns>Whether loading the texture was successful.</returns>
 public virtual bool LoadTexture(Textures.Texture texture, OpenGlTextureWrapMode wrapMode)
 {
     return(false);
 }
Beispiel #8
0
        public void ShowObject(ObjectState State, ObjectType Type)
        {
            bool result = AddObject(State);

            if (State.Prototype.Mesh.VAO == null)
            {
                VAOExtensions.CreateVAO(ref State.Prototype.Mesh, State.Prototype.Dynamic);
            }

            if (!result)
            {
                return;
            }

            foreach (MeshFace face in State.Prototype.Mesh.Faces)
            {
                OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;

                if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture != null || State.Prototype.Mesh.Materials[face.Material].NighttimeTexture != null)
                {
                    if (State.Prototype.Mesh.Materials[face.Material].WrapMode == null)
                    {
                        // If the object does not have a stored wrapping mode, determine it now
                        foreach (VertexTemplate vertex in State.Prototype.Mesh.Vertices)
                        {
                            if (vertex.TextureCoordinates.X < 0.0f || vertex.TextureCoordinates.X > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.RepeatClamp;
                            }

                            if (vertex.TextureCoordinates.Y < 0.0f || vertex.TextureCoordinates.Y > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.ClampRepeat;
                            }
                        }

                        State.Prototype.Mesh.Materials[face.Material].WrapMode = wrap;
                    }
                }

                bool alpha = false;

                if (Type == ObjectType.Overlay && camera.CurrentRestriction != CameraRestrictionMode.NotAvailable)
                {
                    alpha = true;
                }
                else if (State.Prototype.Mesh.Materials[face.Material].Color.A != 255)
                {
                    alpha = true;
                }
                else if (State.Prototype.Mesh.Materials[face.Material].BlendMode == MeshMaterialBlendMode.Additive)
                {
                    alpha = true;
                }
                else if (State.Prototype.Mesh.Materials[face.Material].GlowAttenuationData != 0)
                {
                    alpha = true;
                }
                else
                {
                    if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture != null)
                    {
                        currentHost.LoadTexture(State.Prototype.Mesh.Materials[face.Material].DaytimeTexture, (OpenGlTextureWrapMode)State.Prototype.Mesh.Materials[face.Material].WrapMode);

                        if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture.Transparency == TextureTransparencyType.Alpha)
                        {
                            alpha = true;
                        }
                        else if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture.Transparency == TextureTransparencyType.Partial && currentOptions.TransparencyMode == TransparencyMode.Quality)
                        {
                            alpha = true;
                        }
                    }

                    if (State.Prototype.Mesh.Materials[face.Material].NighttimeTexture != null)
                    {
                        currentHost.LoadTexture(State.Prototype.Mesh.Materials[face.Material].NighttimeTexture, (OpenGlTextureWrapMode)State.Prototype.Mesh.Materials[face.Material].WrapMode);

                        if (State.Prototype.Mesh.Materials[face.Material].NighttimeTexture.Transparency == TextureTransparencyType.Alpha)
                        {
                            alpha = true;
                        }
                        else if (State.Prototype.Mesh.Materials[face.Material].NighttimeTexture.Transparency == TextureTransparencyType.Partial && currentOptions.TransparencyMode == TransparencyMode.Quality)
                        {
                            alpha = true;
                        }
                    }
                }

                /*
                 * For all lists, insert the face at the end of the list.
                 * */
                List <FaceState> list;

                switch (Type)
                {
                case ObjectType.Static:
                case ObjectType.Dynamic:
                    list = alpha ? myAlphaFaces : myOpaqueFaces;
                    break;

                case ObjectType.Overlay:
                    list = alpha ? myOverlayAlphaFaces : myOverlayOpaqueFaces;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(Type), Type, null);
                }

                list.Add(new FaceState(State, face));
            }
        }
Beispiel #9
0
        // --- texture ---

        public override bool LoadTexture(Texture Texture, OpenGlTextureWrapMode wrapMode)
        {
            return(Program.Renderer.TextureManager.LoadTexture(Texture, wrapMode, Environment.TickCount, InterpolationMode.BilinearMipmapped, 16));
        }
Beispiel #10
0
        // --- load texture ---

        /// <summary>Loads the specified texture into OpenGL if not already loaded.</summary>
        /// <param name="handle">The handle to the registered texture.</param>
        /// <param name="wrap">The texture type indicating the clamp mode.</param>
        /// <param name="currentTicks">The current system clock-ticks</param>
        /// <param name="Interpolation">The interpolation mode to use when loading the texture</param>
        /// <param name="AnisotropicFilteringLevel">The anisotropic filtering level to use when loading the texture</param>
        /// <returns>Whether loading the texture was successful.</returns>
        public bool LoadTexture(Texture handle, OpenGlTextureWrapMode wrap, int currentTicks, InterpolationMode Interpolation, int AnisotropicFilteringLevel)
        {
            //Don't try to load a texture to a null handle, this is a seriously bad idea....
            if (handle == null || handle.OpenGlTextures == null)
            {
                return(false);
            }

            //Set last access time
            handle.LastAccess = currentTicks;

            if (handle.OpenGlTextures[(int)wrap].Valid)
            {
                return(true);
            }

            if (handle.Ignore)
            {
                return(false);
            }

            Texture texture;

            if (handle.Origin.GetTexture(out texture))
            {
                if (texture.BitsPerPixel == 32)
                {
                    int[] names = new int[1];
                    GL.GenTextures(1, names);
                    GL.BindTexture(TextureTarget.Texture2D, names[0]);
                    handle.OpenGlTextures[(int)wrap].Name = names[0];
                    handle.Width        = texture.Width;
                    handle.Height       = texture.Height;
                    handle.Transparency = texture.GetTransparencyType();
                    //texture = ResizeToPowerOfTwo(texture);

                    switch (Interpolation)
                    {
                    case InterpolationMode.NearestNeighbor:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
                        break;

                    case InterpolationMode.Bilinear:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Linear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;

                    case InterpolationMode.NearestNeighborMipmapped:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.NearestMipmapNearest);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
                        break;

                    case InterpolationMode.BilinearMipmapped:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.NearestMipmapLinear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;

                    case InterpolationMode.TrilinearMipmapped:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;

                    default:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;
                    }

                    if ((wrap & OpenGlTextureWrapMode.RepeatClamp) != 0)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Repeat);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.ClampToEdge);
                    }

                    if ((wrap & OpenGlTextureWrapMode.ClampRepeat) != 0)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Repeat);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.ClampToEdge);
                    }

                    if (Interpolation == InterpolationMode.NearestNeighbor || Interpolation == InterpolationMode.Bilinear)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 0);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1);
                    }

                    if (Interpolation == InterpolationMode.AnisotropicFiltering && AnisotropicFilteringLevel > 0)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, AnisotropicFilteringLevel);
                    }

                    if (handle.Transparency == TextureTransparencyType.Opaque)
                    {
                        /*
                         * If the texture is fully opaque, the alpha channel is not used.
                         * If the graphics driver and card support 24-bits per channel,
                         * it is best to convert the bitmap data to that format in order
                         * to save memory on the card. If the card does not support the
                         * format, it will likely be upconverted to 32-bits per channel
                         * again, and this is wasted effort.
                         * */
                        int    width = texture.Width;
                        int    height = texture.Height;
                        int    stride = (3 * (width + 1) >> 2) << 2;
                        byte[] oldBytes = texture.Bytes;
                        byte[] newBytes = new byte[stride * texture.Height];
                        int    i = 0, j = 0;

                        for (int y = 0; y < height; y++)
                        {
                            for (int x = 0; x < width; x++)
                            {
                                newBytes[j + 0] = oldBytes[i + 0];
                                newBytes[j + 1] = oldBytes[i + 1];
                                newBytes[j + 2] = oldBytes[i + 2];
                                i += 4;
                                j += 3;
                            }

                            j += stride - 3 * width;
                        }

                        GL.TexImage2D(TextureTarget.Texture2D, 0,
                                      PixelInternalFormat.Rgb8,
                                      texture.Width, texture.Height, 0,
                                      OpenTK.Graphics.OpenGL.PixelFormat.Rgb,
                                      PixelType.UnsignedByte, newBytes);
                    }
                    else
                    {
                        /*
                         * The texture uses its alpha channel, so send the bitmap data
                         * in 32-bits per channel as-is.
                         * */
                        GL.TexImage2D(TextureTarget.Texture2D, 0,
                                      PixelInternalFormat.Rgba8,
                                      texture.Width, texture.Height, 0,
                                      OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
                                      PixelType.UnsignedByte, texture.Bytes);
                    }

                    handle.OpenGlTextures[(int)wrap].Valid = true;
                    return(true);
                }
            }

            handle.Ignore = true;
            return(false);
        }
Beispiel #11
0
        /// <summary>Makes an object visible within the world</summary>
        /// <param name="ObjectIndex">The object's index</param>
        /// <param name="Type">Whether this is a static or dynamic object</param>
        internal static void ShowObject(int ObjectIndex, ObjectType Type)
        {
            if (ObjectManager.Objects[ObjectIndex] == null)
            {
                return;
            }
            if (ObjectManager.Objects[ObjectIndex].RendererIndex == 0)
            {
                if (ObjectCount >= Objects.Length)
                {
                    Array.Resize <Object>(ref Objects, Objects.Length << 1);
                }
                Objects[ObjectCount].ObjectIndex = ObjectIndex;
                Objects[ObjectCount].Type        = Type;
                int f = ObjectManager.Objects[ObjectIndex].Mesh.Faces.Length;
                Objects[ObjectCount].FaceListReferences = new ObjectListReference[f];
                for (int i = 0; i < f; i++)
                {
                    bool alpha = false;
                    int  k     = ObjectManager.Objects[ObjectIndex].Mesh.Faces[i].Material;
                    OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;
                    if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null | ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                    {
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode == null)
                        {
                            // If the object does not have a stored wrapping mode, determine it now
                            for (int v = 0; v < ObjectManager.Objects[ObjectIndex].Mesh.Vertices.Length; v++)
                            {
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                                {
                                    wrap |= OpenGlTextureWrapMode.RepeatClamp;
                                }
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                                {
                                    wrap |= OpenGlTextureWrapMode.ClampRepeat;
                                }
                            }
                        }
                        else
                        {
                            //Yuck cast, but we need the null, as otherwise requires rewriting the texture indexer
                            wrap = (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode;
                        }
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null)
                        {
                            if (Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture, wrap))
                            {
                                TextureTransparencyType type =
                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency;
                                if (type == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (type == TextureTransparencyType.Partial &&
                                         Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                {
                                    alpha = true;
                                }
                            }
                        }
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                        {
                            if (Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture, wrap))
                            {
                                TextureTransparencyType type =
                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency;
                                if (type == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (type == TextureTransparencyType.Partial &
                                         Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                {
                                    alpha = true;
                                }
                            }
                        }
                    }
                    if (Type == ObjectType.Overlay & Camera.CurrentRestriction != CameraRestrictionMode.NotAvailable)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].Color.A != 255)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].BlendMode == MeshMaterialBlendMode.Additive)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].GlowAttenuationData != 0)
                    {
                        alpha = true;
                    }
                    ObjectListType listType;
                    switch (Type)
                    {
                    case ObjectType.Static:
                        listType = alpha ? ObjectListType.DynamicAlpha : ObjectListType.StaticOpaque;
                        break;

                    case ObjectType.Dynamic:
                        listType = alpha ? ObjectListType.DynamicAlpha : ObjectListType.DynamicOpaque;
                        break;

                    case ObjectType.Overlay:
                        listType = alpha ? ObjectListType.OverlayAlpha : ObjectListType.OverlayOpaque;
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (listType == ObjectListType.StaticOpaque)
                    {
                        /*
                         * For the static opaque list, insert the face into
                         * the first vacant position in the matching group's list.
                         * */
                        int groupIndex = (int)ObjectManager.Objects[ObjectIndex].GroupIndex;
                        if (groupIndex >= StaticOpaque.Length)
                        {
                            if (StaticOpaque.Length == 0)
                            {
                                StaticOpaque = new ObjectGroup[16];
                            }
                            while (groupIndex >= StaticOpaque.Length)
                            {
                                Array.Resize <ObjectGroup>(ref StaticOpaque, StaticOpaque.Length << 1);
                            }
                        }
                        if (StaticOpaque[groupIndex] == null)
                        {
                            StaticOpaque[groupIndex] = new ObjectGroup();
                        }
                        ObjectList list     = StaticOpaque[groupIndex].List;
                        int        newIndex = list.FaceCount;
                        for (int j = 0; j < list.FaceCount; j++)
                        {
                            if (list.Faces[j] == null)
                            {
                                newIndex = j;
                                break;
                            }
                        }
                        if (newIndex == list.FaceCount)
                        {
                            if (list.FaceCount == list.Faces.Length)
                            {
                                Array.Resize <ObjectFace>(ref list.Faces, list.Faces.Length << 1);
                            }
                            list.FaceCount++;
                        }
                        list.Faces[newIndex] = new ObjectFace
                        {
                            ObjectListIndex = ObjectCount,
                            ObjectIndex     = ObjectIndex,
                            FaceIndex       = i,
                            Wrap            = wrap
                        };

                        // HACK: Let's store the wrapping mode.

                        StaticOpaque[groupIndex].Update            = true;
                        Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(listType, newIndex);
                        Game.InfoStaticOpaqueFaceCount++;

                        /*
                         * Check if the given object has a bounding box, and insert it to the end of the list of bounding boxes if required
                         */
                        if (ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox != null)
                        {
                            int Index = list.BoundingBoxes.Length;
                            for (int j = 0; j < list.BoundingBoxes.Length; j++)
                            {
                                if (list.Faces[j] == null)
                                {
                                    Index = j;
                                    break;
                                }
                            }
                            if (Index == list.BoundingBoxes.Length)
                            {
                                Array.Resize <BoundingBox>(ref list.BoundingBoxes, list.BoundingBoxes.Length << 1);
                            }
                            list.BoundingBoxes[Index].Upper = ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox[0];
                            list.BoundingBoxes[Index].Lower = ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox[1];
                        }
                    }
                    else
                    {
                        /*
                         * For all other lists, insert the face at the end of the list.
                         * */
                        ObjectList list;
                        switch (listType)
                        {
                        case ObjectListType.DynamicOpaque:
                            list = DynamicOpaque;
                            break;

                        case ObjectListType.DynamicAlpha:
                            list = DynamicAlpha;
                            break;

                        case ObjectListType.OverlayOpaque:
                            list = OverlayOpaque;
                            break;

                        case ObjectListType.OverlayAlpha:
                            list = OverlayAlpha;
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                        if (list.FaceCount == list.Faces.Length)
                        {
                            Array.Resize <ObjectFace>(ref list.Faces, list.Faces.Length << 1);
                        }
                        list.Faces[list.FaceCount] = new ObjectFace
                        {
                            ObjectListIndex = ObjectCount,
                            ObjectIndex     = ObjectIndex,
                            FaceIndex       = i,
                            Wrap            = wrap
                        };

                        // HACK: Let's store the wrapping mode.

                        Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(listType, list.FaceCount);
                        list.FaceCount++;
                    }
                }
                ObjectManager.Objects[ObjectIndex].RendererIndex = ObjectCount + 1;
                ObjectCount++;
            }
        }
Beispiel #12
0
        // --- load texture ---
        /// <summary>Loads the specified texture into OpenGL if not already loaded.</summary>
        /// <param name="handle">The handle to the registered texture.</param>
        /// <param name="wrap">The texture type indicating the clamp mode.</param>
        /// <returns>Whether loading the texture was successful.</returns>
        internal static bool LoadTexture(Texture handle, OpenGlTextureWrapMode wrap)
        {
            if (handle.OpenGlTextures[(int)wrap].Valid) {
                return true;
            } else if (handle.Ignore) {
                return false;
            } else {
                OpenBveApi.Textures.Texture texture;
                if (handle.Origin.GetTexture(out texture)) {
                    if (texture.BitsPerPixel == 32) {
                        int[] names = new int[1];
                        Gl.glGenTextures(1, names);
                        int error = Gl.glGetError();
                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, names[0]);
                        error = Gl.glGetError();
                        handle.OpenGlTextures[(int)wrap].Name = names[0];
                        handle.Width = texture.Width;
                        handle.Height = texture.Height;
                        handle.Transparency = texture.GetTransparencyType();
                        texture = UpsizeToPowerOfTwo(texture);

            //						int newWidth = Math.Min(texture.Width, 256);
            //						int newHeight = Math.Min(texture.Height, 256);
            //						texture = Resize(texture, newWidth, newHeight);

                        switch (Interface.CurrentOptions.Interpolation) {
                            case Interface.InterpolationMode.NearestNeighbor:
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                                break;
                            case Interface.InterpolationMode.Bilinear:
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                                break;
                            case Interface.InterpolationMode.NearestNeighborMipmapped:
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_NEAREST);
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                                break;
                            case Interface.InterpolationMode.BilinearMipmapped:
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_LINEAR);
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                                break;
                            case Interface.InterpolationMode.TrilinearMipmapped:
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                                break;
                            default:
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                                break;
                        }
                        if ((wrap & OpenGlTextureWrapMode.RepeatClamp) != 0) {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                        } else {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
                        }
                        if ((wrap & OpenGlTextureWrapMode.ClampRepeat) != 0) {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
                        } else {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
                        }
                        if (Interface.CurrentOptions.Interpolation == Interface.InterpolationMode.NearestNeighbor & Interface.CurrentOptions.Interpolation == Interface.InterpolationMode.Bilinear) {
                            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_FALSE);
                        } else {
                            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_TRUE);
                        }
                        if (Interface.CurrentOptions.Interpolation == Interface.InterpolationMode.AnisotropicFiltering) {
                            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, Interface.CurrentOptions.AnisotropicFilteringLevel);
                        }
                        if (handle.Transparency == OpenBveApi.Textures.TextureTransparencyType.Opaque) {
                            /*
                             * If the texture is fully opaque, the alpha channel is not used.
                             * If the graphics driver and card support 24-bits per channel,
                             * it is best to convert the bitmap data to that format in order
                             * to save memory on the card. If the card does not support the
                             * format, it will likely be upconverted to 32-bits per channel
                             * again, and this is wasted effort.
                             * */
                            int width = texture.Width;
                            int height = texture.Height;
                            int stride = (3 * (width + 1) >> 2) << 2;
                            byte[] oldBytes = texture.Bytes;
                            byte[] newBytes = new byte[stride * texture.Height];
                            int i = 0, j = 0;
                            for (int y = 0; y < height; y++) {
                                for (int x = 0; x < width; x++) {
                                    newBytes[j + 0] = oldBytes[i + 0];
                                    newBytes[j + 1] = oldBytes[i + 1];
                                    newBytes[j + 2] = oldBytes[i + 2];
                                    i += 4;
                                    j += 3;
                                }
                                j += stride - 3 * width;
                            }
                            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB8, texture.Width, texture.Height, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, newBytes);
                        } else {
                            /*
                             * The texture uses its alpha channel, so send the bitmap data
                             * in 32-bits per channel as-is.
                             * */
                            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, texture.Width, texture.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, texture.Bytes);
                        }
                        handle.OpenGlTextures[(int)wrap].Valid = true;
                        return true;
                    }
                }
            }
            handle.Ignore = true;
            return false;
        }
Beispiel #13
0
        public void ShowObject(ObjectState State, ObjectType Type)
        {
            bool result = AddObject(State);

            if (!renderer.ForceLegacyOpenGL && State.Prototype.Mesh.VAO == null)
            {
                VAOExtensions.CreateVAO(ref State.Prototype.Mesh, State.Prototype.Dynamic, renderer.DefaultShader.VertexLayout);
            }

            if (!result)
            {
                return;
            }

            foreach (MeshFace face in State.Prototype.Mesh.Faces)
            {
                OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;

                if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture != null || State.Prototype.Mesh.Materials[face.Material].NighttimeTexture != null)
                {
                    if (State.Prototype.Mesh.Materials[face.Material].WrapMode == null)
                    {
                        // If the object does not have a stored wrapping mode, determine it now
                        foreach (VertexTemplate vertex in State.Prototype.Mesh.Vertices)
                        {
                            if (vertex.TextureCoordinates.X < 0.0f || vertex.TextureCoordinates.X > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.RepeatClamp;
                            }

                            if (vertex.TextureCoordinates.Y < 0.0f || vertex.TextureCoordinates.Y > 1.0f)
                            {
                                wrap |= OpenGlTextureWrapMode.ClampRepeat;
                            }
                        }

                        State.Prototype.Mesh.Materials[face.Material].WrapMode = wrap;
                    }
                }

                bool alpha = false;

                if (Type == ObjectType.Overlay && camera.CurrentRestriction != CameraRestrictionMode.NotAvailable)
                {
                    alpha = true;
                }
                else if (State.Prototype.Mesh.Materials[face.Material].Color.A != 255)
                {
                    alpha = true;
                }
                else if (State.Prototype.Mesh.Materials[face.Material].BlendMode == MeshMaterialBlendMode.Additive)
                {
                    alpha = true;
                }
                else if (State.Prototype.Mesh.Materials[face.Material].GlowAttenuationData != 0)
                {
                    alpha = true;
                }
                else
                {
                    if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture != null)
                    {
                        currentHost.LoadTexture(State.Prototype.Mesh.Materials[face.Material].DaytimeTexture, (OpenGlTextureWrapMode)State.Prototype.Mesh.Materials[face.Material].WrapMode);

                        if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture.Transparency == TextureTransparencyType.Alpha)
                        {
                            alpha = true;
                        }
                        else if (State.Prototype.Mesh.Materials[face.Material].DaytimeTexture.Transparency == TextureTransparencyType.Partial && currentOptions.TransparencyMode == TransparencyMode.Quality)
                        {
                            alpha = true;
                        }
                    }

                    if (State.Prototype.Mesh.Materials[face.Material].NighttimeTexture != null)
                    {
                        currentHost.LoadTexture(State.Prototype.Mesh.Materials[face.Material].NighttimeTexture, (OpenGlTextureWrapMode)State.Prototype.Mesh.Materials[face.Material].WrapMode);

                        if (State.Prototype.Mesh.Materials[face.Material].NighttimeTexture.Transparency == TextureTransparencyType.Alpha)
                        {
                            alpha = true;
                        }
                        else if (State.Prototype.Mesh.Materials[face.Material].NighttimeTexture.Transparency == TextureTransparencyType.Partial && currentOptions.TransparencyMode == TransparencyMode.Quality)
                        {
                            alpha = true;
                        }
                    }
                }

                List <FaceState> list;

                switch (Type)
                {
                case ObjectType.Static:
                case ObjectType.Dynamic:
                    list = alpha ? myAlphaFaces : myOpaqueFaces;
                    break;

                case ObjectType.Overlay:
                    list = alpha ? myOverlayAlphaFaces : myOverlayOpaqueFaces;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(Type), Type, null);
                }

                if (!alpha)
                {
                    /*
                     * If an opaque face, itinerate through the list to see if the prototype is present in the list
                     * When the new renderer is in use, this prevents re-binding the VBO as it is simply re-drawn with
                     * a different translation matrix
                     * NOTE: The shader isn't currently smart enough to do depth discards, so if this changes may need to
                     * be revisited
                     */
                    if (list.Count == 0)
                    {
                        list.Add(new FaceState(State, face));
                    }
                    else
                    {
                        for (int i = 0; i < list.Count; i++)
                        {
                            if (list[i].Object.Prototype == State.Prototype)
                            {
                                list.Insert(i, new FaceState(State, face));
                                break;
                            }
                            if (i == list.Count - 1)
                            {
                                list.Add(new FaceState(State, face));
                                break;
                            }
                        }
                    }
                }
                else
                {
                    /*
                     * Alpha faces should be inserted at the end of the list- We're going to sort it anyway so it makes no odds
                     */
                    list.Add(new FaceState(State, face));
                }
            }
        }
Beispiel #14
0
		// --- load texture ---
		
		/// <summary>Loads the specified texture into OpenGL if not already loaded.</summary>
		/// <param name="handle">The handle to the registered texture.</param>
		/// <param name="wrap">The texture type indicating the clamp mode.</param>
		/// <returns>Whether loading the texture was successful.</returns>
		internal static bool LoadTexture(Texture handle, OpenGlTextureWrapMode wrap){
			if (handle.OpenGlTextures[(int)wrap].Valid)
				return true;
			if (handle.Ignore)
				return false;
			else {
				OpenBveApi.Textures.Texture texture;
				if (handle.Origin.GetTexture(out texture)) {
					if (texture.BitsPerPixel == 32) {
						int[] names = new int[1];
						GL.GenTextures(1, names);
						ErrorCode error = GL.GetError();
						GL.BindTexture(TextureTarget.Texture2D, names[0]);
						error = GL.GetError();
						handle.OpenGlTextures[(int)wrap].Name = names[0];
						handle.Width = texture.Width;
						handle.Height = texture.Height;
						handle.Transparency = texture.GetTransparencyType();
						texture = UpsizeToPowerOfTwo(texture);
						
//						int newWidth = Math.Min(texture.Width, 256);
//						int newHeight = Math.Min(texture.Height, 256);
//						texture = Resize(texture, newWidth, newHeight);
						
						switch (Options.Current.Interpolation) {
							case Options.InterpolationMode.NearestNeighbor:
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
								break;
							case Options.InterpolationMode.Bilinear:
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Linear);
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
								break;
							case Options.InterpolationMode.NearestNeighborMipmapped:
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.NearestMipmapNearest);
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
								break;
							case Options.InterpolationMode.BilinearMipmapped:
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.NearestMipmapLinear);
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
								break;
							case Options.InterpolationMode.TrilinearMipmapped:
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
								break;
							default:
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
								GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
								break;
						}
						if ((wrap & OpenGlTextureWrapMode.RepeatClamp) != 0) {
							GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Repeat);
						} else {
							GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.ClampToEdge);
						}
						if ((wrap & OpenGlTextureWrapMode.ClampRepeat) != 0) {
							GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Repeat);
						} else {
							GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.ClampToEdge);
						}
						if (Options.Current.Interpolation == Options.InterpolationMode.NearestNeighbor && Options.Current.Interpolation == Options.InterpolationMode.Bilinear) {
							GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 0);
						} else {
							GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1);
						}
						if (Options.Current.Interpolation == Options.InterpolationMode.AnisotropicFiltering) {
							GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, Options.Current.AnisotropicFilteringLevel);
						}
						if (handle.Transparency == OpenBveApi.Textures.TextureTransparencyType.Opaque) {
							/*
							 * If the texture is fully opaque, the alpha channel is not used.
							 * If the graphics driver and card support 24-bits per channel,
							 * it is best to convert the bitmap data to that format in order
							 * to save memory on the card. If the card does not support the
							 * format, it will likely be upconverted to 32-bits per channel
							 * again, and this is wasted effort.
							 * */
							int width = texture.Width;
							int height = texture.Height;
							int stride = (3 * (width + 1) >> 2) << 2;
							byte[] oldBytes = texture.Bytes;
							byte[] newBytes = new byte[stride * texture.Height];
							int i = 0, j = 0;
							for (int y = 0; y < height; y++) {
								for (int x = 0; x < width; x++) {
									newBytes[j + 0] = oldBytes[i + 0];
									newBytes[j + 1] = oldBytes[i + 1];
									newBytes[j + 2] = oldBytes[i + 2];
									i += 4;
									j += 3;
								}
								j += stride - 3 * width;
							}
							GL.TexImage2D(TextureTarget.Texture2D, 0, 
								PixelInternalFormat.Rgb8, 
								texture.Width, texture.Height, 0,
								OpenTK.Graphics.OpenGL.PixelFormat.Rgb, 
								PixelType.UnsignedByte, newBytes);
						} else {
							/*
							 * The texture uses its alpha channel, so send the bitmap data
							 * in 32-bits per channel as-is.
							 * */
							GL.TexImage2D(TextureTarget.Texture2D, 0, 
								PixelInternalFormat.Rgba8, 
								texture.Width, texture.Height, 0, 
								OpenTK.Graphics.OpenGL.PixelFormat.Rgba, 
								PixelType.UnsignedByte, texture.Bytes);
						}
						handle.OpenGlTextures[(int)wrap].Valid = true;
						return true;
					}
				}
			}
			handle.Ignore = true;
			return false;
		}
Beispiel #15
0
        private static void RenderFace(ref MeshMaterial Material, VertexTemplate[] Vertices, OpenGlTextureWrapMode wrap, ref MeshFace Face, double CameraX, double CameraY, double CameraZ)
        {
            // texture
            if (Material.DaytimeTexture != null)
            {
                if (Textures.LoadTexture(Material.DaytimeTexture, wrap))
                {
                    if (!TexturingEnabled)
                    {
                        GL.Enable(EnableCap.Texture2D);
                        TexturingEnabled = true;
                    }
                    if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture)
                    {
                        GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                        LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
                    }
                }
                else
                {
                    if (TexturingEnabled)
                    {
                        GL.Disable(EnableCap.Texture2D);
                        TexturingEnabled = false;
                        LastBoundTexture = null;
                    }
                }
            }
            else
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                    LastBoundTexture = null;
                }
            }
            // blend mode
            float factor;

            if (Material.BlendMode == MeshMaterialBlendMode.Additive)
            {
                factor = 1.0f;
                if (!BlendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                }
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
                if (FogEnabled)
                {
                    GL.Disable(EnableCap.Fog);
                }
            }
            else if (Material.NighttimeTexture == null)
            {
                float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                if (blend > 1.0f)
                {
                    blend = 1.0f;
                }
                factor = 1.0f - 0.7f * blend;
            }
            else
            {
                factor = 1.0f;
            }
            if (Material.NighttimeTexture != null)
            {
                if (LightingEnabled)
                {
                    GL.Disable(EnableCap.Lighting);
                    LightingEnabled = false;
                }
            }
            else
            {
                if (OptionLighting & !LightingEnabled)
                {
                    GL.Enable(EnableCap.Lighting);
                    LightingEnabled = true;
                }
            }
            // render daytime polygon
            int FaceType = Face.Flags & MeshFace.FaceTypeMask;

            switch (FaceType)
            {
            case MeshFace.FaceTypeTriangles:
                GL.Begin(PrimitiveType.Triangles);
                break;

            case MeshFace.FaceTypeTriangleStrip:
                GL.Begin(PrimitiveType.TriangleStrip);
                break;

            case MeshFace.FaceTypeQuads:
                GL.Begin(PrimitiveType.Quads);
                break;

            case MeshFace.FaceTypeQuadStrip:
                GL.Begin(PrimitiveType.QuadStrip);
                break;

            default:
                GL.Begin(PrimitiveType.Polygon);
                break;
            }
            if (Material.GlowAttenuationData != 0)
            {
                float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
                if (OptionWireframe)
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f);
                }
                else
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
                }
            }
            else
            {
                if (OptionWireframe)
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f);
                }
                else
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
                }
            }
            if ((Material.Flags & MeshMaterial.EmissiveColorMask) != 0)
            {
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
            }
            else
            {
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
            }
            if (Material.DaytimeTexture != null)
            {
                if (LightingEnabled)
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                        GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
                else
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
            }
            else
            {
                if (LightingEnabled)
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
                else
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
            }
            GL.End();
            // render nighttime polygon
            if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap))
            {
                if (!TexturingEnabled)
                {
                    GL.Enable(EnableCap.Texture2D);
                    TexturingEnabled = true;
                }
                if (!BlendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                }
                GL.BindTexture(TextureTarget.Texture2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
                LastBoundTexture = null;
                GL.AlphaFunc(AlphaFunction.Greater, 0.0f);
                GL.Enable(EnableCap.AlphaTest);
                switch (FaceType)
                {
                case MeshFace.FaceTypeTriangles:
                    GL.Begin(PrimitiveType.Triangles);
                    break;

                case MeshFace.FaceTypeTriangleStrip:
                    GL.Begin(PrimitiveType.TriangleStrip);
                    break;

                case MeshFace.FaceTypeQuads:
                    GL.Begin(PrimitiveType.Quads);
                    break;

                case MeshFace.FaceTypeQuadStrip:
                    GL.Begin(PrimitiveType.QuadStrip);
                    break;

                default:
                    GL.Begin(PrimitiveType.Polygon);
                    break;
                }
                float alphafactor;
                if (Material.GlowAttenuationData != 0)
                {
                    alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
                    float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }
                    alphafactor *= blend;
                }
                else
                {
                    alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                    if (alphafactor > 1.0f)
                    {
                        alphafactor = 1.0f;
                    }
                }
                if (OptionWireframe)
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f);
                }
                else
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
                }

                if ((Material.Flags & MeshMaterial.EmissiveColorMask) != 0)
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
                }
                else
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                    if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                    {
                        ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                        GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                    }
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                }
                GL.End();
                RestoreAlphaFunc();
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
            }
            // normals
            if (OptionNormals)
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.Begin(PrimitiveType.Lines);
                    GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
                    GL.End();
                }
            }
            // finalize
            if (Material.BlendMode == MeshMaterialBlendMode.Additive)
            {
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
                if (FogEnabled)
                {
                    GL.Enable(EnableCap.Fog);
                }
            }
        }
Beispiel #16
0
        // show object
        internal static void ShowObject(int ObjectIndex, ObjectType Type)
        {
            bool Overlay = Type == ObjectType.Overlay;

            if (ObjectManager.Objects[ObjectIndex] == null)
            {
                return;
            }
            if (ObjectManager.Objects[ObjectIndex].RendererIndex == 0)
            {
                if (ObjectListCount >= ObjectList.Length)
                {
                    Array.Resize <Object>(ref ObjectList, ObjectList.Length << 1);
                }
                ObjectList[ObjectListCount].ObjectIndex = ObjectIndex;
                ObjectList[ObjectListCount].Type        = Type;
                int f = ObjectManager.Objects[ObjectIndex].Mesh.Faces.Length;
                ObjectList[ObjectListCount].FaceListIndices = new int[f];
                for (int i = 0; i < f; i++)
                {
                    if (Overlay)
                    {
                        // overlay
                        if (OverlayListCount >= OverlayList.Length)
                        {
                            Array.Resize(ref OverlayList, OverlayList.Length << 1);
                            Array.Resize(ref OverlayListDistance, OverlayList.Length);
                        }
                        OverlayList[OverlayListCount].ObjectIndex      = ObjectIndex;
                        OverlayList[OverlayListCount].FaceIndex        = i;
                        OverlayList[OverlayListCount].ObjectListIndex  = ObjectListCount;
                        ObjectList[ObjectListCount].FaceListIndices[i] = (OverlayListCount << 2) + 3;
                        OverlayListCount++;
                    }
                    else
                    {
                        int k = ObjectManager.Objects[ObjectIndex].Mesh.Faces[i].Material;
                        OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;
                        bool transparentcolor = false, alpha = false;
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].Color.A != 255)
                        {
                            alpha = true;
                        }
                        else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].BlendMode == MeshMaterialBlendMode.Additive)
                        {
                            alpha = true;
                        }
                        else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].GlowAttenuationData != 0)
                        {
                            alpha = true;
                        }
                        else
                        {
                            if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null)
                            {
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode == null)
                                {
                                    // If the object does not have a stored wrapping mode, determine it now
                                    for (int v = 0; v < ObjectManager.Objects[ObjectIndex].Mesh.Vertices.Length; v++)
                                    {
                                        if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X <0.0f |
                                                                                                                      ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                                        {
                                            wrap |= OpenGlTextureWrapMode.RepeatClamp;
                                        }
                                        if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y <0.0f |
                                                                                                                      ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                                        {
                                            wrap |= OpenGlTextureWrapMode.ClampRepeat;
                                        }
                                    }

                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode = wrap;
                                }
                                else
                                {
                                    //Yuck cast, but we need the null, as otherwise requires rewriting the texture indexer
                                    wrap = (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode;
                                }
                                Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture, (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode);
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency == TextureTransparencyType.Partial)
                                {
                                    transparentcolor = true;
                                }
                            }
                            if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                            {
                                Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture, (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode);
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency == TextureTransparencyType.Partial)
                                {
                                    transparentcolor = true;
                                }
                            }
                        }
                        if (alpha)
                        {
                            // alpha
                            if (AlphaListCount >= AlphaList.Length)
                            {
                                Array.Resize(ref AlphaList, AlphaList.Length << 1);
                                Array.Resize(ref AlphaListDistance, AlphaList.Length);
                            }
                            AlphaList[AlphaListCount]                      = new ObjectFace();
                            AlphaList[AlphaListCount].ObjectIndex          = ObjectIndex;
                            AlphaList[AlphaListCount].FaceIndex            = i;
                            AlphaList[AlphaListCount].ObjectListIndex      = ObjectListCount;
                            AlphaList[AlphaListCount].Wrap                 = wrap;
                            ObjectList[ObjectListCount].FaceListIndices[i] = (AlphaListCount << 2) + 2;
                            AlphaListCount++;
                        }
                        else if (transparentcolor)
                        {
                            // transparent color
                            if (TransparentColorListCount >= TransparentColorList.Length)
                            {
                                Array.Resize(ref TransparentColorList, TransparentColorList.Length << 1);
                                Array.Resize(ref TransparentColorListDistance, TransparentColorList.Length);
                            }
                            TransparentColorList[TransparentColorListCount]                 = new ObjectFace();
                            TransparentColorList[TransparentColorListCount].ObjectIndex     = ObjectIndex;
                            TransparentColorList[TransparentColorListCount].FaceIndex       = i;
                            TransparentColorList[TransparentColorListCount].ObjectListIndex = ObjectListCount;
                            TransparentColorList[TransparentColorListCount].Wrap            = wrap;
                            ObjectList[ObjectListCount].FaceListIndices[i] = (TransparentColorListCount << 2) + 1;
                            TransparentColorListCount++;
                        }
                        else
                        {
                            // opaque
                            if (OpaqueListCount >= OpaqueList.Length)
                            {
                                Array.Resize(ref OpaqueList, OpaqueList.Length << 1);
                            }
                            OpaqueList[OpaqueListCount]                    = new ObjectFace();
                            OpaqueList[OpaqueListCount].ObjectIndex        = ObjectIndex;
                            OpaqueList[OpaqueListCount].FaceIndex          = i;
                            OpaqueList[OpaqueListCount].ObjectListIndex    = ObjectListCount;
                            OpaqueList[OpaqueListCount].Wrap               = wrap;
                            ObjectList[ObjectListCount].FaceListIndices[i] = OpaqueListCount << 2;
                            OpaqueListCount++;
                        }
                    }
                }
                ObjectManager.Objects[ObjectIndex].RendererIndex = ObjectListCount + 1;
                ObjectListCount++;
            }
        }