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; } } }