Exemplo n.º 1
0
 public MaterialRenderer(RenderMaterial renderMaterial)
 {
     material = renderMaterial;
     shader   = ShaderLoader.LoadPlaneShader(material.Material.ShaderName, material.Material.GetShaderArguments());
     quadVao  = SetupQuadBuffer();
 }
Exemplo n.º 2
0
        //Set up a draw call
        private DrawCall CreateDrawCall(Dictionary <string, KVValue> drawProperties, uint[] vertexBuffers, uint[] indexBuffers, ArgumentDependencies modelArguments, VBIB block, Material material)
        {
            var drawCall = new DrawCall();

            switch (drawProperties["m_nPrimitiveType"].Value.ToString())
            {
            case "RENDER_PRIM_TRIANGLES":
                drawCall.PrimitiveType = PrimitiveType.Triangles;
                break;

            default:
                throw new Exception("Unknown PrimitiveType in drawCall! (" + drawProperties["m_nPrimitiveType"].Value + ")");
            }

            drawCall.Material = material;

            // Load shader
            drawCall.Shader = ShaderLoader.LoadShader(drawCall.Material.Parameters.ShaderName, modelArguments);

            //Bind and validate shader
            GL.UseProgram(drawCall.Shader.Program);

            var f = (KVObject)drawProperties["m_indexBuffer"].Value;

            var indexBuffer = default(DrawBuffer);

            indexBuffer.Id       = Convert.ToUInt32(f.Properties["m_hBuffer"].Value);
            indexBuffer.Offset   = Convert.ToUInt32(f.Properties["m_nBindOffsetBytes"].Value);
            drawCall.IndexBuffer = indexBuffer;

            var bufferSize = block.IndexBuffers[(int)drawCall.IndexBuffer.Id].Size;

            drawCall.BaseVertex  = Convert.ToUInt32(drawProperties["m_nBaseVertex"].Value);
            drawCall.VertexCount = Convert.ToUInt32(drawProperties["m_nVertexCount"].Value);
            drawCall.StartIndex  = Convert.ToUInt32(drawProperties["m_nStartIndex"].Value) * bufferSize;
            drawCall.IndexCount  = Convert.ToInt32(drawProperties["m_nIndexCount"].Value);

            if (drawProperties.ContainsKey("m_vTintColor"))
            {
                var tint = (KVObject)drawProperties["m_vTintColor"].Value;
                drawCall.TintColor = new Vector3(
                    Convert.ToSingle(tint.Properties["0"].Value),
                    Convert.ToSingle(tint.Properties["1"].Value),
                    Convert.ToSingle(tint.Properties["2"].Value));

                if (!drawCall.Material.Textures.ContainsKey("g_tTintMask"))
                {
                    drawCall.Material.Textures.Add("g_tTintMask", MaterialLoader.CreateSolidTexture(1f, 1f, 1f));
                }
            }

            if (bufferSize == 2)
            {
                //shopkeeper_vr
                drawCall.IndiceType = DrawElementsType.UnsignedShort;
            }
            else if (bufferSize == 4)
            {
                //glados
                drawCall.IndiceType = DrawElementsType.UnsignedInt;
            }
            else
            {
                throw new Exception("Unsupported indice type");
            }

            var g = (KVObject)drawProperties["m_vertexBuffers"].Value;
            var h = (KVObject)g.Properties["0"].Value; // TODO: Not just 0

            var vertexBuffer = default(DrawBuffer);

            vertexBuffer.Id       = Convert.ToUInt32(h.Properties["m_hBuffer"].Value);
            vertexBuffer.Offset   = Convert.ToUInt32(h.Properties["m_nBindOffsetBytes"].Value);
            drawCall.VertexBuffer = vertexBuffer;

            GL.GenVertexArrays(1, out uint vertexArrayObject);
            drawCall.VertexArrayObject = vertexArrayObject;

            GL.BindVertexArray(drawCall.VertexArrayObject);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffers[drawCall.VertexBuffer.Id]);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffers[drawCall.IndexBuffer.Id]);

            var curVertexBuffer = block.VertexBuffers[(int)drawCall.VertexBuffer.Id];
            var texCoordNum     = 0;

            foreach (var attribute in curVertexBuffer.Attributes)
            {
                var attributeName = "v" + attribute.Name;

                // TODO: other params too?
                if (attribute.Name == "TEXCOORD" && texCoordNum++ > 0)
                {
                    attributeName += texCoordNum;
                }

                BindVertexAttrib(attribute, attributeName, drawCall.Shader.Program, (int)curVertexBuffer.Size);
            }

            GL.BindVertexArray(0);

            return(drawCall);
        }
Exemplo n.º 3
0
        private void MeshControl_Load(object sender, EventArgs e)
        {
            meshControl.MakeCurrent();

            Console.WriteLine("OpenGL version: " + GL.GetString(StringName.Version));
            Console.WriteLine("OpenGL vendor: " + GL.GetString(StringName.Vendor));
            Console.WriteLine("GLSL version: " + GL.GetString(StringName.ShadingLanguageVersion));

            CheckOpenGL();
            LoadBoundingBox();

            GL.Enable(EnableCap.DepthTest);

            GL.ClearColor(Settings.BackgroundColor);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            InitializeInputTick();

            ActiveCamera = new Camera(tabs.Width, tabs.Height, MinBounds, MaxBounds);

            Console.WriteLine("Setting up buffers..");

            var vertexBuffers = new uint[block.VertexBuffers.Count];
            var indexBuffers  = new uint[block.IndexBuffers.Count];

            GL.GenBuffers(block.VertexBuffers.Count, vertexBuffers);
            GL.GenBuffers(block.IndexBuffers.Count, indexBuffers);

            Console.WriteLine(block.VertexBuffers.Count + " vertex buffers");
            Console.WriteLine(block.IndexBuffers.Count + " index buffers");

            for (var i = 0; i < block.VertexBuffers.Count; i++)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffers[i]);
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(block.VertexBuffers[i].Count * block.VertexBuffers[i].Size), block.VertexBuffers[i].Buffer, BufferUsageHint.StaticDraw);

                var verticeBufferSize = 0;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out verticeBufferSize);
            }

            for (var i = 0; i < block.IndexBuffers.Count; i++)
            {
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffers[i]);
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(block.IndexBuffers[i].Count * block.IndexBuffers[i].Size), block.IndexBuffers[i].Buffer, BufferUsageHint.StaticDraw);

                var indiceBufferSize = 0;
                GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out indiceBufferSize);
            }

            Console.WriteLine("Pushed buffers");

            //Prepare drawcalls
            var a = (KVObject)data.Data.Properties["m_sceneObjects"].Value;
            var b = (KVObject)a.Properties["0"].Value;
            var c = (KVObject)b.Properties["m_drawCalls"].Value;

            for (var i = 0; i < c.Properties.Count; i++)
            {
                var d        = (KVObject)c.Properties[i.ToString()].Value;
                var drawCall = default(DrawCall);

                switch (d.Properties["m_nPrimitiveType"].Value.ToString())
                {
                case "RENDER_PRIM_TRIANGLES":
                    drawCall.PrimitiveType = PrimitiveType.Triangles;
                    break;

                default:
                    throw new Exception("Unknown PrimitiveType in drawCall! (" + d.Properties["m_nPrimitiveType"].Value + ")");
                }

                drawCall.BaseVertex  = Convert.ToUInt32(d.Properties["m_nBaseVertex"].Value);
                drawCall.VertexCount = Convert.ToUInt32(d.Properties["m_nVertexCount"].Value);
                drawCall.StartIndex  = Convert.ToUInt32(d.Properties["m_nStartIndex"].Value);
                drawCall.IndexCount  = Convert.ToUInt32(d.Properties["m_nIndexCount"].Value);

                drawCall.Material = MaterialLoader.GetMaterial(d.Properties["m_material"].Value.ToString(), MaxTextureMaxAnisotropy);

                drawCall.MaterialID = drawCall.Material.TextureIDs["g_tColor"];

                // Load shader
                drawCall.Shader = ShaderLoader.LoadShaders(drawCall.Material.ShaderName, modelArguments);

                //Bind and validate shader
                GL.UseProgram(drawCall.Shader);

                var f = (KVObject)d.Properties["m_indexBuffer"].Value;

                var indexBuffer = default(DrawBuffer);
                indexBuffer.Id       = Convert.ToUInt32(f.Properties["m_hBuffer"].Value);
                indexBuffer.Offset   = Convert.ToUInt32(f.Properties["m_nBindOffsetBytes"].Value);
                drawCall.IndexBuffer = indexBuffer;

                if (block.IndexBuffers[(int)drawCall.IndexBuffer.Id].Size == 2)
                {
                    //shopkeeper_vr
                    drawCall.IndiceType = DrawElementsType.UnsignedShort;
                }
                else if (block.IndexBuffers[(int)drawCall.IndexBuffer.Id].Size == 4)
                {
                    //glados
                    drawCall.IndiceType = DrawElementsType.UnsignedInt;
                }
                else
                {
                    throw new Exception("Unsupported indice type");
                }

                var g = (KVObject)d.Properties["m_vertexBuffers"].Value;
                var h = (KVObject)g.Properties["0"].Value;

                var vertexBuffer = default(DrawBuffer);
                vertexBuffer.Id       = Convert.ToUInt32(h.Properties["m_hBuffer"].Value);
                vertexBuffer.Offset   = Convert.ToUInt32(h.Properties["m_nBindOffsetBytes"].Value);
                drawCall.VertexBuffer = vertexBuffer;

                GL.GenVertexArrays(1, out drawCall.VertexArrayObject);

                GL.BindVertexArray(drawCall.VertexArrayObject);
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffers[drawCall.VertexBuffer.Id]);
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffers[drawCall.IndexBuffer.Id]);

                var curVertexBuffer = block.VertexBuffers[(int)drawCall.VertexBuffer.Id];
                var texcoordSet     = false;
                foreach (var attribute in curVertexBuffer.Attributes)
                {
                    switch (attribute.Name)
                    {
                    case "POSITION":
                        BindVertexAttrib(attribute, "vPosition", drawCall.Shader, (int)curVertexBuffer.Size);
                        break;

                    case "NORMAL":
                        BindVertexAttrib(attribute, "vNormal", drawCall.Shader, (int)curVertexBuffer.Size);
                        break;

                    case "TEXCOORD":
                        // Ignore second set of texcoords
                        if (texcoordSet)
                        {
                            break;
                        }

                        BindVertexAttrib(attribute, "vTexCoord", drawCall.Shader, (int)curVertexBuffer.Size);

                        texcoordSet = true;
                        break;

                    case "TANGENT":
                        BindVertexAttrib(attribute, "vTangent", drawCall.Shader, (int)curVertexBuffer.Size);
                        break;

                    case "BLENDINDICES":
                        BindVertexAttrib(attribute, "vBlendIndices", drawCall.Shader, (int)curVertexBuffer.Size);
                        break;

                    case "BLENDWEIGHT":
                        BindVertexAttrib(attribute, "vBlendWeight", drawCall.Shader, (int)curVertexBuffer.Size);
                        break;
                    }
                }

                if (drawCall.Material.IntParams.ContainsKey("F_ALPHA_TEST") && drawCall.Material.IntParams["F_ALPHA_TEST"] == 1)
                {
                    GL.Enable(EnableCap.AlphaTest);

                    if (drawCall.Material.FloatParams.ContainsKey("g_flAlphaTestReference"))
                    {
                        var alphaReference = GL.GetUniformLocation(drawCall.Shader, "alphaReference");
                        GL.Uniform1(alphaReference, drawCall.Material.FloatParams["g_flAlphaTestReference"]);
                    }
                }

                if (drawCall.Material.IntParams.ContainsKey("F_TRANSLUCENT") && drawCall.Material.IntParams["F_TRANSLUCENT"] == 1)
                {
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                }

                GL.BindVertexArray(0);
                GL.EnableVertexAttribArray(drawCall.VertexArrayObject);

                drawCalls.Add(drawCall);
            }

            Loaded = true;
        }