private void RenderImDrawData(DrawData *data) { for (int n = 0; n < data->CmdListsCount; n++) { NativeDrawList *cmdList = data->CmdLists[n]; byte * vb = (byte *)cmdList->VtxBuffer.Data; ushort * ib = (ushort *)cmdList->IdxBuffer.Data; UpdateVB(cmdList->VtxBuffer.Size, vb); for (int cmd_i = 0; cmd_i < cmdList->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmdList->CmdBuffer.Data)[cmd_i]); if (pcmd->UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { var texid = pcmd->TextureId.ToInt32(); UpdateIB((int)pcmd->ElemCount, ib); _indexBuffer.Draw(_vertexBuffer, 0, (int)pcmd->ElemCount); } ib += pcmd->ElemCount; } } }
private bool UpdateBuffer(DeviceContextProxy deviceContext) { unsafe { var data = ImGui.GetDrawData(); if (data->CmdListsCount == 0) { return(false); } Buffer.SpriteCount = data->TotalVtxCount; Buffer.IndexCount = data->TotalIdxCount; Buffer.VertexBufferInternal.EnsureBufferCapacity(deviceContext, data->TotalVtxCount, data->TotalVtxCount * 2); Buffer.IndexBufferInternal.EnsureBufferCapacity(deviceContext, data->TotalIdxCount, data->TotalIdxCount * 2); Buffer.VertexBufferInternal.MapBuffer(deviceContext, (stream) => { for (int i = 0; i < data->CmdListsCount; i++) { NativeDrawList *cmd_list = data->CmdLists[i]; int vCount = cmd_list->VtxBuffer.Size * sizeof(DrawVert); stream.WriteRange((IntPtr)cmd_list->VtxBuffer.Data, vCount); } }); Buffer.IndexBufferInternal.MapBuffer(deviceContext, (stream) => { for (int i = 0; i < data->CmdListsCount; i++) { NativeDrawList *cmd_list = data->CmdLists[i]; int iCount = cmd_list->IdxBuffer.Size * sizeof(ushort); stream.WriteRange((IntPtr)cmd_list->IdxBuffer.Data, iCount); } }); } return(true); }
/// <summary> /// Helper to scale the ClipRect field of each ImDrawCmd. /// Use if your final output buffer is at a different scale than ImGui expects, /// or if there is a difference between your window resolution and framebuffer resolution. /// </summary> /// <param name="drawData">Pointer to the DrawData to scale.</param> /// <param name="scale">The scale to apply.</param> public static unsafe void ScaleClipRects(DrawData *drawData, Vector2 scale) { for (int i = 0; i < drawData->CmdListsCount; i++) { NativeDrawList *cmd_list = drawData->CmdLists[i]; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *drawCmdList = (DrawCmd *)cmd_list->CmdBuffer.Data; DrawCmd *cmd = &drawCmdList[cmd_i]; cmd->ClipRect = new Vector4(cmd->ClipRect.X * scale.X, cmd->ClipRect.Y * scale.Y, cmd->ClipRect.Z * scale.X, cmd->ClipRect.W * scale.Y); } } }
public static extern void ImDrawList_PrimRectUV(NativeDrawList *list, Vector2 a, Vector2 b, Vector2 uv_a, Vector2 uv_b, uint col);
public static extern void ImDrawList_PrimQuadUV(NativeDrawList *list, Vector2 a, Vector2 b, Vector2 c, Vector2 d, Vector2 uv_a, Vector2 uv_b, Vector2 uv_c, Vector2 uv_d, uint col);
public static extern void ImDrawList_PathFill(NativeDrawList *list, uint col);
public static extern void ImDrawList_PathLineTo(NativeDrawList *list, Vector2 pos);
public static unsafe void render(BasicEffect effect) { IO io = ImGui.GetIO(); ImGui.Render(); DrawData *draw_data = ImGui.GetDrawData(); var graphicsDevice = _game.GraphicsDevice; graphicsDevice.DepthStencilState = DepthStencilState.None; graphicsDevice.RasterizerState = new RasterizerState() { ScissorTestEnable = true, CullMode = CullMode.None }; graphicsDevice.SamplerStates[0] = SamplerState.PointClamp; graphicsDevice.BlendState = BlendState.AlphaBlend; // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) ImGui.ScaleClipRects(draw_data, io.DisplayFramebufferScale); //var effect = Assets.defaultEffect; //effect.Texture = Assets.dummyTexture; effect.World = Matrix.Identity; effect.View = Matrix.Identity;// camera.viewMatrix3D; effect.Projection = Matrix.CreateOrthographicOffCenter( 0.0f, io.DisplaySize.X / io.DisplayFramebufferScale.X, io.DisplaySize.Y / io.DisplayFramebufferScale.Y, 0.0f, -1.0f, 1.0f ); // Render command lists for (int n = 0; n < draw_data->CmdListsCount; n++) { NativeDrawList *cmd_list = draw_data->CmdLists[n]; DrawVert * vtx_buffer = (DrawVert *)cmd_list->VtxBuffer.Data; ushort * idx_buffer = (ushort *)cmd_list->IdxBuffer.Data; var vertexElements = cmd_list->VtxBuffer.Size; var indexElements = cmd_list->IdxBuffer.Size; var idxPos = 0; if (vertices.Length < vertexElements) { vertices = new ImGuiVertex[vertexElements / 2 * 3]; _vertexBuffer.Dispose(); _vertexBuffer = new VertexBuffer(graphicsDevice, ImGuiVertex.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); } for (int i = 0; i < vertexElements; i++) { DrawVert vert = *vtx_buffer++; vertices[i].x = vert.pos.X; vertices[i].y = vert.pos.Y; vertices[i].tx = vert.uv.X; vertices[i].ty = vert.uv.Y; vertices[i].color = vert.col; } _vertexBuffer.SetData(vertices, 0, vertexElements); if (indices.Length < indexElements) { indices = new short[indexElements / 2 * 3]; _indexBuffer.Dispose(); _indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); } for (int i = 0; i < indexElements; i++) { indices[i] = (short)idx_buffer[i]; } _indexBuffer.SetData(indices, 0, indexElements); graphicsDevice.Indices = _indexBuffer; graphicsDevice.SetVertexBuffer(_vertexBuffer); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmd_list->CmdBuffer.Data)[cmd_i]); if (pcmd->UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { graphicsDevice.ScissorRectangle = new Rectangle((int)pcmd->ClipRect.X, (int)pcmd->ClipRect.Y, (int)(pcmd->ClipRect.Z - pcmd->ClipRect.X), (int)(pcmd->ClipRect.W - pcmd->ClipRect.Y)); if (pcmd->TextureId.ToInt32() == fontTexture.GetHashCode()) { effect.Texture = fontTexture; } else { throw new NotImplementedException(); } var primivites = (int)pcmd->ElemCount / 3; foreach (var pass in effect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, idxPos, primivites); //graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertexElements, indices, 0, indexElements / 3); } } idxPos += (int)pcmd->ElemCount; } } }
private unsafe void RenderImDrawData(DrawData *drawData) { IO 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) { ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale); int lastActiveTexture; GL.GetInteger(GetPName.ActiveTexture, out lastActiveTexture); //Console.WriteLine(GL.GetError()); GL.ActiveTexture(TextureUnit.Texture0); //Console.WriteLine(GL.GetError()); int lastProgram; GL.GetInteger(GetPName.CurrentProgram, out lastProgram); //Console.WriteLine(GL.GetError()); int lastTexture; GL.GetInteger(GetPName.TextureBinding2D, out lastTexture); //Console.WriteLine(GL.GetError()); int lastArrayBuffer; GL.GetInteger(GetPName.ArrayBufferBinding, out lastArrayBuffer); int lastElementArrayBuffer; GL.GetInteger(GetPName.ElementArrayBufferBinding, out lastElementArrayBuffer); int lastVertexArray; GL.GetInteger(GetPName.VertexArrayBinding, out lastVertexArray); int lastBlendSrcRgb; GL.GetInteger(GetPName.BlendSrcRgb, out lastBlendSrcRgb); int lastBlendDstRgb; GL.GetInteger(GetPName.BlendDstRgb, out lastBlendDstRgb); int lastBlendSrcAlpha; GL.GetInteger(GetPName.BlendSrcAlpha, out lastBlendSrcAlpha); int lastBlendDstAlpha; GL.GetInteger(GetPName.BlendDstAlpha, out lastBlendDstAlpha); int lastBlendEquationRgb; GL.GetInteger(GetPName.BlendEquationRgb, out lastBlendEquationRgb); int lastBlendEquationAlpha; GL.GetInteger(GetPName.BlendEquationAlpha, out lastBlendEquationAlpha); //Console.WriteLine(GL.GetError()); int[] lastViewport = new int[4]; GL.GetInteger(GetPName.Viewport, lastViewport); int[] lastScissorBox = new int[4]; GL.GetInteger(GetPName.ScissorBox, lastScissorBox); //Console.WriteLine(GL.GetError()); bool lastEnableBlend = GL.IsEnabled(EnableCap.Blend); bool lastEnableCullFace = GL.IsEnabled(EnableCap.CullFace); bool lastEnableDepthTest = GL.IsEnabled(EnableCap.DepthTest); bool lastEnableScissorTest = GL.IsEnabled(EnableCap.ScissorTest); GL.Enable(EnableCap.Blend); GL.BlendEquation(BlendEquationMode.FuncAdd); //GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); GL.Viewport(0, 0, fbWidth, fbHeight); Matrix4 orthoProjection = new Matrix4( 2.0f / io.DisplaySize.X, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / -io.DisplaySize.Y, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f); GL.UseProgram(shaderHandle); GL.Uniform1(attribLocationTex, 0); GL.UniformMatrix4(attribLocationProjMtx, false, ref orthoProjection); GL.BindVertexArray(vaoHandle); for (int i = 0; i < drawData->CmdListsCount; i++) { NativeDrawList *cmdList = drawData->CmdLists[i]; ushort * idxBuffer = (ushort *)0; GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandle); GL.BufferData(BufferTarget.ArrayBuffer, cmdList->VtxBuffer.Size * sizeof(DrawVert), new IntPtr(cmdList->VtxBuffer.Data), BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementsHandle); GL.BufferData(BufferTarget.ElementArrayBuffer, cmdList->IdxBuffer.Size * sizeof(ushort *), new IntPtr(cmdList->IdxBuffer.Data), BufferUsageHint.StreamDraw); for (int cmd_i = 0; cmd_i < cmdList->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &((DrawCmd *)cmdList->CmdBuffer.Data)[cmd_i]; if (pcmd->UserCallback != IntPtr.Zero) { Console.WriteLine("User callback not implemented"); throw new NotImplementedException(); } else { //GL.BindTexture(TextureTarget.Texture2D, (int)pcmd->TextureId); GL.BindTexture(TextureTarget.Texture2D, pcmd->TextureId.ToInt32()); GL.Scissor( (int)pcmd->ClipRect.X, (int)(fbHeight - 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(idxBuffer)); } idxBuffer += pcmd->ElemCount; } } GL.UseProgram(lastProgram); GL.BindTexture(TextureTarget.Texture2D, lastTexture); //Console.WriteLine(GL.GetError()); GL.ActiveTexture((TextureUnit)lastActiveTexture); //Console.WriteLine(GL.GetError()); GL.BindVertexArray(lastVertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, lastArrayBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, lastElementArrayBuffer); GL.BlendEquationSeparate((BlendEquationMode)lastBlendEquationRgb, (BlendEquationMode)lastBlendEquationAlpha); GL.BlendFuncSeparate((ArbDrawBuffersBlend)lastBlendSrcRgb, (ArbDrawBuffersBlend)lastBlendDstRgb, (ArbDrawBuffersBlend)lastBlendSrcAlpha, (ArbDrawBuffersBlend)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.Viewport(lastViewport[0], lastViewport[1], lastViewport[2], lastViewport[3]); GL.Scissor(lastScissorBox[0], lastScissorBox[1], lastScissorBox[2], lastScissorBox[3]); if (GL.GetError() != ErrorCode.NoError) { Console.WriteLine(GL.GetError()); //Debugger.Break(); } } }
public static extern void ImDrawList_ChannelsSplit(NativeDrawList *list, int channels_count);
public static extern void ImDrawList_UpdateClipRect(NativeDrawList *list);
public static extern void ImDrawList_PathBezierCurveTo(NativeDrawList *list, Vector2 p1, Vector2 p2, Vector2 p3, int num_segments);
public static extern void ImDrawList_PathRect(NativeDrawList *list, Vector2 rect_min, Vector2 rect_max, float rounding, int rounding_corners);
public static extern void ImDrawList_PathArcToFast(NativeDrawList *list, Vector2 centre, float radius, int a_min_of_12, int a_max_of_12);
public static extern void ImDrawList_PathArcTo(NativeDrawList *list, Vector2 centre, float radius, float a_min, float a_max, int num_segments);
public static extern void ImDrawList_PathStroke(NativeDrawList *list, uint col, byte closed, float thickness);
public static extern void ImDrawList_PrimWriteVtx(NativeDrawList *list, Vector2 pos, Vector2 uv, uint col);
public static extern void ImDrawList_ChannelsMerge(NativeDrawList *list);
public static extern void ImDrawList_PrimWriteIdx(NativeDrawList *list, ushort idx);
public static extern void ImDrawList_ChannelsSetCurrent(NativeDrawList *list, int channel_index);
public static extern void ImDrawList_UpdateTextureID(NativeDrawList *list);
private unsafe void RenderImDrawData(DrawData *draw_data, GraphicsDevice gd, CommandList cl) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (draw_data->CmdListsCount == 0) { return; } uint totalVBSize = (uint)(draw_data->TotalVtxCount * sizeof(DrawVert)); 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++) { NativeDrawList *cmd_list = draw_data->CmdLists[i]; cl.UpdateBuffer( _vertexBuffer, vertexOffsetInVertices * (uint)sizeof(DrawVert), (IntPtr)cmd_list->VtxBuffer.Data, (uint)(cmd_list->VtxBuffer.Size * sizeof(DrawVert))); cl.UpdateBuffer( _indexBuffer, indexOffsetInElements * (uint)sizeof(ushort), (IntPtr)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 into our constant buffer { IO 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); ImGui.ScaleClipRects(draw_data, ImGui.GetIO().DisplayFramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data->CmdListsCount; n++) { NativeDrawList *cmd_list = draw_data->CmdLists[n]; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmd_list->CmdBuffer.Data)[cmd_i]); 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)idx_offset, vtx_offset, 0); } idx_offset += (int)pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.Size; } }
public unsafe static void RenderDrawData(DrawData *drawData, int displayW, int displayH) { // We are using the OpenGL fixed pipeline to make the example code simpler to read! // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. int lastTexture; GL.GetInteger(GetPName.TextureBinding2D, out lastTexture); Int4 lastViewport = new Int4(); TypedReference tr = __makeref(lastViewport); IntPtr ptr = **(IntPtr **)(&tr); GL.GetInteger(GetPName.Viewport, (int *)ptr); Int4 lastScissorBox = new Int4(); tr = __makeref(lastScissorBox); ptr = **(IntPtr **)(&tr); GL.GetInteger(GetPName.ScissorBox, (int *)ptr); GL.PushAttrib(AttribMask.EnableBit | AttribMask.ColorBufferBit | AttribMask.TransformBit); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.TextureCoordArray); GL.EnableClientState(ArrayCap.ColorArray); GL.Enable(EnableCap.Texture2D); GL.UseProgram(0); // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) IO io = ImGui.GetIO(); ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale); // Setup orthographic projection matrix GL.Viewport(0, 0, displayW, displayH); GL.MatrixMode(MatrixMode.Projection); GL.PushMatrix(); GL.LoadIdentity(); GL.Ortho( 0.0f, io.DisplaySize.X / io.DisplayFramebufferScale.X, io.DisplaySize.Y / io.DisplayFramebufferScale.Y, 0.0f, -1.0f, 1.0f ); GL.MatrixMode(MatrixMode.Modelview); GL.PushMatrix(); GL.LoadIdentity(); // Render command lists for (int n = 0; n < drawData->CmdListsCount; n++) { DrawList cmddList = new DrawList(drawData->CmdLists[n]); NativeDrawList *cmdList = drawData->CmdLists[n]; ImVector vtxBuffer = cmdList->VtxBuffer; ImVector idxBuffer = cmdList->IdxBuffer; GL.VertexPointer(2, VertexPointerType.Float, sizeof(DrawVert), new IntPtr((long)vtxBuffer.Data + DrawVert.PosOffset)); GL.TexCoordPointer(2, TexCoordPointerType.Float, sizeof(DrawVert), new IntPtr((long)vtxBuffer.Data + DrawVert.UVOffset)); GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(DrawVert), new IntPtr((long)vtxBuffer.Data + DrawVert.ColOffset)); long idxBufferOffset = 0; for (int cmdi = 0; cmdi < cmdList->CmdBuffer.Size; cmdi++) { DrawCmd *pcmd = &(((DrawCmd *)cmdList->CmdBuffer.Data)[cmdi]); /* if (pcmd->UserCallback!= IntPtr.Zero) { * pcmd->(ref cmdList, ref pcmd); * } else {*/ GL.BindTexture(TextureTarget.Texture2D, (int)pcmd->TextureId); 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.UnsignedByte, new IntPtr((long)idxBuffer.Data + idxBufferOffset)); idxBufferOffset += pcmd->ElemCount * 2 /*sizeof(ushort)*/; } } // Restore modified state GL.DisableClientState(ArrayCap.ColorArray); GL.DisableClientState(ArrayCap.TextureCoordArray); GL.DisableClientState(ArrayCap.VertexArray); GL.BindTexture(TextureTarget.Texture2D, lastTexture); GL.MatrixMode(MatrixMode.Modelview); GL.PopMatrix(); GL.MatrixMode(MatrixMode.Projection); GL.PopMatrix(); GL.PopAttrib(); GL.Viewport(lastViewport.X, lastViewport.Y, lastViewport.Z, lastViewport.W); GL.Scissor(lastScissorBox.X, lastScissorBox.Y, lastScissorBox.Z, lastScissorBox.W); }
private unsafe void RenderImDrawData(DrawData *draw_data) { // Rendering int display_w, display_h; display_w = _nativeWindow.Width; display_h = _nativeWindow.Height; Vector4 clear_color = new Vector4(114f / 255f, 144f / 255f, 154f / 255f, 1.0f); GL.Viewport(0, 0, display_w, display_h); GL.ClearColor(clear_color.X, clear_color.Y, clear_color.Z, clear_color.W); GL.Clear(ClearBufferMask.ColorBufferBit); // We are using the OpenGL fixed pipeline to make the example code simpler to read! // 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.PushAttrib(AttribMask.EnableBit | AttribMask.ColorBufferBit | AttribMask.TransformBit); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); GL.Enable(EnableCap.ScissorTest); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.TextureCoordArray); GL.EnableClientState(ArrayCap.ColorArray); GL.Enable(EnableCap.Texture2D); GL.UseProgram(0); // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) IO io = ImGui.GetIO(); ImGui.ScaleClipRects(draw_data, io.DisplayFramebufferScale); // Setup orthographic projection matrix GL.MatrixMode(MatrixMode.Projection); GL.PushMatrix(); GL.LoadIdentity(); GL.Ortho( 0.0f, io.DisplaySize.X / io.DisplayFramebufferScale.X, io.DisplaySize.Y / io.DisplayFramebufferScale.Y, 0.0f, -1.0f, 1.0f); GL.MatrixMode(MatrixMode.Modelview); GL.PushMatrix(); GL.LoadIdentity(); // Render command lists for (int n = 0; n < draw_data->CmdListsCount; n++) { NativeDrawList *cmd_list = draw_data->CmdLists[n]; byte * vtx_buffer = (byte *)cmd_list->VtxBuffer.Data; ushort * idx_buffer = (ushort *)cmd_list->IdxBuffer.Data; DrawVert vert0 = *((DrawVert *)vtx_buffer); DrawVert vert1 = *(((DrawVert *)vtx_buffer) + 1); DrawVert vert2 = *(((DrawVert *)vtx_buffer) + 2); GL.VertexPointer(2, VertexPointerType.Float, sizeof(DrawVert), new IntPtr(vtx_buffer + DrawVert.PosOffset)); GL.TexCoordPointer(2, TexCoordPointerType.Float, sizeof(DrawVert), new IntPtr(vtx_buffer + DrawVert.UVOffset)); GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(DrawVert), new IntPtr(vtx_buffer + DrawVert.ColOffset)); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmd_list->CmdBuffer.Data)[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)); ushort[] indices = new ushort[pcmd->ElemCount]; for (int i = 0; i < indices.Length; i++) { indices[i] = idx_buffer[i]; } GL.DrawElements(PrimitiveType.Triangles, (int)pcmd->ElemCount, DrawElementsType.UnsignedShort, new IntPtr(idx_buffer)); } idx_buffer += pcmd->ElemCount; } } // Restore modified state GL.DisableClientState(ArrayCap.ColorArray); GL.DisableClientState(ArrayCap.TextureCoordArray); GL.DisableClientState(ArrayCap.VertexArray); GL.BindTexture(TextureTarget.Texture2D, last_texture); GL.MatrixMode(MatrixMode.Modelview); GL.PopMatrix(); GL.MatrixMode(MatrixMode.Projection); GL.PopMatrix(); GL.PopAttrib(); _graphicsContext.SwapBuffers(); }
public static extern void ImDrawList_AddCallback(NativeDrawList *list, ImDrawCallback callback, void *callback_data);
public static extern void ImDrawList_PathLineToMergeDuplicate(NativeDrawList *list, Vector2 pos);
public DrawList(NativeDrawList *nativeDrawList) { _nativeDrawList = nativeDrawList; }
public static extern void ImDrawList_AddDrawCmd(NativeDrawList *list);
private unsafe void RenderImDrawData(DrawData *draw_data, RenderContext rc) { VertexDescriptor descriptor = new VertexDescriptor((byte)sizeof(DrawVert), 3, IntPtr.Zero); int vertexOffsetInVertices = 0; int indexOffsetInElements = 0; if (draw_data->CmdListsCount == 0) { return; } for (int i = 0; i < draw_data->CmdListsCount; i++) { NativeDrawList *cmd_list = draw_data->CmdLists[i]; _vertexBuffer.SetVertexData(new IntPtr(cmd_list->VtxBuffer.Data), descriptor, cmd_list->VtxBuffer.Size, vertexOffsetInVertices); _indexBuffer.SetIndices(new IntPtr(cmd_list->IdxBuffer.Data), IndexFormat.UInt16, cmd_list->IdxBuffer.Size, indexOffsetInElements); vertexOffsetInVertices += cmd_list->VtxBuffer.Size; indexOffsetInElements += cmd_list->IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer { var io = ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _projMatrixBuffer.SetData(ref mvp, sizeof(Matrix4x4)); } BlendState previousBlendState = rc.BlendState; rc.SetBlendState(_blendState); rc.SetDepthStencilState(_depthDisabledState); RasterizerState previousRasterizerState = rc.RasterizerState; rc.SetRasterizerState(_rasterizerState); rc.VertexBuffer = _vertexBuffer; rc.IndexBuffer = _indexBuffer; rc.ShaderSet = _shaderSet; rc.ShaderResourceBindingSlots = _resourceBindings; rc.SetConstantBuffer(0, _projMatrixBuffer); rc.SetSamplerState(2, _rc.PointSampler); ImGui.ScaleClipRects(draw_data, ImGui.GetIO().DisplayFramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data->CmdListsCount; n++) { NativeDrawList *cmd_list = draw_data->CmdLists[n]; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmd_list->CmdBuffer.Data)[cmd_i]); if (pcmd->UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { if (pcmd->TextureId != IntPtr.Zero) { if (pcmd->TextureId == new IntPtr(_fontAtlasID)) { _rc.SetTexture(1, _fontTextureBinding); } else { ShaderTextureBinding binding = ImGuiImageHelper.GetShaderTextureBinding(pcmd->TextureId); _rc.SetTexture(1, binding); } } // TODO: This doesn't take into account viewport coordinates. rc.SetScissorRectangle( (int)pcmd->ClipRect.X, (int)pcmd->ClipRect.Y, (int)pcmd->ClipRect.Z, (int)pcmd->ClipRect.W); rc.DrawIndexedPrimitives((int)pcmd->ElemCount, idx_offset, vtx_offset); } idx_offset += (int)pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.Size; } rc.ClearScissorRectangle(); rc.SetBlendState(previousBlendState); rc.SetDepthStencilState(rc.DefaultDepthStencilState); rc.SetRasterizerState(previousRasterizerState); }
public static extern void ImDrawList_PrimReserve(NativeDrawList *list, int idx_count, int vtx_count);