unsafe void UpdateBuffers(ImDrawDataPtr drawData)
        {
            int drawArgCount = 0; // nr of drawArgs is the same as the nr of ImDrawCmd

            for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n)
            {
                drawArgCount += drawData.CmdListsRange[n].CmdBuffer.Size;
            }

            // create or resize vertex/index buffers
            if (_vtxBuf == null || _vtxBuf.count < drawData.TotalVtxCount)
            {
                CreateOrResizeVtxBuffer(ref _vtxBuf, drawData.TotalVtxCount);
            }
            if (_idxBuf == null || _idxBuf.count < drawData.TotalIdxCount)
            {
                CreateOrResizeIdxBuffer(ref _idxBuf, drawData.TotalIdxCount);
            }
            if (_argBuf == null || _argBuf.count < drawArgCount * 5)
            {
                CreateOrResizeArgBuffer(ref _argBuf, drawArgCount * 5);
            }

            // upload vertex/index data into buffers
            int vtxOf = 0;
            int idxOf = 0;
            int argOf = 0;

            for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n)
            {
                ImDrawListPtr            drawList = drawData.CmdListsRange[n];
                NativeArray <ImDrawVert> vtxArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ImDrawVert>(
                    (void *)drawList.VtxBuffer.Data, drawList.VtxBuffer.Size, Allocator.None);
                NativeArray <ushort> idxArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ushort>(
                    (void *)drawList.IdxBuffer.Data, drawList.IdxBuffer.Size, Allocator.None);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref vtxArray, AtomicSafetyHandle.GetTempMemoryHandle());
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref idxArray, AtomicSafetyHandle.GetTempMemoryHandle());
#endif
                // upload vertex/index data
                _vtxBuf.SetData(vtxArray, 0, vtxOf, vtxArray.Length);
                _idxBuf.SetData(idxArray, 0, idxOf, idxArray.Length);

                // arguments for indexed draw
                _drawArgs[3] = vtxOf;                                           // base vertex location
                for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i)
                {
                    ImDrawCmdPtr cmd = drawList.CmdBuffer[i];
                    _drawArgs[0] = (int)cmd.ElemCount;                          // index count per instance
                    _drawArgs[2] = idxOf + (int)cmd.IdxOffset;                  // start index location
                    _argBuf.SetData(_drawArgs, 0, argOf, 5);

                    argOf += 5;                                                 // 5 int for each cmd
                }
                vtxOf += vtxArray.Length;
                idxOf += idxArray.Length;
            }
        }
        private unsafe void UpdateMesh(ImDrawDataPtr drawData, Vector2 fbSize)
        {
            int subMeshCount = 0;             // nr of submeshes is the same as the nr of ImDrawCmd

            for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n)
            {
                subMeshCount += drawData.CmdListsRange[n].CmdBuffer.Size;
            }

            // set mesh structure
            if (_prevSubMeshCount != subMeshCount)
            {
                _mesh.Clear(true);                 // occasionally crashes when changing subMeshCount without clearing first
                _mesh.subMeshCount = _prevSubMeshCount = subMeshCount;
            }
            _mesh.SetVertexBufferParams(drawData.TotalVtxCount, s_attributes);
            _mesh.SetIndexBufferParams(drawData.TotalIdxCount, IndexFormat.UInt16);

            // upload data into mesh
            int vtxOf = 0;
            int idxOf = 0;
            List <SubMeshDescriptor> descriptors = new List <SubMeshDescriptor>();

            for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n)
            {
                ImDrawListPtr            drawList = drawData.CmdListsRange[n];
                NativeArray <ImDrawVert> vtxArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ImDrawVert>(
                    (void *)drawList.VtxBuffer.Data, drawList.VtxBuffer.Size, Allocator.None);
                NativeArray <ushort> idxArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ushort>(
                    (void *)drawList.IdxBuffer.Data, drawList.IdxBuffer.Size, Allocator.None);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref vtxArray, AtomicSafetyHandle.GetTempMemoryHandle());
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref idxArray, AtomicSafetyHandle.GetTempMemoryHandle());
#endif
                // upload vertex/index data
                _mesh.SetVertexBufferData(vtxArray, 0, vtxOf, vtxArray.Length, 0, NoMeshChecks);
                _mesh.SetIndexBufferData(idxArray, 0, idxOf, idxArray.Length, NoMeshChecks);

                // define subMeshes
                for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i)
                {
                    ImDrawCmdPtr      cmd        = drawList.CmdBuffer[i];
                    SubMeshDescriptor descriptor = new SubMeshDescriptor
                    {
                        topology   = MeshTopology.Triangles,
                        indexStart = idxOf + (int)cmd.IdxOffset,
                        indexCount = (int)cmd.ElemCount,
                        baseVertex = vtxOf + (int)cmd.VtxOffset,
                    };
                    descriptors.Add(descriptor);
                }

                vtxOf += vtxArray.Length;
                idxOf += idxArray.Length;
            }
            _mesh.SetSubMeshes(descriptors, NoMeshChecks);
            _mesh.UploadMeshData(false);
        }
Beispiel #3
0
 private Rectangle GenerateScissorRect(ImDrawCmdPtr draw_command)
 {
     return(new Rectangle(
                (int)draw_command.ClipRect.X,
                (int)draw_command.ClipRect.Y,
                (int)(draw_command.ClipRect.Z - draw_command.ClipRect.X),
                (int)(draw_command.ClipRect.W - draw_command.ClipRect.Y)));
 }
Beispiel #4
0
        private unsafe void RenderCommandLists(ImDrawDataPtr drawData)
        {
            _graphicsDevice.SetVertexBuffer(_vertexBuffer);
            _graphicsDevice.Indices = _indexBuffer;

            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 drawCmd = cmdList.CmdBuffer[cmdi];

                    if (drawCmd.ElemCount == 0)
                    {
                        continue;
                    }

                    if (!_loadedTextures.ContainsKey(drawCmd.TextureId))
                    {
                        throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings");
                    }

                    _graphicsDevice.ScissorRectangle = new Rectangle(
                        (int)drawCmd.ClipRect.X,
                        (int)drawCmd.ClipRect.Y,
                        (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X),
                        (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y)
                        );

                    var effect = UpdateEffect(_loadedTextures[drawCmd.TextureId]);

                    foreach (var pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

#pragma warning disable CS0618 // // FNA does not expose an alternative method.
                        _graphicsDevice.DrawIndexedPrimitives(
                            primitiveType: PrimitiveType.TriangleList,
                            baseVertex: (int)drawCmd.VtxOffset + vtxOffset,
                            minVertexIndex: 0,
                            numVertices: cmdList.VtxBuffer.Size,
                            startIndex: (int)drawCmd.IdxOffset + idxOffset,
                            primitiveCount: (int)drawCmd.ElemCount / 3
                            );
#pragma warning restore CS0618
                    }
                }

                vtxOffset += cmdList.VtxBuffer.Size;
                idxOffset += cmdList.IdxBuffer.Size;
            }
        }
Beispiel #5
0
        void RenderDrawLists(ImDrawDataPtr drawData)
        {
            // view proj
            var surfaceSize = input.Mouse.SurfaceSize;
            var projMatrix  = Matrix.OrthoRH(surfaceSize.X, -surfaceSize.Y, -1, 1);

            CheckBuffers(drawData);  // potentially resize buffers first if needed
            UpdateBuffers(drawData); // updeet em now

            // set pipeline stuff
            var is32Bits = false;

            commandList.SetPipelineState(imPipeline);
            commandList.SetVertexBuffer(0, vertexBinding.Buffer, 0, Unsafe.SizeOf <ImDrawVert>());
            commandList.SetIndexBuffer(indexBinding.Buffer, 0, is32Bits);
            imShader.Parameters.Set(ImGuiShaderKeys.tex, fontTexture);

            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 cmd = cmdList.CmdBuffer[i];

                    if (cmd.TextureId != IntPtr.Zero)
                    {
                        // imShader.Parameters.Set(ImGuiShaderKeys.tex, fontTexture);
                    }
                    else
                    {
                        commandList.SetScissorRectangle(
                            new Rectangle(
                                (int)cmd.ClipRect.X,
                                (int)cmd.ClipRect.Y,
                                (int)(cmd.ClipRect.Z - cmd.ClipRect.X),
                                (int)(cmd.ClipRect.W - cmd.ClipRect.Y)
                                )
                            );

                        imShader.Parameters.Set(ImGuiShaderKeys.tex, fontTexture);
                        imShader.Parameters.Set(ImGuiShaderKeys.proj, ref projMatrix);
                        imShader.Apply(context);

                        commandList.DrawIndexed((int)cmd.ElemCount, idxOffset, vtxOffset);
                    }

                    idxOffset += (int)cmd.ElemCount;
                }

                vtxOffset += cmdList.VtxBuffer.Size;
            }
        }
Beispiel #6
0
        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();
        }
        public void Draw()
        {
            unsafe
            {
                ImDrawDataPtr drawData = ImGui.GetDrawData();
                Graphics.SetColor(Color.White);
                for (int n = 0; n < drawData.CmdListsCount; n++)
                {
                    ImDrawListPtr cmdList     = drawData.CmdListsRange[n];
                    var           _vertexData = new byte[cmdList.VtxBuffer.Size * _Vert_Size_];
                    var           _indexData  = new ushort[cmdList.IdxBuffer.Size];
                    fixed(void *vtxDstPtr = _vertexData)
                    fixed(void *idxDstPtr = _indexData)
                    {
                        Buffer.MemoryCopy((void *)cmdList.VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList.VtxBuffer.Size * _Vert_Size_);
                        Buffer.MemoryCopy((void *)cmdList.IdxBuffer.Data, idxDstPtr, _indexData.Length * sizeof(ushort), cmdList.IdxBuffer.Size * sizeof(ushort));
                    }

                    var mesh = Graphics.NewMesh(PositionColorVertex.VertexInfo, _vertexData,
                                                MeshDrawMode.Trangles, SpriteBatchUsage.Dynamic);
                    mesh.SetVertexMap(Trans(_indexData));

                    for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                    {
                        ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi];

                        if (!_loadedTextures.TryGetValue(drawCmd.TextureId, out var img))
                        {
                            throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings");
                        }

                        Graphics.SetScissor(
                            (int)drawCmd.ClipRect.X,
                            (int)drawCmd.ClipRect.Y,
                            (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X),
                            (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y)
                            );

                        mesh.SetTexture(img);
                        mesh.SetDrawRange((int)drawCmd.IdxOffset, (int)drawCmd.ElemCount);
                        Graphics.Draw(mesh);
                    }
                    mesh.Dispose();
                    mesh = null;
                }
            }

            Graphics.SetScissor();
        }
        private void RenderCommandLists(ImDrawDataPtr drawData)
        {
            // TODO Pass in the game window to get the screen width and height
            var m_Ortho = Monorail.Mathlib.Matrix4.CreateOrthographicOffCenter(0, 1280, 800, 0, -1, 1);

            m_GraphicsDevice.BindVertexArrayObject(m_VertexArrayObject.VaoId);

            var drawcount = 0;
            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 drawCmd = cmdList.CmdBuffer[cmdi];
                    var          texId   = drawCmd.TextureId;


                    OpenGL.GlBindings.Enable(OpenGL.Enable.GL_SCISSOR_TEST);
                    OpenGL.GlBindings.glScissor((int)drawCmd.ClipRect.X, (int)drawCmd.ClipRect.Y, (uint)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X), (uint)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y));



                    // TODO If textureId not loaded?
                    //    m_GraphicsDevice.ScissorRect();
                    m_GraphicsDevice.BindShaderProgram(m_ShaderProgram.ShaderProgramId);

                    m_GraphicsDevice.BindVertexArrayObject(m_VertexArrayObject.VaoId);
                    m_GraphicsDevice.BindTexture(m_Texture.TextureId, OpenGL.TextureType.GL_TEXTURE_2D);


                    m_ShaderProgram.SetUniform("projection_matrix", m_Ortho);
                    m_ShaderProgram.SetUniform("FontTexture", 0);


                    m_GraphicsDevice.DrawElements(PrimitiveType.TriangleList, (int)drawCmd.ElemCount, DrawElementsType.UnsignedInt, idxOffset);


                    drawcount++;

                    idxOffset += (int)drawCmd.ElemCount;
                }
                vtxOffset += cmdList.VtxBuffer.Size;
            }

            OpenGL.GlBindings.Disable(OpenGL.Enable.GL_SCISSOR_TEST);
        }
Beispiel #9
0
        private unsafe void RenderCommandLists(ImDrawDataPtr ptr)
        {
            GraphicsDevice.SetVertexBuffer(VertexBuffer);
            GraphicsDevice.Indices = IndexBuffer;

            int vtxOffset = 0;
            int idxOffset = 0;

            for (int i = 0; i < ptr.CmdListsCount; i++)
            {
                ImDrawListPtr cmdList = ptr.CmdListsRange[i];

                for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                {
                    ImDrawCmdPtr cmd = cmdList.CmdBuffer[cmdi];
                    if (!Textures.ContainsKey(cmd.TextureId))
                    {
                        throw new InvalidOperationException($"Could not find ImGUI texture with ID {cmd.TextureId}");
                    }

                    GraphicsDevice.ScissorRectangle = new Rectangle(
                        (int)cmd.ClipRect.X,
                        (int)cmd.ClipRect.Y,
                        (int)(cmd.ClipRect.Z - cmd.ClipRect.X),
                        (int)(cmd.ClipRect.W - cmd.ClipRect.Y)
                        );

                    Effect e = UpdateEffect(Textures[cmd.TextureId]);
                    for (int passIndex = 0; passIndex < e.CurrentTechnique.Passes.Count; passIndex++)
                    {
                        EffectPass pass = e.CurrentTechnique.Passes[passIndex];
                        pass.Apply();
                        GraphicsDevice.DrawIndexedPrimitives(
                            primitiveType: PrimitiveType.TriangleList,
                            baseVertex: vtxOffset,
                            minVertexIndex: 0,
                            numVertices: cmdList.VtxBuffer.Size,
                            startIndex: idxOffset,
                            primitiveCount: (int)cmd.ElemCount / 3
                            );
                    }

                    idxOffset += (int)cmd.ElemCount;
                }

                vtxOffset += cmdList.VtxBuffer.Size;
            }
        }
Beispiel #10
0
        private unsafe void RenderCommandLists(ImDrawDataPtr drawData)
        {
            _graphicsDevice.SetVertexBuffer(_vertexBuffer);
            _graphicsDevice.Indices = _indexBuffer;

            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 drawCmd = cmdList.CmdBuffer[cmdi];

                    if (!_loadedTextures.ContainsKey(drawCmd.TextureId))
                    {
                        throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings");
                    }

                    _graphicsDevice.ScissorRectangle = new Rectangle(
                        (int)drawCmd.ClipRect.X,
                        (int)drawCmd.ClipRect.Y,
                        (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X),
                        (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y)
                        );

                    var effect = UpdateEffect(_loadedTextures[drawCmd.TextureId]);

                    foreach (var pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        _graphicsDevice.DrawIndexedPrimitives(
                            PrimitiveType.TriangleList,
                            vtxOffset,
                            idxOffset,
                            (int)drawCmd.ElemCount / 3);
                    }

                    idxOffset += (int)drawCmd.ElemCount;
                }

                vtxOffset += cmdList.VtxBuffer.Size;
            }
        }
        void CreateDrawCommands(CommandBuffer cmd, ImDrawDataPtr drawData, Vector2 fbSize)
        {
            var prevTextureId = System.IntPtr.Zero;
            var clipOffst     = new Vector4(drawData.DisplayPos.x, drawData.DisplayPos.y, drawData.DisplayPos.x, drawData.DisplayPos.y);
            var clipScale     = new Vector4(drawData.FramebufferScale.x, drawData.FramebufferScale.y, drawData.FramebufferScale.x, drawData.FramebufferScale.y);

            _material.SetBuffer(_verticesID, _vtxBuf);                          // bind vertex buffer

            cmd.SetViewport(new Rect(0f, 0f, fbSize.x, fbSize.y));
            cmd.SetViewProjectionMatrices(
                Matrix4x4.Translate(new Vector3(0.5f / fbSize.x, 0.5f / fbSize.y, 0f)), // small adjustment to improve text
                Matrix4x4.Ortho(0f, fbSize.x, fbSize.y, 0f, 0f, 1f));

            int vtxOf = 0;
            int argOf = 0;

            for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n)
            {
                ImDrawListPtr drawList = drawData.CmdListsRange[n];
                for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i, argOf += 5 * 4)
                {
                    ImDrawCmdPtr drawCmd = drawList.CmdBuffer[i];
                    // TODO: user callback in drawCmd.UserCallback & drawCmd.UserCallbackData

                    // project scissor rectangle into framebuffer space and skip if fully outside
                    var clip = Vector4.Scale(drawCmd.ClipRect - clipOffst, clipScale);
                    if (clip.x >= fbSize.x || clip.y >= fbSize.y || clip.z < 0f || clip.w < 0f)
                    {
                        continue;
                    }

                    if (prevTextureId != drawCmd.TextureId)
                    {
                        _properties.SetTexture(_texID, _texManager.GetTexture((int)(prevTextureId = drawCmd.TextureId)));
                    }

                    _properties.SetInt(_baseVertexID, vtxOf + (int)drawCmd.VtxOffset);                            // base vertex location not automatically added to SV_VertexID
                    cmd.EnableScissorRect(new Rect(clip.x, fbSize.y - clip.w, clip.z - clip.x, clip.w - clip.y)); // invert y
                    cmd.DrawProceduralIndirect(_idxBuf, Matrix4x4.identity, _material, -1, MeshTopology.Triangles, _argBuf, argOf, _properties);
                }
                vtxOf += drawList.VtxBuffer.Size;
            }
            cmd.DisableScissorRect();
        }
Beispiel #12
0
            private void RenderIMGui(Renderer renderer)
            {
                ImGui.Render();
                ImDrawDataPtr drawData = ImGui.GetDrawData();

                for (int i = 0; i < drawData.CmdListsCount; i++)
                {
                    ImDrawListPtr cmdList = drawData.CmdListsRange[i];

                    IVertexBuffer vertexBuffer = CreateVertexBuffer(cmdList);

                    int IndexOffset = 0;


                    for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                    {
                        ImDrawCmdPtr DrawCommand = cmdList.CmdBuffer[cmdi];

                        using (RenderingCommand cmd = renderer.RendererResourceFactory.CreateRenderCommand())
                        {
                            cmd.WithVertexBuffer(vertexBuffer)
                            .WithMaterial(Renderer.DefaultMaterialPtr.Get <Watertight.Rendering.Materials.Material>())
                            .WithCamera(UICamera);

                            if (_ImGUITextureMap.ContainsKey(DrawCommand.TextureId))
                            {
                                cmd.WithTexture(_ImGUITextureMap[DrawCommand.TextureId]);
                            }

                            cmd.WithStartIndex(IndexOffset)
                            .WithPrimitveCount((int)DrawCommand.ElemCount / 3)
                            .WithDebugName("IMGUI Renderer");

                            renderer.ExecuteRenderCommand(cmd);
                        }

                        IndexOffset += (int)DrawCommand.ElemCount;
                    }
                }
            }
        private void CreateDrawCommands(CommandBuffer cmd, ImDrawDataPtr drawData, Vector2 fbSize)
        {
            System.IntPtr prevTextureId = System.IntPtr.Zero;
            Vector4       clipOffst     = new Vector4(drawData.DisplayPos.X, drawData.DisplayPos.Y, drawData.DisplayPos.X, drawData.DisplayPos.Y);
            Vector4       clipScale     = new Vector4(drawData.FramebufferScale.X, drawData.FramebufferScale.Y, drawData.FramebufferScale.X, drawData.FramebufferScale.Y);

            cmd.SetViewport(new Rect(0f, 0f, fbSize.x, fbSize.y));
            cmd.SetViewProjectionMatrices(
                Matrix4x4.Translate(new Vector3(0.5f / fbSize.x, 0.5f / fbSize.y, 0f)),                 // small adjustment to improve text
                Matrix4x4.Ortho(0f, fbSize.x, fbSize.y, 0f, 0f, 1f));

            int subOf = 0;

            for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n)
            {
                ImDrawListPtr drawList = drawData.CmdListsRange[n];
                for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i, ++subOf)
                {
                    ImDrawCmdPtr drawCmd = drawList.CmdBuffer[i];
                    // TODO: user callback in drawCmd.UserCallback & drawCmd.UserCallbackData

                    // project scissor rectangle into framebuffer space and skip if fully outside
                    Vector4 clip = Vector4.Scale(Helper.V4f(drawCmd.ClipRect) - clipOffst, clipScale);
                    if (clip.x >= fbSize.x || clip.y >= fbSize.y || clip.z < 0f || clip.w < 0f)
                    {
                        continue;
                    }

                    if (prevTextureId != drawCmd.TextureId)
                    {
                        _properties.SetTexture(_texID, _texManager.GetTexture((int)(prevTextureId = drawCmd.TextureId)));
                    }

                    cmd.EnableScissorRect(new Rect(clip.x, fbSize.y - clip.w, clip.z - clip.x, clip.w - clip.y));                     // invert y
                    cmd.DrawMesh(_mesh, Matrix4x4.identity, _material, subOf, -1, _properties);
                }
            }
            cmd.DisableScissorRect();
        }
Beispiel #14
0
        private void RenderCommandLists(ImDrawDataPtr drawData)
        {
            this.GraphicsDevice.SetVertexBuffer(this.vertexBuffer);
            this.GraphicsDevice.Indices = this.indexBuffer;

            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 drawCmd = cmdList.CmdBuffer[cmdi];

                    if (!this.LoadedTextures.ContainsKey(drawCmd.TextureId))
                    {
                        throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings");
                    }

                    this.GraphicsDevice.ScissorRectangle = new Rectangle(
                        (int)drawCmd.ClipRect.X,
                        (int)drawCmd.ClipRect.Y,
                        (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X),
                        (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y)
                        );

                    this.UpdateEffect(drawCmd.TextureId);
                    this.Effect.Apply();
                    this.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, vtxOffset, idxOffset, (int)drawCmd.ElemCount / 3);

                    idxOffset += (int)drawCmd.ElemCount;
                }

                vtxOffset += cmdList.VtxBuffer.Size;
            }
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        private unsafe void RenderImDrawData(ImDrawDataPtr drawDataPtr)
        {
            int framebufferWidth  = (int)(drawDataPtr.DisplaySize.X * drawDataPtr.FramebufferScale.X);
            int framebufferHeight = (int)(drawDataPtr.DisplaySize.Y * drawDataPtr.FramebufferScale.Y);

            if (framebufferWidth <= 0 || framebufferHeight <= 0)
            {
                return;
            }

            // Backup GL state
            _gl.GetInteger(GLEnum.ActiveTexture, out int lastActiveTexture);
            _gl.ActiveTexture(GLEnum.Texture0);

            _gl.GetInteger(GLEnum.CurrentProgram, out int lastProgram);
            _gl.GetInteger(GLEnum.TextureBinding2D, out int lastTexture);

            _gl.GetInteger(GLEnum.SamplerBinding, out int lastSampler);

            _gl.GetInteger(GLEnum.ArrayBufferBinding, out int lastArrayBuffer);
            _gl.GetInteger(GLEnum.VertexArrayBinding, out int lastVertexArrayObject);

            #if !GLES
            Span <int> lastPolygonMode = stackalloc int[2];
            _gl.GetInteger(GLEnum.PolygonMode, lastPolygonMode);
            #endif

            Span <int> lastScissorBox = stackalloc int[4];
            _gl.GetInteger(GLEnum.ScissorBox, lastScissorBox);

            _gl.GetInteger(GLEnum.BlendSrcRgb, out int lastBlendSrcRgb);
            _gl.GetInteger(GLEnum.BlendDstRgb, out int lastBlendDstRgb);

            _gl.GetInteger(GLEnum.BlendSrcAlpha, out int lastBlendSrcAlpha);
            _gl.GetInteger(GLEnum.BlendDstAlpha, out int lastBlendDstAlpha);

            _gl.GetInteger(GLEnum.BlendEquationRgb, out int lastBlendEquationRgb);
            _gl.GetInteger(GLEnum.BlendEquationAlpha, out int lastBlendEquationAlpha);

            bool lastEnableBlend       = _gl.IsEnabled(GLEnum.Blend);
            bool lastEnableCullFace    = _gl.IsEnabled(GLEnum.CullFace);
            bool lastEnableDepthTest   = _gl.IsEnabled(GLEnum.DepthTest);
            bool lastEnableStencilTest = _gl.IsEnabled(GLEnum.StencilTest);
            bool lastEnableScissorTest = _gl.IsEnabled(GLEnum.ScissorTest);

            #if !GLES
            bool lastEnablePrimitiveRestart = _gl.IsEnabled(GLEnum.PrimitiveRestart);
            #endif

            SetupRenderState(drawDataPtr, framebufferWidth, framebufferHeight);

            // Will project scissor/clipping rectangles into framebuffer space
            Vector2 clipOff   = drawDataPtr.DisplayPos;       // (0,0) unless using multi-viewports
            Vector2 clipScale = drawDataPtr.FramebufferScale; // (1,1) unless using retina display which are often (2,2)

            // Render command lists
            for (int n = 0; n < drawDataPtr.CmdListsCount; n++)
            {
                ImDrawListPtr cmdListPtr = drawDataPtr.CmdListsRange[n];

                // Upload vertex/index buffers

                _gl.BufferData(GLEnum.ArrayBuffer, (nuint)(cmdListPtr.VtxBuffer.Size * sizeof(ImDrawVert)), (void *)cmdListPtr.VtxBuffer.Data, GLEnum.StreamDraw);
                _gl.CheckGlError($"Data Vert {n}");
                _gl.BufferData(GLEnum.ElementArrayBuffer, (nuint)(cmdListPtr.IdxBuffer.Size * sizeof(ushort)), (void *)cmdListPtr.IdxBuffer.Data, GLEnum.StreamDraw);
                _gl.CheckGlError($"Data Idx {n}");

                for (int cmd_i = 0; cmd_i < cmdListPtr.CmdBuffer.Size; cmd_i++)
                {
                    ImDrawCmdPtr cmdPtr = cmdListPtr.CmdBuffer[cmd_i];

                    if (cmdPtr.UserCallback != IntPtr.Zero)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        Vector4 clipRect;
                        clipRect.X = (cmdPtr.ClipRect.X - clipOff.X) * clipScale.X;
                        clipRect.Y = (cmdPtr.ClipRect.Y - clipOff.Y) * clipScale.Y;
                        clipRect.Z = (cmdPtr.ClipRect.Z - clipOff.X) * clipScale.X;
                        clipRect.W = (cmdPtr.ClipRect.W - clipOff.Y) * clipScale.Y;

                        if (clipRect.X < framebufferWidth && clipRect.Y < framebufferHeight && clipRect.Z >= 0.0f && clipRect.W >= 0.0f)
                        {
                            // Apply scissor/clipping rectangle
                            _gl.Scissor((int)clipRect.X, (int)(framebufferHeight - clipRect.W), (uint)(clipRect.Z - clipRect.X), (uint)(clipRect.W - clipRect.Y));
                            _gl.CheckGlError("Scissor");

                            // Bind texture, Draw
                            _gl.BindTexture(GLEnum.Texture2D, (uint)cmdPtr.TextureId);
                            _gl.CheckGlError("Texture");

                            _gl.DrawElementsBaseVertex(GLEnum.Triangles, cmdPtr.ElemCount, GLEnum.UnsignedShort, (void *)(cmdPtr.IdxOffset * sizeof(ushort)), (int)cmdPtr.VtxOffset);
                            _gl.CheckGlError("Draw");
                        }
                    }
                }
            }

            // Destroy the temporary VAO
            _gl.DeleteVertexArray(_vertexArrayObject);
            _vertexArrayObject = 0;

            // Restore modified GL state
            _gl.UseProgram((uint)lastProgram);
            _gl.BindTexture(GLEnum.Texture2D, (uint)lastTexture);

            _gl.BindSampler(0, (uint)lastSampler);

            _gl.ActiveTexture((GLEnum)lastActiveTexture);

            _gl.BindVertexArray((uint)lastVertexArrayObject);

            _gl.BindBuffer(GLEnum.ArrayBuffer, (uint)lastArrayBuffer);
            _gl.BlendEquationSeparate((GLEnum)lastBlendEquationRgb, (GLEnum)lastBlendEquationAlpha);
            _gl.BlendFuncSeparate((GLEnum)lastBlendSrcRgb, (GLEnum)lastBlendDstRgb, (GLEnum)lastBlendSrcAlpha, (GLEnum)lastBlendDstAlpha);

            if (lastEnableBlend)
            {
                _gl.Enable(GLEnum.Blend);
            }
            else
            {
                _gl.Disable(GLEnum.Blend);
            }

            if (lastEnableCullFace)
            {
                _gl.Enable(GLEnum.CullFace);
            }
            else
            {
                _gl.Disable(GLEnum.CullFace);
            }

            if (lastEnableDepthTest)
            {
                _gl.Enable(GLEnum.DepthTest);
            }
            else
            {
                _gl.Disable(GLEnum.DepthTest);
            }
            if (lastEnableStencilTest)
            {
                _gl.Enable(GLEnum.StencilTest);
            }
            else
            {
                _gl.Disable(GLEnum.StencilTest);
            }

            if (lastEnableScissorTest)
            {
                _gl.Enable(GLEnum.ScissorTest);
            }
            else
            {
                _gl.Disable(GLEnum.ScissorTest);
            }

            #if !GLES
            if (lastEnablePrimitiveRestart)
            {
                _gl.Enable(GLEnum.PrimitiveRestart);
            }
            else
            {
                _gl.Disable(GLEnum.PrimitiveRestart);
            }

            _gl.PolygonMode(GLEnum.FrontAndBack, (GLEnum)lastPolygonMode[0]);
            #endif

            _gl.Scissor(lastScissorBox[0], lastScissorBox[1], (uint)lastScissorBox[2], (uint)lastScissorBox[3]);
        }
Beispiel #17
0
        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;
            }
        }
        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);
        }
Beispiel #19
0
 private void DrawPrimitives(int vertexOffset, int indexOffset, ImDrawListPtr commandList, ImDrawCmdPtr drawCommand)
 {
     GraphicsDevice.DrawIndexedPrimitives(
         PrimitiveType.TriangleList,
         vertexOffset,
         0,
         commandList.VtxBuffer.Size,
         indexOffset,
         (int)(drawCommand.ElemCount / 3));
 }
Beispiel #20
0
        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);
        }
Beispiel #21
0
        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 void EndRender()
        {
            ImGui.Render();

            unsafe
            {
                ImDrawDataPtr drawData = ImGui.GetDrawData();
                if (drawData.CmdListsCount <= 0)
                {
                    return;
                }

                UserDefinedAnnotation annotation = m_d3DeviceContext.QueryInterface <UserDefinedAnnotation>();
                annotation.BeginEvent("ImguiPass");

                // Grow buffers in case they are to small
                if (m_vertexBufferSize < drawData.TotalVtxCount || m_indexBufferSize < drawData.TotalIdxCount)
                {
                    m_indexBufferSize  = (int)(drawData.TotalIdxCount * 1.5f);
                    m_vertexBufferSize = (int)(drawData.TotalVtxCount * 1.5f);

                    CreateVertexIndexBuffer();
                }

                m_d3DeviceContext.MapSubresource(m_vertexBuffer, MapMode.WriteDiscard, MapFlags.None, out DataStream vertexStream);
                m_d3DeviceContext.MapSubresource(m_indexBuffer, MapMode.WriteDiscard, MapFlags.None, out DataStream indexStream);
                for (int i = 0; i < drawData.CmdListsCount; i++)
                {
                    ImDrawListPtr drawList  = drawData.CmdListsRange[i];
                    IntPtr        vertexPtr = drawList.VtxBuffer.Data;
                    vertexStream.Write(vertexPtr, 0, drawList.VtxBuffer.Size * Utilities.SizeOf <ImDrawVert>());

                    IntPtr indexPtr = drawList.IdxBuffer.Data;
                    indexStream.Write(indexPtr, 0, drawList.IdxBuffer.Size * Utilities.SizeOf <ushort>());
                }
                m_d3DeviceContext.UnmapSubresource(m_vertexBuffer, 0);
                m_d3DeviceContext.UnmapSubresource(m_indexBuffer, 0);

                float offset = 0.0f;

                Matrix mvpMatrix = Matrix.OrthoOffCenterLH(offset, m_imguiIO.DisplaySize.X + offset, m_imguiIO.DisplaySize.Y + offset, offset, -1.0f, 1.0f);
                mvpMatrix.Transpose();

                SShaderParameter parameter;
                parameter.parameterType = EShaderParameterType.Matrix;
                parameter.parameterData = mvpMatrix;
                m_shaderParameters[new SHashedName("mvpMatrix")] = parameter;

                SShaderParameter fontTextureParams;
                fontTextureParams.parameterType = EShaderParameterType.Texture;
                fontTextureParams.parameterData = m_boundTextures[m_fontAtlasId];
                m_shaderParameters[new SHashedName("texture")] = fontTextureParams;

                m_shader.SetShaderParameters(m_d3DeviceContext, m_shaderParameters);
                m_shader.SetActive(m_d3DeviceContext);

                m_d3DeviceContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(m_vertexBuffer, Utilities.SizeOf <ImDrawVert>(), 0));
                m_d3DeviceContext.InputAssembler.SetIndexBuffer(m_indexBuffer, Format.R16_UInt, 0);
                m_d3DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                RawViewportF[]    prevViewports       = m_d3DeviceContext.Rasterizer.GetViewports <RawViewportF>();
                RasterizerState   prevRasterizerState = m_d3DeviceContext.Rasterizer.State;
                DepthStencilState prevDepthState      = m_d3DeviceContext.OutputMerger.DepthStencilState;
                BlendState        prevBlendState      = m_d3DeviceContext.OutputMerger.BlendState;
                Rectangle[]       prevScissorRects    = new Rectangle[8];
                m_d3DeviceContext.Rasterizer.GetScissorRectangles(prevScissorRects);


                Viewport viewport = new Viewport(0, 0, m_screenWidth, m_screenHeight, 0.0f, 1.0f);
                m_d3DeviceContext.Rasterizer.SetViewport(viewport);
                m_d3DeviceContext.OutputMerger.DepthStencilState = m_depthStencilState;
                m_d3DeviceContext.OutputMerger.BlendState        = m_blendState;
                m_d3DeviceContext.Rasterizer.State = m_rasterizerState;

                int vertexOffset = 0;
                int indexOffset  = 0;

                for (int i = 0; i < drawData.CmdListsCount; i++)
                {
                    ImDrawListPtr drawList = drawData.CmdListsRange[i];
                    for (int n = 0; n < drawList.CmdBuffer.Size; n++)
                    {
                        ImDrawCmdPtr command = drawList.CmdBuffer[n];
                        if (!m_boundTextures.ContainsKey(command.TextureId))
                        {
                            throw new InvalidOperationException("Requested texture was not bound to imgui, please check your binding");
                        }

                        CTextureSampler textureSampler = m_boundTextures[command.TextureId];

                        m_d3DeviceContext.Rasterizer.SetScissorRectangle((int)command.ClipRect.X, (int)command.ClipRect.Y, (int)command.ClipRect.Z, (int)command.ClipRect.W);
                        m_d3DeviceContext.PixelShader.SetSampler(0, textureSampler.SamplerState);
                        m_d3DeviceContext.PixelShader.SetShaderResource(0, textureSampler.Texture.GetTexture());

                        m_d3DeviceContext.DrawIndexed((int)command.ElemCount, indexOffset, vertexOffset);
                        indexOffset += (int)command.ElemCount;
                    }

                    vertexOffset += drawList.VtxBuffer.Size;
                }

                m_d3DeviceContext.Rasterizer.SetScissorRectangles(prevScissorRects);
                m_d3DeviceContext.OutputMerger.BlendState        = prevBlendState;
                m_d3DeviceContext.OutputMerger.DepthStencilState = prevDepthState;
                m_d3DeviceContext.Rasterizer.State = prevRasterizerState;
                m_d3DeviceContext.Rasterizer.SetViewports(prevViewports);

                prevRasterizerState?.Dispose();
                prevBlendState?.Dispose();
                prevDepthState?.Dispose();

                annotation.EndEvent();
                annotation.Dispose();
            }
        }
Beispiel #23
0
        public void RenderCommandLists(RenderContext renderContext, ImDrawDataPtr drawData)
        {
            if (drawData.TotalVtxCount == 0)
            {
                return;
            }

            renderContext.BindVertexBuffer(_vertexBuffer);
            renderContext.BindIndexBuffer(_indexBuffer);
            renderContext.BindShaderProgram(_shaderProgram);

            int vtxOffset = 0;
            int idxOffset = 0;

            _vertexBuffer.VertexTypeInfo.Apply(_shaderProgram);

            int drawCalls      = 0;
            int primitiveCount = 0;

            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                ImDrawListPtr cmdList = drawData.CmdListsRange[n];

                for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                {
                    ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi];

                    if (!_imGuiSystem.BoundTextures.ContainsKey(drawCmd.TextureId))
                    {
                        throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings");
                    }

                    if (_window == ManaWindow.MainWindow)
                    {
                        renderContext.ScissorRectangle = new Rectangle((int)drawCmd.ClipRect.X,
                                                                       (int)(_window.Height - drawCmd.ClipRect.W),
                                                                       (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X),
                                                                       (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y));
                    }
                    else
                    {
                        var offset = _window.Location - ((Size)ManaWindow.MainWindow.Location + new Size(8, 31));
                        renderContext.ScissorRectangle = new Rectangle((int)drawCmd.ClipRect.X - offset.X,
                                                                       (int)(_window.Height - drawCmd.ClipRect.W) + offset.Y,
                                                                       (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X),
                                                                       (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y));
                    }

                    UpdateShader(renderContext, _imGuiSystem.BoundTextures[drawCmd.TextureId]);

                    int baseVertex     = vtxOffset;
                    int minVertexIndex = 0;
                    int numVertices    = cmdList.VtxBuffer.Size;
                    int numIndices     = cmdList.IdxBuffer.Size;
                    int startIndex     = idxOffset;

                    GL.DrawRangeElementsBaseVertex(PrimitiveType.Triangles,
                                                   minVertexIndex,
                                                   minVertexIndex + numVertices - 1,
                                                   (int)drawCmd.ElemCount,
                                                   DrawElementsType.UnsignedShort,
                                                   (IntPtr)(startIndex * sizeof(ushort)),
                                                   baseVertex);

                    unchecked
                    {
                        drawCalls++;
                        primitiveCount += numIndices;
                    }

                    idxOffset += (int)drawCmd.ElemCount;
                }

                vtxOffset += cmdList.VtxBuffer.Size;
            }
        }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        public static void RenderDrawData(ImDrawDataPtr 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.GetIntegerv(GL.Enum.GL_TEXTURE_BINDING_2D, out lastTexture);
            Int4 lastViewport; GL.GetIntegerv4(GL.Enum.GL_VIEWPORT, out lastViewport);
            Int4 lastScissorBox; GL.GetIntegerv4(GL.Enum.GL_SCISSOR_BOX, out lastScissorBox);

            GL.PushAttrib(GL.Enum.GL_ENABLE_BIT | GL.Enum.GL_COLOR_BUFFER_BIT | GL.Enum.GL_TRANSFORM_BIT);
            GL.Enable(GL.Enum.GL_BLEND);
            GL.BlendFunc(GL.Enum.GL_SRC_ALPHA, GL.Enum.GL_ONE_MINUS_SRC_ALPHA);
            GL.Disable(GL.Enum.GL_CULL_FACE);
            GL.Disable(GL.Enum.GL_DEPTH_TEST);
            GL.Enable(GL.Enum.GL_SCISSOR_TEST);
            GL.EnableClientState(GL.Enum.GL_VERTEX_ARRAY);
            GL.EnableClientState(GL.Enum.GL_TEXTURE_COORD_ARRAY);
            GL.EnableClientState(GL.Enum.GL_COLOR_ARRAY);
            GL.Enable(GL.Enum.GL_TEXTURE_2D);

            GL.UseProgram(0);

            // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
            ImGuiIOPtr io = ImGui.GetIO();

            //ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale); imgui.net doesn't apear to have this

            // Setup orthographic projection matrix
            GL.Viewport(0, 0, displayW, displayH);
            GL.MatrixMode(GL.Enum.GL_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(GL.Enum.GL_MODELVIEW);
            GL.PushMatrix();
            GL.LoadIdentity();

            // Render command lists

            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                ImDrawListPtr cmdList = drawData.CmdListsRange[n];
                //ImDrawList cmdList = drawData[n];
                ImPtrVector <ImDrawVertPtr> vtxBuffer = cmdList.VtxBuffer;
                ImVector <ushort>           idxBuffer = cmdList.IdxBuffer;
                int posOffset = 0;
                int uvOffset  = 8;
                int colOffset = 16;
                //GL.VertexPointer(
                GL.VertexPointer(2, GL.Enum.GL_FLOAT, Unsafe.SizeOf <ImDrawVert>(), new IntPtr((long)vtxBuffer.Data + posOffset));
                GL.TexCoordPointer(2, GL.Enum.GL_FLOAT, Unsafe.SizeOf <ImDrawVert>(), new IntPtr((long)vtxBuffer.Data + uvOffset));
                GL.ColorPointer(4, GL.Enum.GL_UNSIGNED_BYTE, Unsafe.SizeOf <ImDrawVert>(), new IntPtr((long)vtxBuffer.Data + colOffset));

                long idxBufferOffset = 0;
                for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                {
                    ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdi];

                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        throw new NotImplementedException();
                        //pcmd.InvokeUserCallback(ref cmdList, ref pcmd);
                    }
                    else if (FontTextureID == pcmd.TextureId)
                    {
                        GL.BindTexture(GL.Enum.GL_TEXTURE_2D, (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(GL.Enum.GL_TRIANGLES, (int)pcmd.ElemCount, GL.Enum.GL_UNSIGNED_SHORT, new IntPtr((long)idxBuffer.Data + idxBufferOffset));
                    }
                    else
                    {
                        float w, h;
                        var   txid  = pcmd.TextureId;
                        var   sdlid = SDL.SDL_GL_BindTexture(pcmd.TextureId, out w, out h);

                        string errstr = SDL.SDL_GetError();
                        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(GL.Enum.GL_TRIANGLES, (int)pcmd.ElemCount, GL.Enum.GL_UNSIGNED_SHORT, new IntPtr((long)idxBuffer.Data + idxBufferOffset));
                    }
                    idxBufferOffset += pcmd.ElemCount * 2 /*sizeof(ushort)*/;
                }
            }

            // Restore modified state
            GL.DisableClientState(GL.Enum.GL_COLOR_ARRAY);
            GL.DisableClientState(GL.Enum.GL_TEXTURE_COORD_ARRAY);
            GL.DisableClientState(GL.Enum.GL_VERTEX_ARRAY);
            GL.BindTexture(GL.Enum.GL_TEXTURE_2D, lastTexture);
            GL.MatrixMode(GL.Enum.GL_MODELVIEW);
            GL.PopMatrix();
            GL.MatrixMode(GL.Enum.GL_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);
        }
Beispiel #26
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;
            }
        }
    }
Beispiel #27
0
        public void SubmitImGuiToRenderer()
        {
            ImDrawDataPtr test;

            test = ImGui.GetDrawData();
            ImDrawListPtr test3;

            if (test.CmdListsCount > 0)
            {
                test3 = test.CmdListsRange[0];

                ImVector <ushort>           ptr = test3.IdxBuffer;
                ImPtrVector <ImDrawVertPtr> t1  = test3.VtxBuffer;
                ImDrawVertPtr pp;

                ImDrawVert[] vertbuf = new ImDrawVert[t1.Size];

                unsafe
                {
                    for (int i = 0; i < t1.Size; i++)
                    {
                        pp = t1[i];
                        ImDrawVert ff = new ImDrawVert();

                        // Console.WriteLine("vertex x:{0} y:{1}, u:{2} v:{3} color:{4}", ff.pos.X, ff.pos.Y, ff.uv.X, ff.uv.Y, ff.col);
                        ff.pos     = pp.pos;
                        ff.uv      = pp.uv;
                        ff.col     = pp.col;
                        vertbuf[i] = ff;
                    }
                }
                ushort[] indexbuf = new ushort[ptr.Size];

                for (int i = 0; i < ptr.Size; i++)
                {
                    indexbuf[i] = (ushort)ptr[i];
                }

                // indexbuf хранит индекс координаты в vertbuf, рисует полигоны, поэтому уходит по три индекса. индекс составлен так, что координаты
                // перечисляются против часовой стрелки.
                int   y;
                Color c;
                Dictionary <int, Vertex[]> imgvelist = new Dictionary <int, Vertex[]>();
                int idxoffsettemp = 0;
                int nv            = 0;

                for (int i = 0; i < test3.CmdBuffer.Size; i++)
                {
                    ImDrawCmdPtr dc = test3.CmdBuffer[i];
                    if (dc.TextureId != IntPtr.Zero && dc.TextureId.ToInt32() != 1)
                    {
                        List <SpriteRenderable> sr = BufferSpriteRenderable[dc.TextureId.ToInt32()];

                        idxoffsettemp = (int)dc.IdxOffset;

                        // для этих спрайтов в sr,  UV координаты даны относительно текстуры 2048 на 2048 пикселей.
                        y = indexbuf[idxoffsettemp];
                        Vertex[] tempve = new Vertex[6 * sr.Count];
                        nv = 0;

                        foreach (SpriteRenderable sre in sr)
                        {
                            PaletteReference pr = sre.Palette;

                            // берем XY в мире, и превращаем в координаты . Потом отнимаем смещение окна Imgui
                            // float3 worldtoIGposl = sre.ScreenPosition(Game.worldRenderer);

                            // потом в шейдере отнимется смещение от ViewPort
                            // worldtoIGposl = worldtoIGposl - new float3(Game.worldRenderer.Viewport.TopLeft.X, Game.worldRenderer.Viewport.TopLeft.Y, 0);
                            // worldtoIGposl = worldtoIGposl - new float3(worldtoIGposl.X, worldtoIGposl.Y,0);
                            // worldtoIGposl = worldtoIGposl + new float3(this.Bounds.X+100, this.Bounds.Y+100, 0) ;
                            // var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset) - (0.5f * scale * sprite.Size.XY).ToInt2();
                            // Console.WriteLine("x: " + xy.X + " y: " + xy.Y + " | offX:" + sre.sprite.Offset.X + " offY:" + sre.sprite.Offset.Y +" |SpriteRenderable " + this.Actor.Info.Name + " owner:" + this.Actor.Owner);
                            SamplerPointer spritelocation = Game.Renderer.ImguiSpriteRenderer.SetRenderStateForSprite(sre.sprite);
                            // OpenRA.Graphics.Util.FastCreateQuadImGui(tempve, new float3(this.Bounds.X+ 16 * sre.Offset.X / 1024  + sre.sprite.Offset.X, this.Bounds.Y + 16 * sre.Offset.Y  / 1024  + sre.sprite.Offset.Y, 0) + sre.sprite.FractionalOffset * sre.sprite.Size, sre.sprite, new int2(4, 0), pr.TextureIndex, nv, sre.sprite.Size);

                            OpenRA.Graphics.Util.FastCreateQuadImGui(tempve, new float3(16 + vertbuf[y].pos.X + 16 * sre.Offset.X / 1024 + sre.sprite.Offset.X, 16 + vertbuf[y].pos.Y + 16 * sre.Offset.Y / 1024 + sre.sprite.Offset.Y, 0), sre.sprite, spritelocation, pr.TextureIndex, nv, sre.sprite.Size);

                            nv += 6;
                        }

                        nv          -= 6;
                        imgvelist[y] = tempve;

                        // new Vertex(vertbuf[idxoffsettemp].pos.X, vertbuf[idxoffsettemp].pos.Y, 0, vertbuf[idxoffsettemp].uv.X, vertbuf[idxoffsettemp].uv.Y, 0f, 0f, 0f, 5f, 255f / 255f, 255f / 255f, 255f / 255f, 255f / 255f)
                        // sr.Render(null);
                    }
                }
                ve = new Vertex[indexbuf.Length + nv];

                for (int i = 0; i < indexbuf.Length; i++)
                {
                    y = indexbuf[i];                     // индекс для vertbuf хранится в ячейке indexbuf.
                    c = Color.FromArgb(vertbuf[y].col);

                    // если совпал y с imgvelist ключом, то запускаем for на 6 циклов и потом увеличиваем i на 6 позиций.
                    if (imgvelist.ContainsKey(y))
                    {
                        for (int f = 0; f < imgvelist[y].Length; f++)
                        {
                            ve[i] = imgvelist[y][f];
                            i++;
                        }
                        i--;
                    }
                    else
                    {
                        imguifonttextureLocation = Game.Renderer.ImguiSpriteRenderer.SetRenderStateForSprite(sp);
                        ve[i] = new Vertex(vertbuf[y].pos.X, vertbuf[y].pos.Y, 0, vertbuf[y].uv.X, vertbuf[y].uv.Y, 0f, 0f, imguifonttextureLocation.num1, 0f, 4f, 0, c.R / 255f, c.G / 255f, c.B / 255f, c.A / 255f, 0, 0);
                    }
                }

                // теперь нужно создать спрайт, чтобы вызывать Renderer.DrawSprite для занесения данных в VAO
                // типа строчка в VBO появляется как желание нарисовать спрайт. В данном случае спрайт это должна быть буква.
                // Но нет. Тут просто линия цветные
                Game.Renderer.ImguiSpriteRenderer.DrawRGBAVertices(ve);
                //Game.Renderer.ImguiSpriteRenderer.ns = 1;
            }
        }
Beispiel #28
0
        private void DrawPrimitives(int vertex_offset, int index_offset, ImDrawListPtr command_list, ImDrawCmdPtr draw_command)
        {
#pragma warning disable CS0618

#pragma warning disable CS0618

            GraphicsDevice.DrawIndexedPrimitives(
                PrimitiveType.TriangleList, vertex_offset, 0,
                command_list.VtxBuffer.Size, index_offset, (int)((draw_command.ElemCount / 3)));


#pragma warning restore CS0618
        }
        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;
            }
        }
Beispiel #30
0
        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);
        }