public MaterialRenderer(RenderMaterial renderMaterial) { material = renderMaterial; shader = ShaderLoader.LoadPlaneShader(material.Material.ShaderName, material.Material.GetShaderArguments()); quadVao = SetupQuadBuffer(); }
//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); }
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; }