Example #1
0
        /// <summary>
        /// Creates a cached shader for the specifed shader, using the specified shader enumeration
        /// as a lookup key.
        /// </summary>
        private ShaderProgram CreateCachedShader(EverlookShader shader)
        {
            if (!Enum.IsDefined(typeof(EverlookShader), shader))
            {
                throw new ArgumentException("An unknown shader was passed to the rendering cache.", nameof(shader));
            }

            Log.Info($"Creating cached shader for \"{shader}\"");

            ShaderProgram shaderProgram;

            switch (shader)
            {
            case EverlookShader.Plain2D:
            {
                shaderProgram = new Plain2DShader();
                break;
            }

            case EverlookShader.WorldModel:
            {
                shaderProgram = new WorldModelShader();
                break;
            }

            case EverlookShader.BoundingBox:
            {
                shaderProgram = new BoundingBoxShader();
                break;
            }

            case EverlookShader.GameModel:
            {
                shaderProgram = new GameModelShader();
                break;
            }

            case EverlookShader.BaseGrid:
            {
                shaderProgram = new BaseGridShader();
                break;
            }

            default:
            {
                throw new ArgumentOutOfRangeException
                      (
                          nameof(shader),
                          "No implemented shader class for this shader."
                      );
            }
            }

            _shaderCache.Add(shader, shaderProgram);
            return(shaderProgram);
        }
Example #2
0
        /// <inheritdoc />
        public void Initialize()
        {
            ThrowIfDisposed();

            if (this.IsInitialized)
            {
                return;
            }

            this.IsInitialized = true;

            this.Shader = this.Cache.GetShader(EverlookShader.WorldModel) as WorldModelShader;

            if (this.Shader == null)
            {
                throw new ShaderNullException(typeof(WorldModelShader));
            }

            InitializeDoodads();

            // TODO: Load and cache sound emitters

            // Load the textures used in this model
            foreach (string texture in this.Model.GetTextures())
            {
                if (!string.IsNullOrEmpty(texture))
                {
                    if (!this.TextureLookup.ContainsKey(texture))
                    {
                        this.TextureLookup.Add(texture, this.Cache.GetTexture(texture, this.GameContext.Assets));
                    }
                }
            }

            // TODO: Upload visible block vertices

            // TODO: Upload portal vertices for debug rendering

            // TODO: Load lights into some sort of reasonable structure

            // TODO: Load fog as OpenGL fog

            // TODO: Implement antiportal handling. For now, skip them

            // TODO: Upload convex planes for debug rendering
            foreach (ModelGroup modelGroup in this.Model.Groups)
            {
                InitializeModelGroup(modelGroup);
            }

            this.IsInitialized = true;
        }
Example #3
0
        /// <summary>
        /// Initializes the required data for rendering.
        /// </summary>
        public void Initialize()
        {
            this.Shader = this.Cache.GetShader(EverlookShader.WorldModel) as WorldModelShader;

            if (this.Shader == null)
            {
                throw new ShaderNullException(typeof(WorldModelShader));
            }

            this.Shader.Wireframe.SetWireframeColour(EverlookConfiguration.Instance.GetWireframeColour());

            // TODO: Load and cache doodads in their respective sets

            // TODO: Load and cache sound emitters

            // Load the textures used in this model
            foreach (string texture in this.Model.GetTextures())
            {
                if (!string.IsNullOrEmpty(texture))
                {
                    CacheTexture(texture);
                }
            }

            // TODO: Upload visible block vertices

            // TODO: Upload portal vertices for debug rendering

            // TODO: Load lights into some sort of reasonable structure

            // TODO: Load fog as OpenGL fog

            // TODO: Implement antiportal handling. For now, skip them

            // TODO: Upload convex planes for debug rendering

            // TODO: Upload vertices, UVs and normals of groups in parallel buffers
            foreach (ModelGroup modelGroup in this.Model.Groups)
            {
                /*
                 *      Buffers
                 */

                int vertexBufferID;
                GL.GenBuffers(1, out vertexBufferID);

                int normalBufferID;
                GL.GenBuffers(1, out normalBufferID);

                int coordinateBufferID;
                GL.GenBuffers(1, out coordinateBufferID);

                int vertexIndicesID;
                GL.GenBuffers(1, out vertexIndicesID);

                int boundingBoxVertexBufferID;
                GL.GenBuffers(1, out boundingBoxVertexBufferID);

                // Upload all of the vertices in this group
                float[] groupVertexValues = modelGroup
                                            .GetVertices()
                                            .Select(v => v.Flatten())
                                            .SelectMany(f => f)
                                            .ToArray();

                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferID);
                GL.BufferData
                (
                    BufferTarget.ArrayBuffer,
                    (IntPtr)(groupVertexValues.Length * sizeof(float)),
                    groupVertexValues,
                    BufferUsageHint.StaticDraw
                );

                this.VertexBufferLookup.Add(modelGroup, vertexBufferID);

                // Upload all of the normals in this group
                float[] groupNormalValues = modelGroup
                                            .GetNormals()
                                            .Select(v => v.Flatten())
                                            .SelectMany(f => f)
                                            .ToArray();

                GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferID);
                GL.BufferData
                (
                    BufferTarget.ArrayBuffer,
                    (IntPtr)(groupNormalValues.Length * sizeof(float)),
                    groupNormalValues,
                    BufferUsageHint.StaticDraw
                );

                this.NormalBufferLookup.Add(modelGroup, normalBufferID);

                // Upload all of the UVs in this group
                float[] groupTextureCoordinateValues = modelGroup
                                                       .GetTextureCoordinates()
                                                       .Select(v => v.Flatten())
                                                       .SelectMany(f => f)
                                                       .ToArray();

                GL.BindBuffer(BufferTarget.ArrayBuffer, coordinateBufferID);
                GL.BufferData
                (
                    BufferTarget.ArrayBuffer,
                    (IntPtr)(groupTextureCoordinateValues.Length * sizeof(float)),
                    groupTextureCoordinateValues,
                    BufferUsageHint.StaticDraw
                );

                this.TextureCoordinateBufferLookup.Add(modelGroup, coordinateBufferID);

                // Upload vertex indices for this group
                ushort[] groupVertexIndexValuesArray = modelGroup.GetVertexIndices().ToArray();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, vertexIndicesID);
                GL.BufferData
                (
                    BufferTarget.ElementArrayBuffer,
                    (IntPtr)(groupVertexIndexValuesArray.Length * sizeof(ushort)),
                    groupVertexIndexValuesArray,
                    BufferUsageHint.StaticDraw
                );

                this.VertexIndexBufferLookup.Add(modelGroup, vertexIndicesID);

                // Upload the corners of the bounding box
                float[] boundingBoxVertices = modelGroup.GetBoundingBox()
                                              .ToOpenGLBoundingBox()
                                              .GetCorners()
                                              .Select(v => v.AsSIMDVector().Flatten())
                                              .SelectMany(f => f)
                                              .ToArray();

                GL.BindBuffer(BufferTarget.ArrayBuffer, boundingBoxVertexBufferID);
                GL.BufferData
                (
                    BufferTarget.ArrayBuffer,
                    (IntPtr)(boundingBoxVertices.Length * sizeof(float)),
                    boundingBoxVertices,
                    BufferUsageHint.StaticDraw
                );

                this.BoundingBoxVertexBufferLookup.Add(modelGroup, boundingBoxVertexBufferID);
            }

            // The bounding box indices never differ for objects, so we'll initialize that here
            int boundingBoxVertexIndicesBufferID;

            GL.GenBuffers(1, out boundingBoxVertexIndicesBufferID);
            this.BoundingBoxVertexIndexBufferID = boundingBoxVertexIndicesBufferID;

            byte[] boundingBoxIndexValuesArray =
            {
                0, 1, 1, 2,
                2, 3, 3, 0,
                0, 4, 4, 7,
                7, 3, 2, 6,
                6, 7, 6, 5,
                5, 4, 5, 1
            };

            GL.BindBuffer(BufferTarget.ArrayBuffer, boundingBoxVertexIndicesBufferID);
            GL.BufferData
            (
                BufferTarget.ArrayBuffer,
                (IntPtr)(boundingBoxIndexValuesArray.Length * sizeof(byte)),
                boundingBoxIndexValuesArray,
                BufferUsageHint.StaticDraw
            );

            this.IsInitialized = true;
        }