public Renderer(Resource resource, TabControl mainTabs, string fileName, Package currentPackage) { CurrentPackage = currentPackage; CurrentFileName = fileName; block = resource.VBIB; data = (BinaryKV3)resource.Blocks[BlockType.DATA]; modelArguments = (ArgumentDependencies)((ResourceEditInfo)resource.Blocks[BlockType.REDI]).Structs[ResourceEditInfo.REDIStruct.ArgumentDependencies]; tabs = mainTabs; MaterialLoader = new MaterialLoader(CurrentFileName, CurrentPackage); }
public GPUMeshBuffers GetVertexIndexBuffers(VBIB vbib) { if (gpuBuffers.TryGetValue(vbib, out var gpuVbib)) { return(gpuVbib); } else { var newGpuVbib = new GPUMeshBuffers(vbib); gpuBuffers.Add(vbib, newGpuVbib); return(newGpuVbib); } }
public uint GetVertexArrayObject(VBIB vbib, Shader shader, uint vtxIndex, uint idxIndex) { var gpuVbib = GetVertexIndexBuffers(vbib); var vaoKey = new VAOKey { VBIB = gpuVbib, Shader = shader, VertexIndex = vtxIndex, IndexIndex = idxIndex }; if (vertexArrayObjects.TryGetValue(vaoKey, out uint vaoHandle)) { return(vaoHandle); } else { GL.GenVertexArrays(1, out uint newVaoHandle); GL.BindVertexArray(newVaoHandle); GL.BindBuffer(BufferTarget.ArrayBuffer, gpuVbib.VertexBuffers[vtxIndex].Handle); GL.BindBuffer(BufferTarget.ElementArrayBuffer, gpuVbib.IndexBuffers[idxIndex].Handle); var curVertexBuffer = vbib.VertexBuffers[(int)vtxIndex]; 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, shader.Program, (int)curVertexBuffer.Size); } GL.BindVertexArray(0); vertexArrayObjects.Add(vaoKey, newVaoHandle); return(newVaoHandle); } }
public GPUMeshBuffers(VBIB vbib) { VertexBuffers = new Buffer[vbib.VertexBuffers.Count]; IndexBuffers = new Buffer[vbib.IndexBuffers.Count]; for (var i = 0; i < vbib.VertexBuffers.Count; i++) { VertexBuffers[i].Handle = (uint)GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBuffers[i].Handle); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vbib.VertexBuffers[i].Count * vbib.VertexBuffers[i].Size), vbib.VertexBuffers[i].Buffer, BufferUsageHint.StaticDraw); GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out VertexBuffers[i].Size); } for (var i = 0; i < vbib.IndexBuffers.Count; i++) { IndexBuffers[i].Handle = (uint)GL.GenBuffer(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndexBuffers[i].Handle); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(vbib.IndexBuffers[i].Count * vbib.IndexBuffers[i].Size), vbib.IndexBuffers[i].Buffer, BufferUsageHint.StaticDraw); GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out IndexBuffers[i].Size); } }
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); }
public Mesh(ResourceData data, VBIB vbib) { Data = data; VBIB = vbib; GetBounds(); }
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); }
private static float[] ReadAttributeBuffer(VertexBuffer buffer, VertexAttribute attribute) => Enumerable.Range(0, (int)buffer.Count) .SelectMany(i => VBIB.ReadVertexAttribute(i, buffer, attribute)) .ToArray();