private void RenderDrawData(ImDrawDataPtr drawData) { var lastViewport = GraphicsDevice.Viewport; var lastScissorRect = GraphicsDevice.ScissorRectangle; GraphicsDevice.BlendFactor = Color.White; GraphicsDevice.BlendState = BlendState.NonPremultiplied; GraphicsDevice.RasterizerState = _rasterizerState; GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; //ADD THIS LINE drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); GraphicsDevice.Viewport = new Viewport( 0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight); UpdateBuffers(drawData); RenderCommandLists(drawData); GraphicsDevice.Viewport = lastViewport; GraphicsDevice.ScissorRectangle = lastScissorRect; }
protected override void RenderImGui(ImDrawDataPtr drawData) { // Some games have changed the sampler state, and this can make fonts blurry. So we want to make sure // to reset it while rendering var oldSamplerState = _game.GraphicsDevice.SamplerStates[0]; _game.GraphicsDevice.SamplerStates[0] = _defaultSampleState; // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers var lastViewport = _graphicsDevice.Viewport; var lastScissorBox = _graphicsDevice.ScissorRectangle; _graphicsDevice.BlendFactor = Color.White; _graphicsDevice.BlendState = BlendState.NonPremultiplied; _graphicsDevice.RasterizerState = _rasterizerState; _graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); // Setup projection _graphicsDevice.Viewport = new Viewport(0, 0, _graphicsDevice.PresentationParameters.BackBufferWidth, _graphicsDevice.PresentationParameters.BackBufferHeight); UpdateBuffers(drawData); RenderCommandLists(drawData); // Restore modified state _graphicsDevice.Viewport = lastViewport; _graphicsDevice.ScissorRectangle = lastScissorBox; // Reset sampler state back to what the game had previously set up _game.GraphicsDevice.SamplerStates[0] = oldSamplerState; }
/// <summary> /// Gets the geometry as set up by ImGui and sends it to the graphics device /// </summary> private void RenderDrawData(ImDrawDataPtr drawData) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, // scissor enabled, vertex/texcoord/color pointers var lastViewport = this.GraphicsDevice.Viewport; var lastScissorBox = this.GraphicsDevice.ScissorRectangle; this.GraphicsDevice.BlendFactor = Color.White; this.GraphicsDevice.BlendState = BlendState.NonPremultiplied; this.GraphicsDevice.RasterizerState = this.RasterizerState; this.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); // Setup projection this.GraphicsDevice.Viewport = new Viewport(0, 0, this.GraphicsDevice.PresentationParameters.BackBufferWidth, this.GraphicsDevice.PresentationParameters.BackBufferHeight); this.UpdateBuffers(drawData); this.RenderCommandLists(drawData); // Restore modified state this.GraphicsDevice.Viewport = lastViewport; this.GraphicsDevice.ScissorRectangle = lastScissorBox; }
private void RenderDrawData(ImDrawDataPtr drawData) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers var last_viewport = GraphicsDevice.Viewport; var last_scissor_rect = GraphicsDevice.ScissorRectangle; GraphicsDevice.BlendFactor = Color.White; GraphicsDevice.BlendState = BlendState.NonPremultiplied; GraphicsDevice.RasterizerState = _rasterizer_state; GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; //ADD THIS LINE // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) drawData.ScaleClipRects(ImGuiNET.ImGui.GetIO().DisplayFramebufferScale); // Setup projection GraphicsDevice.Viewport = new Viewport(0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight); UpdateBuffers(drawData); RenderCommandLists(drawData); // Restore modified state GraphicsDevice.Viewport = last_viewport; GraphicsDevice.ScissorRectangle = last_scissor_rect; }
/// <summary> /// Gets the geometry as set up by ImGui and sends it to the graphics device /// </summary> private void RenderDrawData(ImDrawDataPtr drawData, int x, int y, int w, int h) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers var lastViewport = _graphicsDevice.Viewport; var lastScissorBox = _graphicsDevice.ScissorRectangle; _graphicsDevice.BlendFactor = Color.White; _graphicsDevice.BlendState = BlendState.NonPremultiplied; _graphicsDevice.RasterizerState = _rasterizerState; _graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); drawData.DisplayPos = new System.Numerics.Vector2(x, y); // Setup projection _graphicsDevice.Viewport = new Viewport(x, y, w, h); UpdateBuffers(drawData); RenderCommandLists(drawData, x, y, w, h); // Restore modified state _graphicsDevice.Viewport = lastViewport; _graphicsDevice.ScissorRectangle = lastScissorBox; }
void RenderDrawData(ImDrawDataPtr drawData) { // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); UpdateBuffers(drawData); RenderCommandLists(drawData); }
unsafe void RenderCommandLists(ImDrawDataPtr drawData) { // Scale coordinates for retina displays (screen coordinates != framebuffer coordinates) int fbWidth = (int)(drawData.DisplaySize.X * drawData.FramebufferScale.X); int fbHeight = (int)(drawData.DisplaySize.Y * drawData.FramebufferScale.Y); // Avoid rendering if display is minimized or if the command list is empty if (fbWidth <= 0 || fbHeight <= 0 || drawData.CmdListsCount == 0) { return; } drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); Rlgl.rlDisableBackfaceCulling(); for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; // Vertex buffer and index buffer generated by Dear ImGui ImPtrVector <ImDrawVertPtr> vtxBuffer = cmdList.VtxBuffer; ImVector <ushort> idxBuffer = cmdList.IdxBuffer; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdi]; if (pcmd.UserCallback != IntPtr.Zero) { // pcmd.UserCallback(cmdList, pcmd); } else { Vector2 pos = drawData.DisplayPos; int rectX = (int)((pcmd.ClipRect.X - pos.X) * drawData.FramebufferScale.X); int rectY = (int)((pcmd.ClipRect.Y - pos.Y) * drawData.FramebufferScale.Y); int rectW = (int)((pcmd.ClipRect.Z - rectX) * drawData.FramebufferScale.X); int rectH = (int)((pcmd.ClipRect.W - rectY) * drawData.FramebufferScale.Y); if (rectX < fbWidth && rectY < fbHeight && rectW >= 0.0f && rectH >= 0.0f) { Raylib.BeginScissorMode(rectX, rectY, rectW, rectH); DrawTriangles(pcmd.ElemCount, idxBuffer, vtxBuffer, (int)pcmd.IdxOffset, (int)pcmd.VtxOffset, pcmd.TextureId); } } } } Raylib.EndScissorMode(); Rlgl.rlEnableBackfaceCulling(); }
private void RenderDrawData(ImDrawDataPtr ptr) { Viewport lastViewport = GraphicsDevice.Viewport; Rectangle lastScissor = GraphicsDevice.ScissorRectangle; GraphicsDevice.BlendFactor = Color.White; GraphicsDevice.BlendState = BlendState.NonPremultiplied; GraphicsDevice.RasterizerState = RasterizerState; GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; ptr.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); GraphicsDevice.Viewport = new Viewport(0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight); UpdateBuffers(ptr); RenderCommandLists(ptr); // Restore graphics state GraphicsDevice.Viewport = lastViewport; GraphicsDevice.ScissorRectangle = lastScissor; }
private unsafe static void RenderDrawLists(ImDrawDataPtr drawData, ImGuiIOPtr io) { if (drawData.CmdListsCount == 0) { return; } int fb_width = (int)(io.DisplaySize.X * io.DisplayFramebufferScale.X); int fb_height = (int)(io.DisplaySize.Y * io.DisplayFramebufferScale.Y); if (fb_width == 0 || fb_height == 0) { return; } drawData.ScaleClipRects(io.DisplayFramebufferScale); //int lastTexutre = GL.GetInteger(GetPName.TextureBinding2D); //int lastArrayBuffer = GL.GetInteger(GetPName.ArrayBufferBinding); //int lastElementArrayBuffer = GL.GetInteger(GetPName.ElementArrayBufferBinding); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); GL.Enable(EnableCap.Texture2D); GL.Disable(EnableCap.Lighting); OpenTK.Graphics.ES11.GL.EnableClientState(OpenTK.Graphics.ES11.EnableCap.VertexArray); OpenTK.Graphics.ES11.GL.EnableClientState(OpenTK.Graphics.ES11.EnableCap.ColorArray); OpenTK.Graphics.ES11.GL.EnableClientState(OpenTK.Graphics.ES11.EnableCap.TextureCoordArray); GL.Viewport(0, 0, fb_width, fb_height); OpenTK.Graphics.ES11.GL.MatrixMode(OpenTK.Graphics.ES11.MatrixMode.Texture); OpenTK.Graphics.ES11.GL.LoadIdentity(); OpenTK.Graphics.ES11.GL.MatrixMode(OpenTK.Graphics.ES11.MatrixMode.Projection); OpenTK.Graphics.ES11.GL.LoadIdentity(); OpenTK.Graphics.ES11.GL.Ortho(0f, io.DisplaySize.X, io.DisplaySize.Y, 0f, -1f, 1f); OpenTK.Graphics.ES11.GL.MatrixMode(OpenTK.Graphics.ES11.MatrixMode.Modelview); OpenTK.Graphics.ES11.GL.LoadIdentity(); //System.Console.WriteLine("-----------------------------------"); //System.Console.WriteLine(drawData.CmdListsCount); for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; OpenTK.Graphics.ES11.GL.VertexPointer(2, OpenTK.Graphics.ES11.VertexPointerType.Float, Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data + 0); OpenTK.Graphics.ES11.GL.TexCoordPointer(2, OpenTK.Graphics.ES11.TexCoordPointerType.Float, Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data + 8); OpenTK.Graphics.ES11.GL.ColorPointer(4, OpenTK.Graphics.ES11.ColorPointerType.UnsignedByte, Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data + 16); var idx_buffer = cmdList.IdxBuffer.Data; for (int cmdIndex = 0; cmdIndex < cmdList.CmdBuffer.Size; cmdIndex++) { ImDrawCmdPtr drawCommand = cmdList.CmdBuffer[cmdIndex]; //System.Console.WriteLine(cmdList.CmdBuffer.Size); if (drawCommand.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { var textureHandle = drawCommand.TextureId; GL.BindTexture(TextureTarget.Texture2D, (int)textureHandle); GL.Scissor((int)drawCommand.ClipRect.X, (int)(fb_height - drawCommand.ClipRect.W), (int)(drawCommand.ClipRect.Z - drawCommand.ClipRect.X), (int)(drawCommand.ClipRect.W - drawCommand.ClipRect.Y)); GL.DrawElements(OpenTK.Graphics.ES20.PrimitiveType.Triangles, (int)drawCommand.ElemCount, DrawElementsType.UnsignedShort, idx_buffer + (int)drawCommand.IdxOffset); } idx_buffer += (Int32)drawCommand.ElemCount; } } //GL.BindTexture(TextureTarget.Texture2D,lastTexutre); //GL.BindBuffer(BufferTarget.ArrayBuffer,lastArrayBuffer); //GL.BindBuffer(BufferTarget.ElementArrayBuffer,lastElementArrayBuffer); GL.Disable(EnableCap.ScissorTest); }
/// <summary> /// Render the imgui calls. /// </summary> /// <param name="r">The Engine.Renderer module.</param> public static void RenderGui(this Renderer r) { // Submit the renderer up to here so there's no interference with its buffer. r.Submit(); // Get render data from imgui. ImGui.Render(); ImDrawDataPtr drawPointer = ImGui.GetDrawData(); ImGuiIOPtr io = ImGui.GetIO(); // Copy vertices and indices. uint vtxOffset = 0; uint idxOffset = 0; Engine.GraphicsManager.BindDataBuffer(GuiBuffer.Vbo); Engine.GraphicsManager.BindIndexBuffer(GuiBuffer.Ibo); for (int i = 0; i < drawPointer.CmdListsCount; i++) { ImDrawListPtr drawList = drawPointer.CmdListsRange[i]; // Check if any command lists. if (drawList.CmdBuffer.Size == 0) { continue; } // Copy vertex and index buffers to the stream buffer. uint vtxSize = (uint)(drawList.VtxBuffer.Size * sizeof(ImDrawVert)); uint idxSize = (uint)drawList.IdxBuffer.Size * sizeof(ushort); // Upload. Engine.GraphicsManager.MapDataBuffer(drawList.VtxBuffer.Data, vtxSize, vtxOffset); Engine.GraphicsManager.MapIndexBuffer(drawList.IdxBuffer.Data, idxSize, idxOffset); // Increment the offset trackers. vtxOffset += vtxSize; idxOffset += idxSize; } // Prepare for drawing. Set the needed state, bind the imgui texture. Engine.GraphicsManager.StateDepthTest(false); // Check if the view matrix is enabled. bool viewMatrixEnabled = Engine.Renderer.ViewMatrixEnabled; if (viewMatrixEnabled) { Engine.Renderer.ViewMatrixEnabled = false; } GuiBuffer.Reset(); GuiBuffer.UnsafeSetMappedVertices(idxOffset / sizeof(ushort)); // The only reason for this is so the MappedVertices doesn't error. drawPointer.ScaleClipRects(io.DisplayFramebufferScale); // Go through command lists and render. uint offset = 0; uint indicesOffset = 0; for (int i = 0; i < drawPointer.CmdListsCount; i++) { // Get the current draw list. ImDrawListPtr drawList = drawPointer.CmdListsRange[i]; for (int cmdList = 0; cmdList < drawList.CmdBuffer.Size; cmdList++) { ImDrawCmdPtr currentCommandList = drawList.CmdBuffer[cmdList]; Engine.GraphicsManager.BindTexture((uint)currentCommandList.TextureId); // Set the clip rect. Engine.GraphicsManager.SetClipRect( (int)currentCommandList.ClipRect.X, (int)currentCommandList.ClipRect.Y, (int)(currentCommandList.ClipRect.Z - currentCommandList.ClipRect.X), (int)(currentCommandList.ClipRect.W - currentCommandList.ClipRect.Y)); // Set the draw range of this specific command, and draw it. GuiBuffer.SetRenderRangeIndices(offset, offset + currentCommandList.ElemCount); GuiBuffer.SetBaseVertex(indicesOffset); r.Render(GuiBuffer); // Set drawing offset. offset += currentCommandList.ElemCount; } indicesOffset += (uint)drawList.VtxBuffer.Size; } // Reset state to default. Engine.GraphicsManager.DefaultGLState(); Engine.Renderer.ViewMatrixEnabled = viewMatrixEnabled; }
unsafe private static void RenderDrawLists(RenderTarget target, ImDrawDataPtr draw_data) { ImGui.GetDrawData(); if (draw_data.CmdListsCount == 0) { return; } var oldView = target.GetView(); //target.SetView(new View(new FloatRect(0, 0, target.Size.X, target.Size.Y))); var io = ImGui.GetIO(); int fb_width = (int)(io.DisplaySize.X * io.DisplayFramebufferScale.X); int fb_height = (int)(io.DisplaySize.Y * io.DisplayFramebufferScale.Y); draw_data.ScaleClipRects(io.DisplayFramebufferScale); /* * for (int n = 0; n < draw_data.CmdListsCount; ++n) * { * var cmd_list = draw_data.CmdListsRange[n]; * var vtx_buffer = cmd_list.VtxBuffer; * var idx_buffer = cmd_list.IdxBuffer; * * for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; ++cmd_i) * { * var pcmd = cmd_list.CmdBuffer[cmd_i]; * if (pcmd.UserCallback != IntPtr.Zero) * Marshal.GetDelegateForFunctionPointer<DrawCmdUserCallback>(pcmd.UserCallback)(cmd_list, pcmd); * else * { * var vertices = new Vertex[pcmd.ElemCount]; * for ( int i = 0; i < pcmd.ElemCount; ++i ) * { * var vert = vtx_buffer[idx_buffer[i]]; * Vertex v; * v.Position = new Vector2f(vert.pos.X, vert.pos.Y); * v.TexCoords = new Vector2f(vert.uv.X, vert.uv.Y); * v.Color = new Color((byte)((vert.col >> 0) & 0xFF), (byte)((vert.col >> 8) & 0xFF), (byte)((vert.col >> 16) & 0xFF), (byte)((vert.col >> 24) & 0xFF)); * vertices[i] = v; * } * * //View view = new View(new FloatRect((int)(pcmd.ClipRect.X), (int)(fb_height - pcmd.ClipRect.W), (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y))); * //target.SetView(view); * // todo: texturing * target.Draw(vertices, SFML.Graphics.PrimitiveType.Triangles); * } * } * } * * target.SetView(oldView); * //*/ //* GL.PushAttrib(AttribMask.EnableBit | AttribMask.ColorBufferBit | AttribMask.TransformBit); GL.Enable(EnableCap.Blend); //honestly don't know what this did but removing it doesn't change anything ¯\_(ツ)_/¯ //GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); GL.Enable(EnableCap.Texture2D); GL.Disable(EnableCap.Lighting); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.ColorArray); GL.EnableClientState(ArrayCap.TextureCoordArray); GL.Viewport(0, 0, fb_width, fb_height); GL.MatrixMode(MatrixMode.Texture); GL.LoadIdentity(); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Ortho(0, io.DisplaySize.X, io.DisplaySize.Y, 0, -1, 1); for (int n = 0; n < draw_data.CmdListsCount; ++n) { var cmd_list = draw_data.CmdListsRange[n]; var vtx_buffer = cmd_list.VtxBuffer.Data; var idx_buffer = cmd_list.IdxBuffer.Data; GL.VertexPointer(2, VertexPointerType.Float, sizeof(ImDrawVert), vtx_buffer + Marshal.OffsetOf <ImDrawVert>(nameof(ImDrawVert.pos)).ToInt32()); GL.TexCoordPointer(2, TexCoordPointerType.Float, sizeof(ImDrawVert), vtx_buffer + Marshal.OffsetOf <ImDrawVert>(nameof(ImDrawVert.uv)).ToInt32()); GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(ImDrawVert), vtx_buffer + Marshal.OffsetOf <ImDrawVert>(nameof(ImDrawVert.col)).ToInt32()); for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; ++cmd_i) { var pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { Marshal.GetDelegateForFunctionPointer <DrawCmdUserCallback>(pcmd.UserCallback)(cmd_list, pcmd); } else { uint textureHandle = ConvertImTextureIDToGLTextureHandle(pcmd.TextureId); GL.BindTexture(TextureTarget.Texture2D, textureHandle); GL.Scissor((int)(pcmd.ClipRect.X), (int)(fb_height - pcmd.ClipRect.W), (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y)); GL.DrawElements(OpenTK.Graphics.OpenGL.PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, idx_buffer); } } } GL.PopAttrib(); //*/ }
void renderInternal(ImDrawDataPtr draw_data) { BufferChanged = false; if (draw_data.CmdListsCount == 0) { return; } var vertexSize = draw_data.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > vertexBufferSize) { BufferChanged = true; var newSize = (int)(vertexSize * 1.5f); GL.DeleteBuffer(vertexBuffer); GL.CreateBuffers(1, out vertexBuffer); GL.NamedBufferData(vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.VertexArrayVertexBuffer(vertexArray, 0, vertexBuffer, IntPtr.Zero, Unsafe.SizeOf <ImDrawVert>()); vertexBufferSize = newSize; } var indexSize = draw_data.TotalIdxCount * sizeof(ushort); if (indexSize > indexBufferSize) { BufferChanged = true; var newSize = (int)(indexSize * 1.5f); GL.DeleteBuffer(indexBuffer); GL.CreateBuffers(1, out indexBuffer); GL.NamedBufferData(indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.VertexArrayElementBuffer(vertexArray, indexBuffer); indexBufferSize = newSize; } // Setup orthographic projection matrix into our constant buffer var io = ImGui.GetIO(); var mvp = Matrix4.CreateOrthographicOffCenter( 0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); GL.UseProgram(shader.Program); GL.UniformMatrix4(shader.GetUniformLocation("projection_matrix"), false, ref mvp); GL.Uniform1(shader.GetUniformLocation("in_fontTexture"), 0); Utils.CheckError("Projection"); GL.BindVertexArray(vertexArray); Utils.CheckError("VAO"); draw_data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); Utils.CheckError($"Render state"); // Render command lists for (int n = 0; n < draw_data.CmdListsCount; n++) { var cmd_list = draw_data.CmdListsRange[n]; GL.NamedBufferSubData(vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); Utils.CheckError($"Data Vert {n}"); GL.NamedBufferSubData(indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); Utils.CheckError($"Data Idx {n}"); int idx_offset = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); Utils.CheckError("Texture"); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); Utils.CheckError("Scissor"); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), 0); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } Utils.CheckError("Draw"); idx_offset += (int)pcmd.ElemCount; } } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); GL.Disable(EnableCap.ScissorTest); GL.BindVertexArray(0); }
private void RenderImDrawData(ImDrawDataPtr drawData, GraphicsDevice gd, CommandList cl) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (drawData.CmdListsCount == 0) { return; } uint totalVbSize = (uint)(drawData.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>()); if (totalVbSize > _vertexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_vertexBuffer); _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVbSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); } uint totalIbSize = (uint)(drawData.TotalIdxCount * sizeof(ushort)); if (totalIbSize > _indexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_indexBuffer); _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIbSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); } for (int i = 0; i < drawData.CmdListsCount; i++) { ImDrawListPtr cmdList = drawData.CmdListsRange[i]; cl.UpdateBuffer( _vertexBuffer, vertexOffsetInVertices * (uint)Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data, (uint)(cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>())); cl.UpdateBuffer( _indexBuffer, indexOffsetInElements * sizeof(ushort), cmdList.IdxBuffer.Data, (uint)(cmdList.IdxBuffer.Size * sizeof(ushort))); vertexOffsetInVertices += (uint)cmdList.VtxBuffer.Size; indexOffsetInElements += (uint)cmdList.IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp); cl.SetVertexBuffer(0, _vertexBuffer); cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16); cl.SetPipeline(_pipeline); cl.SetGraphicsResourceSet(0, _mainResourceSet); drawData.ScaleClipRects(io.DisplayFramebufferScale); // Render command lists int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int cmdI = 0; cmdI < cmdList.CmdBuffer.Size; cmdI++) { ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdI]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { if (pcmd.TextureId != IntPtr.Zero) { if (pcmd.TextureId == _fontAtlasID) { cl.SetGraphicsResourceSet(1, _fontTextureResourceSet); } else { cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId)); } } cl.SetScissorRect( 0, (uint)pcmd.ClipRect.X, (uint)pcmd.ClipRect.Y, (uint)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (uint)(pcmd.ClipRect.W - pcmd.ClipRect.Y)); cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idxOffset, vtxOffset, 0); } idxOffset += (int)pcmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } }
private void RenderImDrawData(ImDrawDataPtr drawDataPtr) { if (drawDataPtr.CmdListsCount == 0) { return; } for (var i = 0; i < drawDataPtr.CmdListsCount; i++) { var commandList = drawDataPtr.CmdListsRange[i]; var vertexSize = commandList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > _vertexBufferSize) { var newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize); GL.NamedBufferData(_vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _vertexBufferSize = newSize; } var indexSize = commandList.IdxBuffer.Size * sizeof(ushort); if (indexSize > _indexBufferSize) { var newSize = (int)Math.Max(_indexBufferSize * 1.5f, indexSize); GL.NamedBufferData(_indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _indexBufferSize = newSize; } } // Setup orthographic projection matrix into our constant buffer var io = ImGui.GetIO(); var mvp = Matrix4.CreateOrthographicOffCenter( 0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _shader.Use(); _shader.SetUniform("projection_matrix", Matrix4.Transpose(mvp)); _shader.SetSampler("in_fontTexture", 0); Debug.CheckGLError("ImGui-Projection"); GL.BindVertexArray(_vertexArray); Debug.CheckGLError("ImGui-VAO"); drawDataPtr.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); // Render command lists for (var n = 0; n < drawDataPtr.CmdListsCount; n++) { var commandList = drawDataPtr.CmdListsRange[n]; GL.NamedBufferSubData(_vertexBuffer, IntPtr.Zero, commandList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), commandList.VtxBuffer.Data); Debug.CheckGLError($"ImGui-Data Vertices {n}"); GL.NamedBufferSubData(_indexBuffer, IntPtr.Zero, commandList.IdxBuffer.Size * sizeof(ushort), commandList.IdxBuffer.Data); Debug.CheckGLError($"ImGui-Data Indices {n}"); var vertexOffset = 0; var indexOffset = 0; for (var commandIndex = 0; commandIndex < commandList.CmdBuffer.Size; commandIndex++) { var drawCmdPtr = commandList.CmdBuffer[commandIndex]; if (drawCmdPtr.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)drawCmdPtr.TextureId); Debug.CheckGLError("ImGui-Texture"); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = drawCmdPtr.ClipRect; GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); Debug.CheckGLError("ImGui-Scissor"); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)drawCmdPtr.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(indexOffset * sizeof(ushort)), vertexOffset); } else { GL.DrawElements(BeginMode.Triangles, (int)drawCmdPtr.ElemCount, DrawElementsType.UnsignedShort, (int)drawCmdPtr.IdxOffset * sizeof(ushort)); } Debug.CheckGLError("ImGui-Draw"); } indexOffset += (int)drawCmdPtr.ElemCount; } vertexOffset += commandList.VtxBuffer.Size; } GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); }
/* * internal void PressChar(char keyChar) * { * PressedChars.Add(keyChar); * } * * private static void SetKeyMappings() * { * ImGuiIOPtr io = ImGui.GetIO(); * io.KeyMap[(int)ImGuiKey.Tab] = (int)Key.Tab; * io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)Key.Left; * io.KeyMap[(int)ImGuiKey.RightArrow] = (int)Key.Right; * io.KeyMap[(int)ImGuiKey.UpArrow] = (int)Key.Up; * io.KeyMap[(int)ImGuiKey.DownArrow] = (int)Key.Down; * io.KeyMap[(int)ImGuiKey.PageUp] = (int)Key.PageUp; * io.KeyMap[(int)ImGuiKey.PageDown] = (int)Key.PageDown; * io.KeyMap[(int)ImGuiKey.Home] = (int)Key.Home; * io.KeyMap[(int)ImGuiKey.End] = (int)Key.End; * io.KeyMap[(int)ImGuiKey.Delete] = (int)Key.Delete; * io.KeyMap[(int)ImGuiKey.Backspace] = (int)Key.BackSpace; * io.KeyMap[(int)ImGuiKey.Enter] = (int)Key.Enter; * io.KeyMap[(int)ImGuiKey.Escape] = (int)Key.Escape; * io.KeyMap[(int)ImGuiKey.A] = (int)Key.A; * io.KeyMap[(int)ImGuiKey.C] = (int)Key.C; * io.KeyMap[(int)ImGuiKey.V] = (int)Key.V; * io.KeyMap[(int)ImGuiKey.X] = (int)Key.X; * io.KeyMap[(int)ImGuiKey.Y] = (int)Key.Y; * io.KeyMap[(int)ImGuiKey.Z] = (int)Key.Z; * } */ private void RenderImDrawData(ImDrawDataPtr draw_data) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (draw_data.CmdListsCount == 0) { return; } uint totalVBSize = (uint)(draw_data.TotalVtxCount * IM_DRAW_VERT_SIZE); if (totalVBSize > _vertexBufferSize) { int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, totalVBSize); GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _vertexBufferSize = newSize; GL.BindBuffer(BufferTarget.ArrayBuffer, 0); Console.WriteLine($"Resized vertex buffer to new size {_vertexBufferSize}"); } uint totalIBSize = (uint)(draw_data.TotalIdxCount * sizeof(ushort)); if (totalIBSize > _indexBufferSize) { int newSize = (int)Math.Max(_indexBufferSize * 1.5f, totalIBSize); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer); GL.BufferData(BufferTarget.ElementArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _indexBufferSize = newSize; GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); Console.WriteLine($"Resized index buffer to new size {_indexBufferSize}"); } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer); GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(vertexOffsetInVertices * IM_DRAW_VERT_SIZE), cmd_list.VtxBuffer.Size * IM_DRAW_VERT_SIZE, cmd_list.VtxBuffer.Data); GLException.CheckError($"Data Vert {i}"); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer); GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)(indexOffsetInElements * sizeof(ushort)), cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); GLException.CheckError($"Data Idx {i}"); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); vertexOffsetInVertices += (uint)cmd_list.VtxBuffer.Size; indexOffsetInElements += (uint)cmd_list.IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter(0, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _shader.UseShader(); GL.UniformMatrix4(_shader.GetUniformLocation("projection_matrix"), false, ref mvp); GL.Uniform1(_shader.GetUniformLocation("in_fontTexture"), 0); GLException.CheckError("Projection"); GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer); GLException.CheckError("VAO"); draw_data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GLException.CheckError("ImGUI EnableCap"); // Render command lists int vtx_offset = 0; int idx_offset = 0; GLException.CheckError("Bind Font Texture"); for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); GLException.CheckError("Scissor"); GL.DrawElements(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)((idx_offset * sizeof(ushort)) + vtx_offset)); GLException.CheckError("DrawElements"); idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } //_fontTexture.UnbindTexture(); GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); // unbind VAO GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); }
private void RenderImDrawData(ImDrawDataPtr drawData) { if (drawData.CmdListsCount == 0) { return; } //calculate sizes int totalVBSize = drawData.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>(); int totalIBSize = drawData.TotalIdxCount * sizeof(ushort); //resize buffers if (totalVBSize > lastVBSize) { GL.NamedBufferData(meshVBO, totalVBSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); lastVBSize = totalVBSize; } if (totalIBSize > lastIBSize) { GL.NamedBufferData(meshEBO, totalIBSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); lastIBSize = totalIBSize; } int vertexOffsetInVertices = 0; int indexOffsetInElements = 0; for (int i = 0; i < drawData.CmdListsCount; i++) { ImDrawListPtr cmdList = drawData.CmdListsRange[i]; GL.NamedBufferSubData(meshVBO, (IntPtr)(vertexOffsetInVertices * Unsafe.SizeOf <ImDrawVert>()), cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data); GL.NamedBufferSubData(meshEBO, (IntPtr)(indexOffsetInElements * sizeof(ushort)), cmdList.IdxBuffer.Size * sizeof(ushort), cmdList.IdxBuffer.Data); vertexOffsetInVertices += cmdList.VtxBuffer.Size; indexOffsetInElements += cmdList.IdxBuffer.Size; } //enable states GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, //width io.DisplaySize.Y, 0f, //height -1f, 1f); //near and far plane GL.UseProgram(shader); GL.UniformMatrix4(projectionLoc, true, ref mvp); //projection GL.Uniform1(textureLoc, 0); GL.BindVertexArray(meshVAO); drawData.ScaleClipRects(io.DisplayFramebufferScale); //render command lists int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int i = 0; i < cmdList.CmdBuffer.Size; i++) { ImDrawCmdPtr pcmd = cmdList.CmdBuffer[i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idxOffset * sizeof(ushort)), vtxOffset); idxOffset += (int)pcmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); GL.BindVertexArray(0); }
private static void RenderDrawData(ImDrawDataPtr drawData, RID parent) { // allocate and clear out our CanvasItem pool as needed int neededNodes = 0; for (int i = 0; i < drawData.CmdListsCount; i++) { neededNodes += drawData.CmdListsRange[i].CmdBuffer.Size; } while (_children.Count < neededNodes) { RID newChild = VisualServer.CanvasItemCreate(); VisualServer.CanvasItemSetParent(newChild, parent); VisualServer.CanvasItemSetDrawIndex(newChild, _children.Count); _children.Add(newChild); _meshes.Add(new ArrayMesh()); } // trim unused nodes to reduce draw calls while (_children.Count > neededNodes) { int idx = _children.Count - 1; VisualServer.FreeRid(_children[idx]); _children.RemoveAt(idx); _meshes.RemoveAt(idx); } // render drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); int nodeN = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; int idxOffset = 0; int nVert = cmdList.VtxBuffer.Size; Godot.Vector2[] vertices = new Godot.Vector2[nVert]; Godot.Color[] colors = new Godot.Color[nVert]; Godot.Vector2[] uvs = new Godot.Vector2[nVert]; for (int i = 0; i < cmdList.VtxBuffer.Size; i++) { var v = cmdList.VtxBuffer[i]; vertices[i] = new Godot.Vector2(v.pos.X, v.pos.Y); // need to reverse the color bytes byte[] col = BitConverter.GetBytes(v.col); colors[i] = Godot.Color.Color8(col[0], col[1], col[2], col[3]); uvs[i] = new Godot.Vector2(v.uv.X, v.uv.Y); } for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++, nodeN++) { ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi]; int[] indices = new int[drawCmd.ElemCount]; for (int i = idxOffset, j = 0; i < idxOffset + drawCmd.ElemCount; i++, j++) { indices[j] = cmdList.IdxBuffer[i]; } var arrays = new Godot.Collections.Array(); arrays.Resize((int)ArrayMesh.ArrayType.Max); arrays[(int)ArrayMesh.ArrayType.Vertex] = vertices; arrays[(int)ArrayMesh.ArrayType.Color] = colors; arrays[(int)ArrayMesh.ArrayType.TexUv] = uvs; arrays[(int)ArrayMesh.ArrayType.Index] = indices; var mesh = _meshes[nodeN]; while (mesh.GetSurfaceCount() > 0) { mesh.SurfaceRemove(0); } mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); RID child = _children[nodeN]; Texture tex = GetTexture(drawCmd.TextureId); VisualServer.CanvasItemClear(child); VisualServer.CanvasItemSetClip(child, true); VisualServer.CanvasItemSetCustomRect(child, true, new Godot.Rect2( drawCmd.ClipRect.X, drawCmd.ClipRect.Y, drawCmd.ClipRect.Z - drawCmd.ClipRect.X, drawCmd.ClipRect.W - drawCmd.ClipRect.Y) ); VisualServer.CanvasItemAddMesh(child, mesh.GetRid(), null, null, tex.GetRid(), new RID(null)); // why doesn't this quite work? // VisualServer.CanvasItemAddTriangleArray(child, indices, vertices, colors, uvs, null, null, tex.GetRid(), -1, new RID(null)); idxOffset += (int)drawCmd.ElemCount; } } }
private void RenderImDrawData(ImDrawDataPtr draw_data) { if (draw_data.CmdListsCount == 0) { return; } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > _vertexBufferSize) { int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize); GL.NamedBufferData(_vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _vertexBufferSize = newSize; //Console.WriteLine($"Resized dear imgui vertex buffer to new size {_vertexBufferSize}"); } int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort); if (indexSize > _indexBufferSize) { int newSize = (int)Math.Max(_indexBufferSize * 1.5f, indexSize); GL.NamedBufferData(_indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _indexBufferSize = newSize; //Console.WriteLine($"Resized dear imgui index buffer to new size {_indexBufferSize}"); } } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter(0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _shader.UseShader(); _shader.SetMatrix("projection_matrix", ref mvp); _shader.SetInt("in_fontTexture", 0); GLException.CheckError("ImGui Projection"); GL.BindVertexArray(_vertexArray); GLException.CheckError("ImGui VAO"); draw_data.ScaleClipRects(io.DisplayFramebufferScale); SetRenderSettings(io); // Render command lists for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; GL.NamedBufferSubData(_vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); GLException.CheckError($"ImGui Data Vert {n}"); GL.NamedBufferSubData(_indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); GLException.CheckError($"ImGui Data Idx {n}"); int vtx_offset = 0; int idx_offset = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { int callback = (int)pcmd.UserCallback; int callbackData = (int)pcmd.UserCallbackData; if (ImGuiDelegates[callback - 1](ImGuiDelegateArgs[callbackData - 1])) { _shader.UseShader(); _shader.SetMatrix("projection_matrix", ref mvp); _shader.SetInt("in_fontTexture", 0); GLException.CheckError("ImGui Projection"); GL.BindVertexArray(_vertexArray); GLException.CheckError("ImGui VAO"); draw_data.ScaleClipRects(io.DisplayFramebufferScale); // Reset ImGui values SetRenderSettings(io); } } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); GLException.CheckError("ImGui Texture"); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); GLException.CheckError("ImGui Scissor"); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } } GLException.CheckError("ImGui Draw"); idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } UnsetRenderSettings(); }
private void RenderImDrawData(ImDrawDataPtr draw_data) { if (draw_data.CmdListsCount == 0) { return; } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > vertexBufferSize) { int newSize = (int)Math.Max(vertexBufferSize * 1.5f, vertexSize); GL.NamedBufferData(vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); vertexBufferSize = newSize; DevConsole.Log(LogType.Verbose, $"Resized dear imgui vertex buffer to new size {vertexBufferSize}"); } int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort); if (indexSize > indexBufferSize) { int newSize = (int)Math.Max(indexBufferSize * 1.5f, indexSize); GL.NamedBufferData(indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); indexBufferSize = newSize; DevConsole.Log(LogType.Verbose, $"Resized dear imgui index buffer to new size {indexBufferSize}"); } } ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter(0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); material.UseMaterial(); Ogl.UniformMatrix4(material.shader.GetUniformLocation("projection_matrix"), false, ref mvp); Ogl.Uniform1(material.shader.GetUniformLocation("in_fontTexture"), 0); Ogl.BindVertexArray(vao); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer); draw_data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); // Render command lists for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; GL.NamedBufferSubData(vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); GL.NamedBufferSubData(indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); int vtx_offset = 0; int idx_offset = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset); //GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } } idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); }
public void Draw(float elapsedTime) { ImGuiIOPtr io = ImGui.GetIO(); ImGui.NewFrame(); ImGui.PushFont(defaultFont); ImGui.SetNextWindowPos(new Vector2(8, 8)); ImGui.Begin("fps", ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoScrollbar); // Apply exponential smoothing to the FPS. float fps = 1.0f / elapsedTime; avgFPS += 0.1f * (fps - avgFPS); ImGui.Text($"FPS {Math.Round(avgFPS)}"); if (showInfo) { var position = camera.Position; var direction = camera.Front; string posStr = $"Pos {position.X:0.00}, {position.Y:0.00}, {position.Z:0.00}\n" + $"Dir {direction.X:0.00}, {direction.Y:0.00}, {direction.Z:0.00}\n"; ImGui.Text(posStr); } ImGui.End(); if (showInfo) { ImGui.SetNextWindowPos(new Vector2(width - 400 - 8, 8)); ImGui.SetNextWindowSize(new Vector2(400, 0)); ImGui.Begin("info", ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoScrollbar); string info = $"{vendor}\n{renderer}\n{version}\n{glsl}"; ImGui.Text(info); ImGui.End(); } ImGui.PopFont(); ImGui.Render(); ImDrawDataPtr data = ImGui.GetDrawData(); if (data.CmdListsCount == 0) { return; } vertexArray.Bind(); uint requiredVertexBufferSize = (uint)(data.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>()); if (requiredVertexBufferSize > vertexBufferSize) { vertexBufferSize = Math.Max(2 * vertexBufferSize, requiredVertexBufferSize); vertexBuffer.SetData(IntPtr.Zero, (int)vertexBufferSize, BufferUsageHint.DynamicDraw); } uint requiredIndexBufferSize = (uint)(data.TotalIdxCount * sizeof(ushort)); if (requiredIndexBufferSize > indexBufferSize) { indexBufferSize = Math.Max(2 * indexBufferSize, requiredIndexBufferSize); indexBuffer.SetData(IntPtr.Zero, (int)indexBufferSize, BufferUsageHint.DynamicDraw); } uint vertexBufferOffset = 0; uint indexBufferOffset = 0; for (int i = 0; i < data.CmdListsCount; ++i) { ImDrawListPtr list = data.CmdListsRange[i]; uint vertexDataSize = (uint)(list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()); uint indexDataSize = (uint)(list.IdxBuffer.Size * sizeof(ushort)); vertexBuffer.Bind(); GL.BufferSubData(vertexBuffer.BufferTarget, (IntPtr)vertexBufferOffset, (int)vertexDataSize, list.VtxBuffer.Data); indexBuffer.Bind(); GL.BufferSubData(indexBuffer.BufferTarget, (IntPtr)indexBufferOffset, (int)indexDataSize, list.IdxBuffer.Data); vertexBufferOffset += vertexDataSize; indexBufferOffset += indexDataSize; } Matrix4 projection = Matrix4.CreateOrthographicOffCenter(0, io.DisplaySize.X, io.DisplaySize.Y, 0, -1, 1); shaderProgram.Use(); shaderProgram.SetUniform("font_texture", 0); shaderProgram.SetUniform("projection", ref projection); data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.StencilTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); uint indexOffset = 0; uint vertexOffset = 0; for (int i = 0; i < data.CmdListsCount; ++i) { ImDrawListPtr list = data.CmdListsRange[i]; for (int j = 0; j < list.CmdBuffer.Size; ++j) { ImDrawCmdPtr cmd = list.CmdBuffer[j]; if (cmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { texture.Bind(); Vector4 clip = cmd.ClipRect; GL.Scissor((int)clip.X, (int)height - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)cmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(indexOffset * sizeof(ushort)), (int)vertexOffset); } indexOffset += cmd.ElemCount; } vertexOffset += (uint)list.VtxBuffer.Size; } VertexArray.Unbind(); }
private void RenderImDrawData(ImDrawDataPtr draw_data) { if (draw_data.CmdListsCount == 0) { return; } //Update Mesh int totalVBSize = draw_data.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>(); int totalIBSize = draw_data.TotalIdxCount * sizeof(ushort); mesh.UpdateMeshData( IntPtr.Zero, IntPtr.Zero, totalVBSize, totalIBSize); int vertexOffsetInVertices = 0; int indexOffsetInElements = 0; for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; GL.NamedBufferSubData(mesh.VBO, (IntPtr)(vertexOffsetInVertices * Unsafe.SizeOf <ImDrawVert>()), cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); GL.NamedBufferSubData(mesh.EBO, (IntPtr)(indexOffsetInElements * sizeof(ushort)), cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); vertexOffsetInVertices += cmd_list.VtxBuffer.Size; indexOffsetInElements += cmd_list.IdxBuffer.Size; } //Enable render states GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter( 0.0f, io.DisplaySize.X, //width io.DisplaySize.Y, 0.0f, //height -1.0f, 1.0f); //near and far plane shader.Use(); shader.SetMatrix4("projection_matrix", mvp); shader.SetInt("in_fontTexture", 0); mesh.Use(); draw_data.ScaleClipRects(io.DisplayFramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset); } idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); GL.BindVertexArray(0); }
private static unsafe void renderDrawData(ImDrawDataPtr drawData) { // scale coordinates for retina displays ImGuiIOPtr io = ImGui.GetIO(); int fbWidth = (int)(io.DisplaySize.X * io.DisplayFramebufferScale.X); int fbHeight = (int)(io.DisplaySize.Y * io.DisplayFramebufferScale.Y); if (fbWidth < 0 || fbHeight < 0) { return; } drawData.ScaleClipRects(io.DisplayFramebufferScale); // backup GL state GL.GetInteger(GetPName.ActiveTexture, out int lastActiveTexture); GL.ActiveTexture(TextureUnit.Texture0); GL.GetInteger(GetPName.CurrentProgram, out int lastProgram); GL.GetInteger(GetPName.TextureBinding2D, out int lastTexture); GL.GetInteger(GetPName.SamplerBinding, out int lastSampler); GL.GetInteger(GetPName.ArrayBufferBinding, out int lastArrayBuffer); GL.GetInteger(GetPName.VertexArrayBinding, out int lastVertexArray); int[] lastPolygonMode = new int[2]; GL.GetInteger(GetPName.PolygonMode, lastPolygonMode); int[] lastViewport = new int[4]; GL.GetInteger(GetPName.Viewport, lastViewport); int[] lastScissorBox = new int[4]; GL.GetInteger(GetPName.ScissorBox, lastScissorBox); GL.GetInteger(GetPName.BlendSrcRgb, out int lastBlendSrcRgb); GL.GetInteger(GetPName.BlendDstRgb, out int lastBlendDstRgb); GL.GetInteger(GetPName.BlendSrcAlpha, out int lastBlendSrcAlpha); GL.GetInteger(GetPName.BlendDstAlpha, out int lastBlendDstAlpha); GL.GetInteger(GetPName.BlendEquationRgb, out int lastBlendEquationRgb); GL.GetInteger(GetPName.BlendEquationAlpha, out int lastBlendEquationAlpha); bool lastEnableBlend = GL.IsEnabled(EnableCap.Blend); bool lastEnableCullFace = GL.IsEnabled(EnableCap.CullFace); bool lastEnableDepthTest = GL.IsEnabled(EnableCap.DepthTest); bool lastEnableScissorTest = GL.IsEnabled(EnableCap.ScissorTest); // setup GL state GL.Enable(EnableCap.Blend); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); // setup viewport with orthographic projecton matrix GL.Viewport(0, 0, fbWidth, fbHeight); float l = 0; float r = io.DisplaySize.X; float t = 0; float b = io.DisplaySize.Y; Matrix4 orthoProjection = new Matrix4( 2.0f / (r - l), 0, 0, 0, 0, 2.0f / (t - b), 0, 0, 0, 0, -1.0f, 0, (r + l) / (l - r), (t + b) / (b - t), 0, 1.0f ); GL.UseProgram(_programHandle); GL.Uniform1(_attribLocationTex, 0); GL.UniformMatrix4(_attribLocationProjMtx, false, ref orthoProjection); GL.BindSampler(0, 0); // recreate the VAO every time int vaoHandle = GL.GenVertexArray(); GL.BindVertexArray(vaoHandle); GL.BindBuffer(BufferTarget.ArrayBuffer, _vboHandle); GL.EnableVertexAttribArray(_attribLocationPosition); GL.EnableVertexAttribArray(_attribLocationUV); GL.EnableVertexAttribArray(_attribLocationColor); GL.VertexAttribPointer(_attribLocationPosition, 2, VertexAttribPointerType.Float, false, ImGuiVert.Size, ImGuiVert.PosOffset); GL.VertexAttribPointer(_attribLocationUV, 2, VertexAttribPointerType.Float, false, ImGuiVert.Size, ImGuiVert.UVOffset); GL.VertexAttribPointer(_attribLocationColor, 4, VertexAttribPointerType.UnsignedByte, false, ImGuiVert.Size, ImGuiVert.ColOffset); // draw System.Numerics.Vector2 pos = new System.Numerics.Vector2(l, t); for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; int indexBufferOffset = 0; GL.BindBuffer(BufferTarget.ArrayBuffer, _vboHandle); GL.BufferData(BufferTarget.ArrayBuffer, cmdList.VtxBuffer.Size * ImGuiVert.Size, cmdList.VtxBuffer.Data, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementsHandle); GL.BufferData(BufferTarget.ElementArrayBuffer, cmdList.IdxBuffer.Size * sizeof(ushort), cmdList.IdxBuffer.Data, BufferUsageHint.StreamDraw); for (int cmdIndex = 0; cmdIndex < cmdList.CmdBuffer.Size; cmdIndex++) { ImDrawCmdPtr pCmd = cmdList.CmdBuffer[cmdIndex]; Vector4 clipRect = new Vector4( pCmd.ClipRect.X - pos.X, pCmd.ClipRect.Y - pos.Y, pCmd.ClipRect.Z - pos.X, pCmd.ClipRect.W - pos.Y ); GL.Scissor((int)clipRect.X, (int)(fbHeight - clipRect.W), (int)(clipRect.Z - clipRect.X), (int)(clipRect.W - clipRect.Y)); GL.BindTexture(TextureTarget.Texture2D, pCmd.TextureId.ToInt32()); GL.DrawElements(BeginMode.Triangles, (int)pCmd.ElemCount, DrawElementsType.UnsignedShort, indexBufferOffset); indexBufferOffset += (int)pCmd.ElemCount * 2; } } GL.DeleteVertexArray(vaoHandle); // restore modified GL state GL.UseProgram(lastProgram); GL.BindTexture(TextureTarget.Texture2D, lastTexture); GL.BindSampler(0, lastSampler); GL.ActiveTexture((TextureUnit)lastActiveTexture); GL.BindVertexArray(lastVertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, lastArrayBuffer); GL.BlendEquationSeparate((BlendEquationMode)lastBlendEquationRgb, (BlendEquationMode)lastBlendEquationAlpha); GL.BlendFuncSeparate((BlendingFactorSrc)lastBlendSrcRgb, (BlendingFactorDest)lastBlendDstRgb, (BlendingFactorSrc)lastBlendSrcAlpha, (BlendingFactorDest)lastBlendDstAlpha); if (lastEnableBlend) { GL.Enable(EnableCap.Blend); } else { GL.Disable(EnableCap.Blend); } if (lastEnableCullFace) { GL.Enable(EnableCap.CullFace); } else { GL.Disable(EnableCap.CullFace); } if (lastEnableDepthTest) { GL.Enable(EnableCap.DepthTest); } else { GL.Disable(EnableCap.DepthTest); } if (lastEnableScissorTest) { GL.Enable(EnableCap.ScissorTest); } else { GL.Disable(EnableCap.ScissorTest); } GL.PolygonMode(MaterialFace.FrontAndBack, (PolygonMode)lastPolygonMode[0]); GL.Viewport(lastViewport[0], lastViewport[1], lastViewport[2], lastViewport[3]); GL.Scissor(lastScissorBox[0], lastScissorBox[1], lastScissorBox[2], lastScissorBox[3]); }
private void RenderImDrawData(ImDrawDataPtr draw_data, GraphicsDevice gd, CommandList cl) { #if DEBUG using Profiler fullProfiler = new Profiler(GetType()); #endif if (draw_data.CmdListsCount == 0) { return; } uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; uint totalVBSize = (uint)(draw_data.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>()); if (totalVBSize > vertexBuffer.SizeInBytes) { gd.DisposeWhenIdle(vertexBuffer); vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); } uint totalIBSize = (uint)(draw_data.TotalIdxCount * sizeof(ushort)); if (totalIBSize > indexBuffer.SizeInBytes) { gd.DisposeWhenIdle(indexBuffer); indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; cl.UpdateBuffer( vertexBuffer, vertexOffsetInVertices * (uint)Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data, (uint)(cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>())); cl.UpdateBuffer( indexBuffer, indexOffsetInElements * sizeof(ushort), cmd_list.IdxBuffer.Data, (uint)(cmd_list.IdxBuffer.Size * sizeof(ushort))); vertexOffsetInVertices += (uint)cmd_list.VtxBuffer.Size; indexOffsetInElements += (uint)cmd_list.IdxBuffer.Size; } //Setup orthographic projection matrix regarding backend (view matrix is identity) Matrix4x4 proj; if (gd.BackendType == GraphicsBackend.Vulkan) { proj = new ImGuiCamera( draw_data.DisplayPos.X, draw_data.DisplayPos.X + draw_data.DisplaySize.X, draw_data.DisplayPos.Y, draw_data.DisplayPos.Y + draw_data.DisplaySize.Y).ProjectionMatrix; } else { proj = new ImGuiCamera( draw_data.DisplayPos.X, draw_data.DisplayPos.X + draw_data.DisplaySize.X, draw_data.DisplayPos.Y + draw_data.DisplaySize.Y, draw_data.DisplayPos.Y).ProjectionMatrix; } cl.SetPipeline(pipeline); cl.SetFullViewports(); cl.SetVertexBuffer(0, vertexBuffer); cl.SetIndexBuffer(indexBuffer, IndexFormat.UInt16); cl.UpdateBuffer(projMatrixBuffer, 0, ref proj); cl.SetGraphicsResourceSet(0, mainResourceSet); draw_data.ScaleClipRects(draw_data.FramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new BootEngineException("ImGUI command user callback not implemented."); } else { if (pcmd.TextureId != IntPtr.Zero) { if (pcmd.TextureId == fontAtlasID) { cl.SetGraphicsResourceSet(1, fontTextureResourceSet); } else { cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId)); } } Vector2 clipOff = draw_data.DisplayPos; Vector2 clipScale = draw_data.FramebufferScale; cl.SetScissorRect( 0, (uint)((pcmd.ClipRect.X - clipOff.X) * clipScale.X), (uint)((pcmd.ClipRect.Y - clipOff.Y) * clipScale.Y), (uint)((pcmd.ClipRect.Z - clipOff.X) * clipScale.X), (uint)((pcmd.ClipRect.W - clipOff.Y) * clipScale.Y)); cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idx_offset, vtx_offset, 0); } idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } }
unsafe void RenderImDrawData(ImDrawDataPtr draw_data, RenderState rstate) { var io = ImGui.GetIO(); //Set cursor var cur = ImGuiNative.igGetMouseCursor(); switch (cur) { case ImGuiMouseCursor.Arrow: game.CursorKind = CursorKind.Arrow; break; case ImGuiMouseCursor.ResizeAll: game.CursorKind = CursorKind.Move; break; case ImGuiMouseCursor.TextInput: game.CursorKind = CursorKind.TextInput; break; case ImGuiMouseCursor.ResizeNS: game.CursorKind = CursorKind.ResizeNS; break; case ImGuiMouseCursor.ResizeNESW: game.CursorKind = CursorKind.ResizeNESW; break; case ImGuiMouseCursor.ResizeNWSE: game.CursorKind = CursorKind.ResizeNWSE; break; } //Render draw_data.ScaleClipRects(io.DisplayFramebufferScale); var mat = Matrix4.CreateOrthographicOffCenter(0, game.Width, game.Height, 0, 0, 1); Shader lastShader = textShader; textShader.SetMatrix(textShader.GetLocation("modelviewproj"), ref mat); textShader.SetInteger(textShader.GetLocation("tex"), 0); colorShader.SetMatrix(textShader.GetLocation("modelviewproj"), ref mat); colorShader.SetInteger(textShader.GetLocation("tex"), 0); textShader.UseProgram(); rstate.Cull = false; rstate.BlendMode = BlendMode.Normal; rstate.DepthEnabled = false; for (int n = 0; n < draw_data.CmdListsCount; n++) { var cmd_list = draw_data.CmdListsRange[n]; byte * vtx_buffer = (byte *)cmd_list.VtxBuffer.Data; ushort *idx_buffer = (ushort *)cmd_list.IdxBuffer.Data; var vtxCount = cmd_list.VtxBuffer.Size; var idxCount = cmd_list.IdxBuffer.Size; if (vboSize < vtxCount || iboSize < idxCount) { if (vbo != null) { vbo.Dispose(); } if (ibo != null) { ibo.Dispose(); } vboSize = Math.Max(vboSize, vtxCount); iboSize = Math.Max(iboSize, idxCount); vbo = new VertexBuffer(typeof(Vertex2D), vboSize, true); ibo = new ElementBuffer(iboSize, true); vbo.SetElementBuffer(ibo); vbuffer = new Vertex2D[vboSize]; ibuffer = new ushort[iboSize]; } for (int i = 0; i < cmd_list.IdxBuffer.Size; i++) { ibuffer[i] = idx_buffer[i]; } for (int i = 0; i < cmd_list.VtxBuffer.Size; i++) { var ptr = (ImDrawVert *)vtx_buffer; var unint = ptr[i].col; var a = unint >> 24 & 0xFF; var b = unint >> 16 & 0xFF; var g = unint >> 8 & 0xFF; var r = unint & 0xFF; vbuffer[i] = new Vertex2D(ptr[i].pos, ptr[i].uv, new Color4(r / 255f, g / 255f, b / 255f, a / 255f)); } vbo.SetData(vbuffer, cmd_list.VtxBuffer.Size); ibo.SetData(ibuffer, cmd_list.IdxBuffer.Size); int startIndex = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { var pcmd = cmd_list.CmdBuffer[cmd_i]; //TODO: Do something with pcmd->UserCallback ?? var tid = pcmd.TextureId.ToInt32(); Texture2D tex; if (tid == FONT_TEXTURE_ID) { if (lastShader != textShader) { textShader.UseProgram(); lastShader = textShader; } fontTexture.BindTo(0); } else if (textures.TryGetValue(tid, out tex)) { if (lastShader != colorShader) { colorShader.UseProgram(); lastShader = colorShader; } tex.BindTo(0); } else { dot.BindTo(0); } GL.Enable(GL.GL_SCISSOR_TEST); GL.Scissor( (int)pcmd.ClipRect.X, (int)(io.DisplaySize.Y - pcmd.ClipRect.W), (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y)); vbo.Draw(PrimitiveTypes.TriangleList, 0, startIndex, (int)pcmd.ElemCount / 3); GL.Disable(GL.GL_SCISSOR_TEST); startIndex += (int)pcmd.ElemCount; } } }
private unsafe void RenderImDrawData(ImDrawDataPtr drawData) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (drawData.CmdListsCount == 0) { return; } uint totalVbSize = (uint)(drawData.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>()); if (totalVbSize > _vertexBufferSize) { int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, totalVbSize); _gl.NamedBufferData(_vertexBuffer, (uint)newSize, null, VertexBufferObjectUsage.DynamicDraw); _vertexBufferSize = (uint)newSize; if (_glVersion >= new Version(4, 3)) { var str = $"Silk.NET ImGui: Resized vertex buffer to new size {_vertexBufferSize}"; _gl.DebugMessageInsert(DebugSource.DebugSourceApi, DebugType.DontCare, 1879701u, DebugSeverity.DebugSeverityNotification, (uint)str.Length, str); } } uint totalIbSize = (uint)(drawData.TotalIdxCount * sizeof(ushort)); if (totalIbSize > _indexBufferSize) { int newSize = (int)Math.Max(_indexBufferSize * 1.5f, totalIbSize); _gl.NamedBufferData(_indexBuffer, (uint)newSize, null, VertexBufferObjectUsage.DynamicDraw); _indexBufferSize = (uint)newSize; if (_glVersion >= new Version(4, 3)) { var str = $"Silk.NET ImGui: Resized index buffer to new size {_indexBufferSize}"; _gl.DebugMessageInsert(DebugSource.DebugSourceApi, DebugType.DontCare, 1879702u, DebugSeverity.DebugSeverityNotification, (uint)str.Length, str); } } for (int i = 0; i < drawData.CmdListsCount; i++) { ImDrawListPtr cmdList = drawData.CmdListsRange[i]; _gl.NamedBufferSubData(_vertexBuffer, (IntPtr)(vertexOffsetInVertices * Unsafe.SizeOf <ImDrawVert>()), (UIntPtr)(cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()), (void *)cmdList.VtxBuffer.Data); _gl.CheckGlError($"Data Vert {i}"); _gl.NamedBufferSubData(_indexBuffer, (IntPtr)(indexOffsetInElements * sizeof(ushort)), (UIntPtr)(cmdList.IdxBuffer.Size * sizeof(ushort)), (void *)cmdList.IdxBuffer.Data); _gl.CheckGlError($"Data Idx {i}"); vertexOffsetInVertices += (uint)cmdList.VtxBuffer.Size; indexOffsetInElements += (uint)cmdList.IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGuiNET.ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( -1.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _shader.UseShader(); _gl.ProgramUniformMatrix4(_shader.Program, _shader.GetUniformLocation("projection_matrix"), 1, false, (float *)Unsafe.AsPointer(ref mvp)); _gl.ProgramUniform1(_shader.Program, _shader.GetUniformLocation("in_fontTexture"), 0); _gl.CheckGlError("Projection"); _gl.BindVertexArray(_vertexArray); _gl.CheckGlError("VAO"); drawData.ScaleClipRects(io.DisplayFramebufferScale); _gl.Enable(EnableCap.Blend); _gl.Enable(EnableCap.ScissorTest); _gl.BlendEquation(BlendEquationModeEXT.FuncAdd); _gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); _gl.Disable(EnableCap.CullFace); _gl.Disable(EnableCap.DepthTest); // Render command lists int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int cmdI = 0; cmdI < cmdList.CmdBuffer.Size; cmdI++) { ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdI]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { _gl.ActiveTexture(TextureUnit.Texture0); _gl.BindTexture(TextureTarget.Texture2D, (uint)pcmd.TextureId); _gl.CheckGlError("Texture"); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; _gl.Scissor((int)clip.X, _windowHeight - (int)clip.W, (uint)(clip.Z - clip.X), (uint)(clip.W - clip.Y)); _gl.CheckGlError("Scissor"); _gl.DrawElementsBaseVertex(PrimitiveType.Triangles, (uint)pcmd.ElemCount, DrawElementsType.UnsignedShort, (void *)(idxOffset * sizeof(ushort)), vtxOffset); _gl.CheckGlError("Draw"); } idxOffset += (int)pcmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } _gl.Disable(EnableCap.Blend); _gl.Disable(EnableCap.ScissorTest); }
private void RenderImDrawData(ImDrawDataPtr draw_data) { if (draw_data.CmdListsCount == 0) { return; } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > _vertexBufferSize) { int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize); GL.NamedBufferData(_vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _vertexBufferSize = newSize; Console.WriteLine($"Resized dear imgui vertex buffer to new size {_vertexBufferSize}"); } int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort); if (indexSize > _indexBufferSize) { int newSize = (int)Math.Max(_indexBufferSize * 1.5f, indexSize); GL.NamedBufferData(_indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _indexBufferSize = newSize; Console.WriteLine($"Resized dear imgui index buffer to new size {_indexBufferSize}"); } } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter( 0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _shaderLoader.UseShader(); GL.UniformMatrix4(_shaderLoader.GetUniformLocation("projection_matrix"), false, ref mvp); GL.Uniform1(_shaderLoader.GetUniformLocation("in_fontTexture"), 0); Util.CheckGLError("Projection"); GL.BindVertexArray(_vertexArray); Util.CheckGLError("VAO"); draw_data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); // Render command lists for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; GL.NamedBufferSubData(_vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); Util.CheckGLError($"Data Vert {n}"); GL.NamedBufferSubData(_indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); Util.CheckGLError($"Data Idx {n}"); int vtx_offset = 0; int idx_offset = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); Util.CheckGLError("Texture"); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); Util.CheckGLError("Scissor"); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } Util.CheckGLError("Draw"); } idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); }
private static void RenderImDrawData(ImDrawDataPtr data) { if (data.CmdListsCount == 0) { return; } for (int i = 0; i < data.CmdListsCount; i++) { ImDrawListPtr cmd_list = data.CmdListsRange[i]; int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > vertexBufferSize) { int newSize = (int)MathHelper.Max(vertexBufferSize * 1.5f, vertexSize); // New Code vertexBuffer.SetData(IntPtr.Zero, newSize); //GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); //GL.BufferData(BufferTarget.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); // //GL.NamedBufferData(vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); vertexBufferSize = newSize; } int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort); if (indexSize > indexBufferSize) { int newSize = (int)MathHelper.Max(indexBufferSize * 1.5f, indexSize); // New Code indexBuffer.SetData(IntPtr.Zero, newSize); //GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer); //GL.BufferData(BufferTarget.ElementArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); // //GL.NamedBufferData(indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); indexBufferSize = newSize; } } GL.Viewport(0, 0, (int)data.DisplaySize.X, (int)data.DisplaySize.Y); // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter( data.DisplayPos.X, data.DisplayPos.X + data.DisplaySize.X, data.DisplayPos.Y + data.DisplaySize.Y, data.DisplayPos.Y, -1.0f, 1.0f); shader.Bind(); shader.SetMatrix4("projection_matrix", false, ref mvp); shader.SetInt("in_fontTexture", 0); vertexArray.Bind(); data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); // Render command lists for (int n = 0; n < data.CmdListsCount; n++) { ImDrawListPtr cmd_list = data.CmdListsRange[n]; // New Code vertexBuffer.SetSubData(cmd_list.VtxBuffer.Data, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()); indexBuffer.SetData(cmd_list.IdxBuffer.Data, cmd_list.IdxBuffer.Size * sizeof(ushort)); //GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); //GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf<ImDrawVert>(), cmd_list.VtxBuffer.Data); // //GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer); //GL.BufferSubData(BufferTarget.ElementArrayBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); // //GL.NamedBufferSubData(vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf<ImDrawVert>(), cmd_list.VtxBuffer.Data); //GL.NamedBufferSubData(indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); int vtx_offset = 0; int idx_offset = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, window.Height - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } } idx_offset += (int)pcmd.ElemCount; } } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); //GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); vertexArray.Unbind(); }
public unsafe void RenderDrawData(ImDrawDataPtr drawData, int displayW, int displayH) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. int last_texture; GL.GetInteger(GetPName.TextureBinding2D, out last_texture); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) var io = ImGui.GetIO(); drawData.ScaleClipRects(io.DisplayFramebufferScale); shader.Use(); Matrix4 modelView = Matrix4.Identity; Matrix4 projection = new Matrix4(); OrthoCamera(io.DisplaySize.X / io.DisplayFramebufferScale.X, io.DisplaySize.Y / io.DisplayFramebufferScale.Y, ref projection); shader.SetUniformMatrix4("modelView", modelView); shader.SetUniformMatrix4("projection", projection); shader.SetSamplerUniform(0, 0); GL.ActiveTexture(TextureUnit.Texture0); // Render command lists for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmd_list = drawData.CmdListsRange[n]; byte * vtx_buffer = (byte *)cmd_list.VtxBuffer.Data; ushort * idx_buffer = (ushort *)cmd_list.IdxBuffer.Data; Vertex2DColorUV vertex = new Vertex2DColorUV(); var sz = sizeof(Vertex2DColorUV); var buffer = new VertexBuffer <Vertex2DColorUV>(vtx_buffer, cmd_list.VtxBuffer.Size * sizeof(Vertex2DColorUV), vertex.GetVertexFormat()); buffer.Bind(shader); for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.BindTexture(TextureTarget.Texture2D, pcmd.TextureId.ToInt32()); GL.Scissor((int)pcmd.ClipRect.X, (int)(io.DisplaySize.Y - pcmd.ClipRect.W), (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y)); GL.DrawElements(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, new IntPtr(idx_buffer)); } idx_buffer += pcmd.ElemCount; } } // Restore modified state GL.BindTexture(TextureTarget.Texture2D, last_texture); GL.Disable(EnableCap.ScissorTest); }
private static void IGRender2(ImDrawDataPtr dd) { if (dd.CmdListsCount == 0) { return; } for (int i = 0; i < dd.CmdListsCount; i++) { ImDrawListPtr cmd_list = dd.CmdListsRange[i]; int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > VtxBufSize) { int newSize = (int)Math.Max(VtxBufSize * 1.5f, vertexSize); GL.NamedBufferData(VertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); VtxBufSize = newSize; } int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort); if (indexSize > IdxBufSize) { int newSize = (int)Math.Max(IdxBufSize * 1.5f, indexSize); GL.NamedBufferData(IndexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); IdxBufSize = newSize; } } var io = ImGui.GetIO(); var MVP = Matrix4.CreateOrthographicOffCenter(0.0f, Engine.Width, Engine.Height, 0.0f, -1.0f, 1.0f); ImGuiProgram.Use(); ImGuiProgram.UniformMatrix4("Projection", ref MVP); GL.Uniform1(ImGuiProgram.UniformLocation("Texture"), 0); IG_VAO.Bind(); dd.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); for (int n = 0; n < dd.CmdListsCount; n++) { ImDrawListPtr cmdList = dd.CmdListsRange[n]; GL.NamedBufferSubData(VertexBuffer, IntPtr.Zero, cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data); GL.NamedBufferSubData(IndexBuffer, IntPtr.Zero, cmdList.IdxBuffer.Size * sizeof(ushort), cmdList.IdxBuffer.Data); int vOffset = 0; int iOffset = 0; for (int i = 0; i < cmdList.CmdBuffer.Size; i++) { ImDrawCmdPtr pcmd = cmdList.CmdBuffer[i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GLTexture.Active(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, Engine.Height - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(iOffset * sizeof(ushort)), vOffset); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } } iOffset += (int)pcmd.ElemCount; } vOffset += cmdList.VtxBuffer.Size; } GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); }