private void SetupDrawCalls(Mesh mesh, Dictionary <string, string> skinMaterials) { var vbib = mesh.VBIB; var data = mesh.GetData(); var gpuMeshBuffers = guiContext.MeshBufferCache.GetVertexIndexBuffers(vbib); //Prepare drawcalls var sceneObjects = data.GetArray("m_sceneObjects"); foreach (var sceneObject in sceneObjects) { var objectDrawCalls = sceneObject.GetArray("m_drawCalls"); foreach (var objectDrawCall in objectDrawCalls) { var materialName = objectDrawCall.GetProperty <string>("m_material"); if (skinMaterials != null && skinMaterials.ContainsKey(materialName)) { materialName = skinMaterials[materialName]; } var material = guiContext.MaterialLoader.GetMaterial(materialName); var isOverlay = material.Material.IntParams.ContainsKey("F_OVERLAY"); // Ignore overlays for now if (isOverlay) { continue; } var shaderArguments = new Dictionary <string, bool>(); if (DrawCall.IsCompressedNormalTangent(objectDrawCall)) { shaderArguments.Add("fulltangent", false); } // TODO: Don't pass around so much shit var drawCall = CreateDrawCall(objectDrawCall, vbib, shaderArguments, material); if (drawCall.Material.IsBlended) { DrawCallsBlended.Add(drawCall); } else { DrawCallsOpaque.Add(drawCall); } } } //drawCalls = drawCalls.OrderBy(x => x.Material.Parameters.Name).ToList(); }
private void SetupDrawCallMaterial(DrawCall drawCall, IDictionary <string, bool> shaderArguments, RenderMaterial material) { drawCall.Material = material; // Add shader parameters from material to the shader parameters from the draw call var combinedShaderParameters = shaderArguments .Concat(material.Material.GetShaderArguments()) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Load shader drawCall.Shader = guiContext.ShaderLoader.LoadShader(drawCall.Material.Material.ShaderName, combinedShaderParameters); //Bind and validate shader GL.UseProgram(drawCall.Shader.Program); if (!drawCall.Material.Textures.ContainsKey("g_tTintMask")) { drawCall.Material.Textures.Add("g_tTintMask", MaterialLoader.CreateSolidTexture(1f, 1f, 1f)); } if (!drawCall.Material.Textures.ContainsKey("g_tNormal")) { drawCall.Material.Textures.Add("g_tNormal", MaterialLoader.CreateSolidTexture(0.5f, 1f, 0.5f)); } }
private DrawCall CreateDrawCall(IKeyValueCollection objectDrawCall, VBIB vbib, GPUMeshBuffers gpuMeshBuffers, IDictionary <string, bool> shaderArguments, RenderMaterial material) { var drawCall = new DrawCall(); switch (objectDrawCall.GetProperty <string>("m_nPrimitiveType")) { case "RENDER_PRIM_TRIANGLES": drawCall.PrimitiveType = PrimitiveType.Triangles; break; default: throw new Exception("Unknown PrimitiveType in drawCall! (" + objectDrawCall.GetProperty <string>("m_nPrimitiveType") + ")"); } drawCall.Material = material; // Add shader parameters from material to the shader parameters from the draw call var combinedShaderParameters = shaderArguments .Concat(material.Material.GetShaderArguments()) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Load shader drawCall.Shader = guiContext.ShaderLoader.LoadShader(drawCall.Material.Material.ShaderName, combinedShaderParameters); //Bind and validate shader GL.UseProgram(drawCall.Shader.Program); var indexBufferObject = objectDrawCall.GetSubCollection("m_indexBuffer"); var indexBuffer = default(DrawBuffer); indexBuffer.Id = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_hBuffer")); indexBuffer.Offset = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_nBindOffsetBytes")); drawCall.IndexBuffer = indexBuffer; var indexElementSize = vbib.IndexBuffers[(int)drawCall.IndexBuffer.Id].Size; //drawCall.BaseVertex = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nBaseVertex")); //drawCall.VertexCount = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nVertexCount")); drawCall.StartIndex = Convert.ToUInt32(objectDrawCall.GetProperty <object>("m_nStartIndex")) * indexElementSize; drawCall.IndexCount = Convert.ToInt32(objectDrawCall.GetProperty <object>("m_nIndexCount")); if (objectDrawCall.ContainsKey("m_vTintColor")) { var tintColor = objectDrawCall.GetSubCollection("m_vTintColor").ToVector3(); drawCall.TintColor = new OpenTK.Vector3(tintColor.X, tintColor.Y, tintColor.Z); } if (!drawCall.Material.Textures.ContainsKey("g_tTintMask")) { drawCall.Material.Textures.Add("g_tTintMask", MaterialLoader.CreateSolidTexture(1f, 1f, 1f)); } if (!drawCall.Material.Textures.ContainsKey("g_tNormal")) { drawCall.Material.Textures.Add("g_tNormal", MaterialLoader.CreateSolidTexture(0.5f, 1f, 0.5f)); } if (indexElementSize == 2) { //shopkeeper_vr drawCall.IndexType = DrawElementsType.UnsignedShort; } else if (indexElementSize == 4) { //glados drawCall.IndexType = DrawElementsType.UnsignedInt; } else { throw new Exception("Unsupported index type"); } var m_vertexBuffers = objectDrawCall.GetSubCollection("m_vertexBuffers"); var m_vertexBuffer = m_vertexBuffers.GetSubCollection("0"); // TODO: Not just 0 var vertexBuffer = default(DrawBuffer); vertexBuffer.Id = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_hBuffer")); vertexBuffer.Offset = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_nBindOffsetBytes")); drawCall.VertexBuffer = vertexBuffer; drawCall.VertexArrayObject = guiContext.MeshBufferCache.GetVertexArrayObject( vbib, drawCall.Shader, drawCall.VertexBuffer.Id, drawCall.IndexBuffer.Id); return(drawCall); }
//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.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 (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 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 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 DrawCall CreateDrawCall(IKeyValueCollection objectDrawCall, VBIB vbib, IDictionary <string, bool> shaderArguments, RenderMaterial material) { var drawCall = new DrawCall(); string primitiveType = objectDrawCall.GetProperty <object>("m_nPrimitiveType") switch { string primitiveTypeString => primitiveTypeString, byte primitiveTypeByte => (primitiveTypeByte == 5) ? "RENDER_PRIM_TRIANGLES" : ("UNKNOWN_" + primitiveTypeByte), _ => throw new NotImplementedException("Unknown PrimitiveType in drawCall!") }; switch (primitiveType) { case "RENDER_PRIM_TRIANGLES": drawCall.PrimitiveType = PrimitiveType.Triangles; break; default: throw new NotImplementedException("Unknown PrimitiveType in drawCall! (" + primitiveType + ")"); } SetupDrawCallMaterial(drawCall, shaderArguments, material); var indexBufferObject = objectDrawCall.GetSubCollection("m_indexBuffer"); var indexBuffer = default(DrawBuffer); indexBuffer.Id = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_hBuffer")); indexBuffer.Offset = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_nBindOffsetBytes")); drawCall.IndexBuffer = indexBuffer; var indexElementSize = vbib.IndexBuffers[(int)drawCall.IndexBuffer.Id].ElementSizeInBytes; //drawCall.BaseVertex = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nBaseVertex")); //drawCall.VertexCount = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nVertexCount")); drawCall.StartIndex = Convert.ToUInt32(objectDrawCall.GetProperty <object>("m_nStartIndex")) * indexElementSize; drawCall.IndexCount = Convert.ToInt32(objectDrawCall.GetProperty <object>("m_nIndexCount")); if (objectDrawCall.ContainsKey("m_vTintColor")) { var tintColor = objectDrawCall.GetSubCollection("m_vTintColor").ToVector3(); drawCall.TintColor = new OpenTK.Vector3(tintColor.X, tintColor.Y, tintColor.Z); } if (indexElementSize == 2) { //shopkeeper_vr drawCall.IndexType = DrawElementsType.UnsignedShort; } else if (indexElementSize == 4) { //glados drawCall.IndexType = DrawElementsType.UnsignedInt; } else { throw new Exception("Unsupported index type"); } var m_vertexBuffer = objectDrawCall.GetArray("m_vertexBuffers")[0]; // TODO: Not just 0 var vertexBuffer = default(DrawBuffer); vertexBuffer.Id = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_hBuffer")); vertexBuffer.Offset = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_nBindOffsetBytes")); drawCall.VertexBuffer = vertexBuffer; drawCall.VertexArrayObject = guiContext.MeshBufferCache.GetVertexArrayObject( vbib, drawCall.Shader, drawCall.VertexBuffer.Id, drawCall.IndexBuffer.Id); return(drawCall); }