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);
        }
Esempio n. 2
0
        unsafe void updateBuffers(ImDrawDataPtr drawData)
        {
            if (drawData.TotalVtxCount == 0)
            {
                return;
            }

            // Expand buffers if we need more room
            if (drawData.TotalVtxCount > _vertexBufferSize)
            {
                _vertexBuffer?.Dispose();

                _vertexBufferSize = (int)(drawData.TotalVtxCount * 1.5f);
                _vertexBuffer     = new VertexBuffer(Core.graphicsDevice, _vertexDeclaration, _vertexBufferSize, BufferUsage.None);
                _vertexData       = new byte[_vertexBufferSize * _vertexDeclarationSize];
            }

            if (drawData.TotalIdxCount > _indexBufferSize)
            {
                _indexBuffer?.Dispose();

                _indexBufferSize = (int)(drawData.TotalIdxCount * 1.5f);
                _indexBuffer     = new IndexBuffer(Core.graphicsDevice, IndexElementSize.SixteenBits, _indexBufferSize, BufferUsage.None);
                _indexData       = new byte[_indexBufferSize * sizeof(ushort)];
            }

            // Copy ImGui's vertices and indices to a set of managed byte arrays
            int vtxOffset = 0;
            int idxOffset = 0;

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

                fixed(void *vtxDstPtr = &_vertexData[vtxOffset *_vertexDeclarationSize])
                fixed(void *idxDstPtr = &_indexData[idxOffset * sizeof(ushort)])
                {
                    Buffer.MemoryCopy((void *)cmdList.VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList.VtxBuffer.Size * _vertexDeclarationSize);
                    Buffer.MemoryCopy((void *)cmdList.IdxBuffer.Data, idxDstPtr, _indexData.Length, cmdList.IdxBuffer.Size * sizeof(ushort));
                }

                vtxOffset += cmdList.VtxBuffer.Size;
                idxOffset += cmdList.IdxBuffer.Size;
            }

            // Copy the managed byte arrays to the gpu vertex- and index buffers
            _vertexBuffer.SetData(_vertexData, 0, drawData.TotalVtxCount * _vertexDeclarationSize);
            _indexBuffer.SetData(_indexData, 0, drawData.TotalIdxCount * sizeof(ushort));
        }
Esempio n. 3
0
        void UpdateBuffers(ImDrawDataPtr drawData)
        {
            // copy de dators
            int vtxOffsetBytes = 0;
            int idxOffsetBytes = 0;

            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                ImDrawListPtr cmdList = drawData.CmdListsRange[n];
                vertexBinding.Buffer.SetData(commandList, new DataPointer(cmdList.VtxBuffer.Data, cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()), vtxOffsetBytes);
                indexBinding.Buffer.SetData(commandList, new DataPointer(cmdList.IdxBuffer.Data, cmdList.IdxBuffer.Size * sizeof(ushort)), idxOffsetBytes);
                vtxOffsetBytes += cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>();
                idxOffsetBytes += cmdList.IdxBuffer.Size * sizeof(ushort);
            }
        }
Esempio n. 4
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;
            }
        }
        /// <summary>
        /// Ensures that the geometry buffers exist and have sufficient size.
        /// </summary>
        private void EnsureBuffers(ref ImDrawDataPtr drawDataPtr)
        {
            var dirty    = false;
            var vtxCount = 0;
            var idxCount = 0;

            for (var i = 0; i < drawDataPtr.CmdListsCount; i++)
            {
                var cmd = drawDataPtr.CmdListsRange[i];
                vtxCount = Math.Max(vtxCount, cmd.VtxBuffer.Size);
                idxCount = Math.Max(idxCount, cmd.IdxBuffer.Size);
            }

            if (vertexBuffer == null || vertexBuffer.VertexCount < vtxCount)
            {
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }

                vertexBuffer = DynamicVertexBuffer.Create(ImGuiVertex.VertexDeclaration, vtxCount);
                dirty        = true;
            }

            if (indexBuffer == null || indexBuffer.IndexCount < idxCount)
            {
                if (indexBuffer != null)
                {
                    indexBuffer.Dispose();
                }

                indexBuffer = DynamicIndexBuffer.Create(IndexBufferElementType.Int16, idxCount);
                dirty       = true;
            }

            if (rasterizerState == null)
            {
                rasterizerState = RasterizerState.Create();
                rasterizerState.ScissorTestEnable = true;
            }

            if (geometryStream == null || dirty)
            {
                this.geometryStream = GeometryStream.Create();
                this.geometryStream.Attach(this.vertexBuffer);
                this.geometryStream.Attach(this.indexBuffer);
            }
        }
Esempio n. 6
0
        private unsafe void UpdateBuffers(ImDrawDataPtr drawData)
        {
            if (drawData.TotalVtxCount == 0)
            {
                return;
            }
            //// Expand buffers if we need more room
            //if (drawData.TotalVtxCount > _vertexBufferSize)
            //{
            //    _vertexBuffer?.Dispose();

            //    _vertexBufferSize = (int)(drawData.TotalVtxCount * 1.5f);
            //    _vertexBuffer = new VertexBuffer(_graphicsDevice, DrawVertDeclaration.Declaration, _vertexBufferSize, BufferUsage.None);
            //    _vertexData = new byte[_vertexBufferSize * DrawVertDeclaration.Size];
            //}

            //if (drawData.TotalIdxCount > _indexBufferSize)
            //{
            //    _indexBuffer?.Dispose();

            //    _indexBufferSize = (int)(drawData.TotalIdxCount * 1.5f);
            //    _indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, _indexBufferSize, BufferUsage.None);
            //    _indexData = new byte[_indexBufferSize * sizeof(ushort)];
            //}

            //// Copy ImGui's vertices and indices to a set of managed byte arrays
            //int vtxOffset = 0;
            //int idxOffset = 0;

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

            //    fixed (void* vtxDstPtr = &_vertexData[vtxOffset * DrawVertDeclaration.Size])
            //    fixed (void* idxDstPtr = &_indexData[idxOffset * sizeof(ushort)])
            //    {
            //        Buffer.MemoryCopy((void*)cmdList.VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList.VtxBuffer.Size * DrawVertDeclaration.Size);
            //        Buffer.MemoryCopy((void*)cmdList.IdxBuffer.Data, idxDstPtr, _indexData.Length, cmdList.IdxBuffer.Size * sizeof(ushort));
            //    }

            //    vtxOffset += cmdList.VtxBuffer.Size;
            //    idxOffset += cmdList.IdxBuffer.Size;
            //}

            //// Copy the managed byte arrays to the gpu vertex- and index buffers
            //_vertexBuffer.SetData(_vertexData, 0, drawData.TotalVtxCount * DrawVertDeclaration.Size);
            //_indexBuffer.SetData(_indexData, 0, drawData.TotalIdxCount * sizeof(ushort));
        }
        public static void Render(ImDrawDataPtr drawData, int w, int h)
        {
            var io = ImGui.GetIO();

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            m_shader.Use();
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, m_fontsTextureHandle);

            m_shader.SetVector2("viewport_min", new Vector2(0, 0));
            m_shader.SetVector2("viewport_max", new Vector2(w, h));

            GL.BindVertexArray(m_vertexArray);

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

                GL.BindBuffer(BufferTarget.ArrayBuffer, m_vertexBuffer);
                GL.BufferData(BufferTarget.ArrayBuffer,
                              cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(),
                              cmdList.VtxBuffer.Data, BufferUsageHint.DynamicDraw);

                GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_indexBuffer);
                GL.BufferData(BufferTarget.ElementArrayBuffer,
                              cmdList.IdxBuffer.Size * sizeof(ushort),
                              cmdList.IdxBuffer.Data, BufferUsageHint.DynamicDraw);

                for (int j = 0; j < cmdList.CmdBuffer.Size; ++j)
                {
                    var cmd = cmdList.CmdBuffer[j];

                    int elemCount = (int)cmd.ElemCount;
                    int offset    = (int)cmd.IdxOffset;
                    GL.DrawElements(PrimitiveType.Triangles, elemCount, DrawElementsType.UnsignedShort, offset * sizeof(ushort));
                }

                //cmdList.VtxBuffer.Size



                //var d = drawList.VtxBuffer

                //drawList.VtxBuffer[0].
            }
        }
Esempio n. 8
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;
            }
        }
Esempio n. 9
0
        private void SetupRenderState(ImDrawDataPtr drawData, int fbWidth, int fbHeight, uint vertexArrayObject)
        {
            glEnable(GL_BLEND);
            glBlendEquation(GL_FUNC_ADD);
            glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
            glDisable(GL_CULL_FACE);
            glDisable(GL_DEPTH_TEST);
            glDisable(GL_STENCIL_TEST);
            glEnable(GL_SCISSOR_TEST);
            glDisable(GL_PRIMITIVE_RESTART);
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

            glViewport(0, 0, fbWidth, fbHeight);
            var l = drawData.DisplayPos.X;
            var r = drawData.DisplayPos.X + drawData.DisplaySize.X;
            var t = drawData.DisplayPos.Y;
            var b = drawData.DisplayPos.Y + drawData.DisplaySize.Y;

            var orthoProjection = new[, ]
            {
                { 2.0f / (r - l), 0.0f, 0.0f, 0.0f },
                { 0.0f, 2.0f / (t - b), 0.0f, 0.0f },
                { 0.0f, 0.0f, -1.0f, 0.0f },
                { (r + l) / (l - r), (t + b) / (b - t), 0.0f, 1.0f },
            };

            glUseProgram(_shaderHandle);
            glUniform1i(_attribLocationTex, 0);
            glUniformMatrix4fv(_attribLocationProjMtx, 1, false, orthoProjection[0, 0]);

            glBindSampler(0, 0);

            glBindVertexArray(vertexArrayObject);

            glBindBuffer(GL_ARRAY_BUFFER, _vboHandle);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _elementsHandle);
            glEnableVertexAttribArray(_attribLocationVtxPos);
            glEnableVertexAttribArray(_attribLocationVtxUv);
            glEnableVertexAttribArray(_attribLocationVtxColor);

            glVertexAttribPointer(_attribLocationVtxPos, 2, GL_FLOAT, false, Unsafe.SizeOf <ImDrawVert>(),
                                  Marshal.OffsetOf <ImDrawVert>("pos"));
            glVertexAttribPointer(_attribLocationVtxUv, 2, GL_FLOAT, false, Unsafe.SizeOf <ImDrawVert>(),
                                  Marshal.OffsetOf <ImDrawVert>("uv"));
            glVertexAttribPointer(_attribLocationVtxColor, 4, GL_UNSIGNED_BYTE, true, Unsafe.SizeOf <ImDrawVert>(),
                                  Marshal.OffsetOf <ImDrawVert>("col"));
        }
        private unsafe void UpdateBuffers(ImDrawDataPtr drawData)
        {
            if (drawData.TotalVtxCount == 0)
            {
                return;
            }

            if (drawData.TotalVtxCount > vertexBufferSize)
            {
                vertexBuffer?.Dispose();

                vertexBufferSize = (int)(drawData.TotalVtxCount * 1.5f);
                vertexBuffer     = new VertexBuffer(GraphicsDevice, DrawVertexDeclaration.Declaration, vertexBufferSize, BufferUsage.None);
                vertexData       = new byte[vertexBufferSize * DrawVertexDeclaration.Size];
            }

            if (drawData.TotalIdxCount > indexBufferSize)
            {
                indexBuffer?.Dispose();

                indexBufferSize = (int)(drawData.TotalIdxCount * 1.5f);
                indexBuffer     = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, indexBufferSize, BufferUsage.None);
                indexData       = new byte[indexBufferSize * sizeof(ushort)];
            }

            int vtxOffset = 0;
            int idxOffset = 0;

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

                fixed(void *vtxDstPtr = &vertexData[vtxOffset *DrawVertexDeclaration.Size])
                fixed(void *idxDstPtr = &indexData[idxOffset * sizeof(ushort)])
                {
                    Buffer.MemoryCopy((void *)cmdList.VtxBuffer.Data, vtxDstPtr, vertexData.Length, cmdList.VtxBuffer.Size * DrawVertexDeclaration.Size);
                    Buffer.MemoryCopy((void *)cmdList.IdxBuffer.Data, idxDstPtr, indexData.Length, cmdList.IdxBuffer.Size * sizeof(ushort));
                }

                vtxOffset += cmdList.VtxBuffer.Size;
                idxOffset += cmdList.IdxBuffer.Size;
            }

            vertexBuffer.SetData(vertexData, 0, drawData.TotalVtxCount * DrawVertexDeclaration.Size);
            indexBuffer.SetData(indexData, 0, drawData.TotalIdxCount * sizeof(ushort));
        }
Esempio n. 11
0
        private unsafe void UpdateBuffers(ImDrawDataPtr drawData)
        {
            if (drawData.TotalVtxCount == 0)
            {
                return;
            }

            if (drawData.TotalVtxCount > _imGuiVertex.BufferSize)
            {
                _imGuiVertex.Buffer?.Dispose();
                _imGuiVertex.BufferSize = (int)(drawData.TotalVtxCount * 1.5f);
                _imGuiVertex.Buffer     = new VertexBuffer(GraphicsDevice, DrawVertexDeclaration.Declaration, _imGuiVertex.BufferSize, BufferUsage.None);
                _imGuiVertex.Data       = new byte[_imGuiVertex.BufferSize * DrawVertexDeclaration.Size];
            }

            if (drawData.TotalIdxCount > _imGuiIndex.BufferSize)
            {
                _imGuiIndex.Buffer?.Dispose();

                _imGuiIndex.BufferSize = (int)(drawData.TotalIdxCount * 1.5f);
                _imGuiIndex.Buffer     = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, _imGuiIndex.BufferSize, BufferUsage.None);
                _imGuiIndex.Data       = new byte[_imGuiIndex.BufferSize * sizeof(ushort)];
            }

            var vertexOffset = 0;
            var indexOffset  = 0;

            for (var i = 0; i < drawData.CmdListsCount; ++i)
            {
                var commands = drawData.CmdListsRange[i];
                fixed(void *vtxDstPtr = &_imGuiVertex.Data[vertexOffset *DrawVertexDeclaration.Size])
                {
                    fixed(void *idxDstPtr = &_imGuiIndex.Data[indexOffset * sizeof(ushort)])
                    {
                        Buffer.MemoryCopy((void *)commands.VtxBuffer.Data, vtxDstPtr, _imGuiVertex.Data.Length, commands.VtxBuffer.Size * DrawVertexDeclaration.Size);
                        Buffer.MemoryCopy((void *)commands.IdxBuffer.Data, idxDstPtr, _imGuiIndex.Data.Length, commands.IdxBuffer.Size * sizeof(ushort));
                    }
                }

                vertexOffset += commands.VtxBuffer.Size;
                indexOffset  += commands.IdxBuffer.Size;
            }

            _imGuiVertex.Buffer.SetData(_imGuiVertex.Data, 0, drawData.TotalVtxCount * DrawVertexDeclaration.Size);
            _imGuiIndex.Buffer.SetData(_imGuiIndex.Data, 0, drawData.TotalIdxCount * sizeof(ushort));
        }
        public void RenderDrawLists(CommandBuffer cmd, ImDrawDataPtr drawData)
        {
            Vector2 fbSize = drawData.DisplaySize * drawData.FramebufferScale;

            if (fbSize.x <= 0f || fbSize.y <= 0f || drawData.TotalVtxCount == 0)
            {
                return; // avoid rendering when minimized
            }
            s_updateBuffersPerfMarker.Begin();
            UpdateBuffers(drawData);
            s_updateBuffersPerfMarker.End();

            cmd.BeginSample("DearImGui.ExecuteDrawCommands");
            s_createDrawComandsPerfMarker.Begin();
            CreateDrawCommands(cmd, drawData, fbSize);
            s_createDrawComandsPerfMarker.End();
            cmd.EndSample("DearImGui.ExecuteDrawCommands");
        }
        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();
        }
        private void RenderDrawData(ImDrawDataPtr drawData)
        {
            var width  = (int)(drawData.DisplaySize.X * drawData.FramebufferScale.X);
            var height = (int)(drawData.DisplaySize.Y * drawData.FramebufferScale.Y);

            var renderState = SaveRenderState();

            SetupRenderState(drawData, width, height, _vertexArray);

            var clipOff   = drawData.DisplayPos;
            var clipScale = drawData.FramebufferScale;

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

                GL.BufferData(BufferTarget.ArrayBuffer, cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data, BufferUsageHint.StreamDraw);
                GL.BufferData(BufferTarget.ElementArrayBuffer, cmdList.IdxBuffer.Size * sizeof(short), cmdList.IdxBuffer.Data, BufferUsageHint.StreamDraw);

                for (int cmd_i = 0; cmd_i < cmdList.CmdBuffer.Size; cmd_i++)
                {
                    var pcmd = cmdList.CmdBuffer[cmd_i];

                    Vector4 clipRect = new Vector4
                                       (
                        (pcmd.ClipRect.X - clipOff.X) * clipScale.X,
                        (pcmd.ClipRect.Y - clipOff.Y) * clipScale.Y,
                        (pcmd.ClipRect.Z - clipOff.X) * clipScale.X,
                        (pcmd.ClipRect.W - clipOff.Y) * clipScale.Y
                                       );

                    if (clipRect.X < width && clipRect.Y < height && clipRect.Z >= 0.0f && clipRect.W >= 0.0f)
                    {
                        GL.Scissor((int)(clipRect.X), (int)(height - clipRect.W), (int)(clipRect.Z - clipRect.X), (int)(clipRect.W - clipRect.Y));

                        GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId);

                        GL.DrawElements(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(pcmd.IdxOffset * sizeof(short)));
                    }
                }
            }

            RestoreRenderState(renderState);
        }
Esempio n. 15
0
        private void RenderDrawData(ImDrawDataPtr ptr)
        {
            Viewport  lastViewport = GraphicsDevice.Viewport;
            Rectangle lastScissor  = GraphicsDevice.ScissorRectangle;

            GraphicsDevice.BlendFactor       = Color.White;
            GraphicsDevice.BlendState        = BlendState.NonPremultiplied;
            GraphicsDevice.RasterizerState   = RasterizerState;
            GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;

            ptr.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale);
            GraphicsDevice.Viewport = new Viewport(0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight);
            UpdateBuffers(ptr);
            RenderCommandLists(ptr);

            // Restore graphics state
            GraphicsDevice.Viewport         = lastViewport;
            GraphicsDevice.ScissorRectangle = lastScissor;
        }
Esempio n. 16
0
        void CheckBuffers(ImDrawDataPtr drawData)
        {
            uint totalVBOSize = (uint)(drawData.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>());

            if (totalVBOSize > vertexBinding.Buffer.SizeInBytes)
            {
                var vertexBuffer = Xenko.Graphics.Buffer.Vertex.New(device, (int)(totalVBOSize * 1.5f));
                vertexBinding = new VertexBufferBinding(vertexBuffer, imVertLayout, 0);
            }

            uint totalIBOSize = (uint)(drawData.TotalIdxCount * sizeof(ushort));

            if (totalIBOSize > indexBinding.Buffer.SizeInBytes)
            {
                var is32Bits    = false;
                var indexBuffer = Xenko.Graphics.Buffer.Index.New(device, (int)(totalIBOSize * 1.5f));
                indexBinding = new IndexBufferBinding(indexBuffer, is32Bits, 0);
            }
        }
Esempio n. 17
0
        private void SetupRenderState(ImDrawDataPtr drawData)
        {
            // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
            Gl.Enable(EnableCap.Blend);
            Gl.BlendEquation(BlendEquationMode.FuncAdd);
            Gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
            Gl.Disable(EnableCap.CullFace);
            Gl.Disable(EnableCap.DepthTest);
            Gl.Enable(EnableCap.ScissorTest);
            Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);

            // Setup viewport, orthographic projection matrix
            // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
            Gl.Viewport(0, 0, (int)(drawData.DisplaySize.X * drawData.FramebufferScale.X), (int)(drawData.DisplaySize.Y * drawData.FramebufferScale.Y));
            var L = drawData.DisplayPos.X;
            var R = drawData.DisplayPos.X + drawData.DisplaySize.X;
            var T = drawData.DisplayPos.Y;
            var B = drawData.DisplayPos.Y + drawData.DisplaySize.Y;
            var ortho_projection = new float[]
            {
                2f / (R - L), 0, 0, 0,
                0, 2f / (T - B), 0, 0,
                0, 0, -1f, 0,
                (R + L) / (L - R), (T + B) / (B - T), 0, 1f
            };

            Gl.UseProgram(_shaderHandle);
            Gl.Uniform1(_attribLocationTex, 0);
            Gl.UniformMatrix4(_attribLocationProjMtx, false, ortho_projection);

            Gl.BindVertexArray(_vertexArrayObject);

            // Bind vertex/index buffers and setup attributes for ImDrawVert
            Gl.BindBuffer(BufferTarget.ArrayBuffer, _vboHandle);
            Gl.BindBuffer(BufferTarget.ElementArrayBuffer, _elementsHandle);
            Gl.EnableVertexAttribArray((uint)_attribLocationVtxPos);
            Gl.EnableVertexAttribArray((uint)_attribLocationVtxUV);
            Gl.EnableVertexAttribArray((uint)_attribLocationVtxColor);
            Gl.VertexAttribPointer((uint)_attribLocationVtxPos, 2, VertexAttribType.Float, false, Unsafe.SizeOf <ImDrawVert>(), Marshal.OffsetOf(typeof(ImDrawVert), "pos"));
            Gl.VertexAttribPointer((uint)_attribLocationVtxUV, 2, VertexAttribType.Float, false, Unsafe.SizeOf <ImDrawVert>(), Marshal.OffsetOf(typeof(ImDrawVert), "uv"));
            Gl.VertexAttribPointer((uint)_attribLocationVtxColor, 4, VertexAttribType.UnsignedByte, true, Unsafe.SizeOf <ImDrawVert>(), Marshal.OffsetOf(typeof(ImDrawVert), "col"));
        }
Esempio n. 18
0
        private unsafe void RenderImDrawData(DrawEvent e)
        {
            CommandBuffer cmdBuffer = e.cmd;
            var           io        = ImGui.GetIO();
            var           graphics  = Graphics.Instance;
            float         width     = io.DisplaySize.X;
            float         height    = io.DisplaySize.Y;
            ImDrawDataPtr draw_data = ImGui.GetDrawData();

            if (draw_data.CmdListsCount == 0)
            {
                return;
            }

            if (pipeline == VkPipeline.Null)
            {
                pipeline = pass.CreateGraphicsPipeline(e.rendrPass, 0, VertexPos2dTexColor.Layout, VkPrimitiveTopology.TriangleList);
            }

            ref Buffer vb = ref vertexBuffer[graphics.WorkContext];
        public unsafe void RenderDrawLists(CommandBuffer cmd, ImDrawDataPtr drawData)
        {
            NumericsV2f fbOSize = drawData.DisplaySize * drawData.FramebufferScale;

            if (fbOSize.X <= 0f || fbOSize.Y <= 0f || drawData.TotalVtxCount == 0)
            {
                return;                 // avoid rendering when minimized
            }
            Vector2 fbSize = *(Vector2 *)&fbOSize;

            s_updateMeshPerfMarker.Begin();
            UpdateMesh(drawData, fbSize);
            s_updateMeshPerfMarker.End();

            cmd.BeginSample("DearImGui.ExecuteDrawCommands");
            s_createDrawComandsPerfMarker.Begin();
            CreateDrawCommands(cmd, drawData, fbSize);
            s_createDrawComandsPerfMarker.End();
            cmd.EndSample("DearImGui.ExecuteDrawCommands");
        }
Esempio n. 20
0
        private void UpdateBuffers(ImDrawDataPtr data)
        {
            GL.BindVertexArray(vao);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);

            int totalVBSize = (data.TotalVtxCount * Marshal.SizeOf <ImDrawVert>());

            if (totalVBSize > sizeVertex)
            {
                sizeVertex = (int)(totalVBSize * 1.5f);

                GL.BufferData(BufferTarget.ArrayBuffer, sizeVertex, IntPtr.Zero, BufferUsageHint.DynamicDraw);
            }

            uint totalIBSize = (uint)(data.TotalIdxCount * sizeof(ushort));

            if (totalIBSize > sizeIndex)
            {
                sizeIndex = (int)(totalIBSize * 1.5f);

                GL.BufferData(BufferTarget.ElementArrayBuffer, sizeIndex, IntPtr.Zero, BufferUsageHint.DynamicDraw);
            }

            int vertexOffsetInVertices = 0;
            int indexOffsetInElements  = 0;

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

                GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(vertexOffsetInVertices * Marshal.SizeOf <ImDrawVert>()),
                                 cmd_list.VtxBuffer.Size * Marshal.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data);

                GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)(indexOffsetInElements * sizeof(ushort)),
                                 cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data);

                vertexOffsetInVertices += cmd_list.VtxBuffer.Size;
                indexOffsetInElements  += cmd_list.IdxBuffer.Size;
            }
        }
Esempio n. 21
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();
        }
Esempio n. 23
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;
            }
        }
Esempio n. 24
0
        void SetupRenderState(ImDrawDataPtr drawData, int fbWidth, int fbHeight)
        {
            glEnable(EnableCap.Blend);
            glBlendEquation(BlendEquationMode.FuncAdd);
            glBlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
            glDisable(EnableCap.CullFace);
            glDisable(EnableCap.DepthTest);
            glEnable(EnableCap.ScissorTest);

            glUseProgram(_shader.ProgramID);

            var left   = drawData.DisplayPos.X;
            var right  = drawData.DisplayPos.X + drawData.DisplaySize.X;
            var top    = drawData.DisplayPos.Y;
            var bottom = drawData.DisplayPos.Y + drawData.DisplaySize.Y;

            _shader["Texture"].SetValue(0);
            _shader["ProjMtx"].SetValue(Matrix4x4.CreateOrthographicOffCenter(left, right, bottom, top, -1, 1));
            glBindSampler(0, 0);

            glBindVertexArray(_vertexArrayObject);

            // Bind vertex/index buffers and setup attributes for ImDrawVert
            glBindBuffer(BufferTarget.ArrayBuffer, _vboHandle);
            glBindBuffer(BufferTarget.ElementArrayBuffer, _elementsHandle);

            EnableVertexAttribArray(_shader["Position"].Location);
            EnableVertexAttribArray(_shader["UV"].Location);
            EnableVertexAttribArray(_shader["Color"].Location);

            var drawVertSize = Marshal.SizeOf <ImDrawVert>();

            VertexAttribPointer(_shader["Position"].Location, 2, VertexAttribPointerType.Float, false, drawVertSize, Marshal.OffsetOf <ImDrawVert>("pos"));
            VertexAttribPointer(_shader["UV"].Location, 2, VertexAttribPointerType.Float, false, drawVertSize, Marshal.OffsetOf <ImDrawVert>("uv"));
            VertexAttribPointer(_shader["Color"].Location, 4, VertexAttribPointerType.UnsignedByte, true, drawVertSize, Marshal.OffsetOf <ImDrawVert>("col"));
        }
Esempio n. 25
0
        public void RenderDrawData(RenderContext renderContext, ImDrawDataPtr drawData, int windowWidth, int windowHeight)
        {
            // If width or height is zero, game is minimized, so don't draw anything.
            if (windowWidth == 0 || windowHeight == 0)
            {
                return;
            }

            Rectangle lastViewport         = renderContext.ViewportRectangle;
            Rectangle lastScissorRectangle = renderContext.ScissorRectangle;
            bool      lastBlend            = renderContext.Blend;
            bool      lastDepthTest        = renderContext.DepthTest;
            bool      lastScissorTest      = renderContext.ScissorTest;
            bool      lastCullBackfaces    = renderContext.CullBackfaces;

            // RenderContext.State state = renderContext.GetState();

            renderContext.ViewportRectangle = new Rectangle(0, 0, windowWidth, windowHeight);
            renderContext.ScissorRectangle  = new Rectangle(0, 0, windowWidth, windowHeight);
            renderContext.Blend             = true;
            renderContext.DepthTest         = false;
            renderContext.ScissorTest       = true;
            renderContext.CullBackfaces     = false;

            UpdateBuffers(renderContext, drawData);
            RenderCommandLists(renderContext, drawData);

            // renderContext.SetState(state);

            renderContext.ViewportRectangle = lastViewport;
            renderContext.ScissorRectangle  = lastScissorRectangle;
            renderContext.Blend             = lastBlend;
            renderContext.DepthTest         = lastDepthTest;
            renderContext.ScissorTest       = lastScissorTest;
            renderContext.CullBackfaces     = lastCullBackfaces;
        }
Esempio n. 26
0
        /// <summary>
        /// Gets the geometry as set up by ImGui and sends it to the graphics device
        /// </summary>
        void RenderDrawData(ImDrawDataPtr drawData)
        {
            // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers
            var lastViewport   = Core.GraphicsDevice.Viewport;
            var lastScissorBox = Core.GraphicsDevice.ScissorRectangle;

            Core.GraphicsDevice.BlendFactor       = Color.White;
            Core.GraphicsDevice.BlendState        = BlendState.NonPremultiplied;
            Core.GraphicsDevice.RasterizerState   = _rasterizerState;
            Core.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;

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

            // Setup projection
            Core.GraphicsDevice.Viewport = new Viewport(0, 0, Core.GraphicsDevice.PresentationParameters.BackBufferWidth, Core.GraphicsDevice.PresentationParameters.BackBufferHeight);

            UpdateBuffers(drawData);
            RenderCommandLists(drawData);

            // Restore modified state
            Core.GraphicsDevice.Viewport         = lastViewport;
            Core.GraphicsDevice.ScissorRectangle = lastScissorBox;
        }
Esempio n. 27
0
        private void RenderImDrawData(ImDrawDataPtr drawData, GraphicsDevice gd, CommandList cl)
        {
            uint vertexOffsetInVertices = 0;
            uint indexOffsetInElements  = 0;

            if (drawData.CmdListsCount == 0)
            {
                return;
            }

            uint totalVbSize = (uint)(drawData.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>());

            if (totalVbSize > _vertexBuffer.SizeInBytes)
            {
                gd.DisposeWhenIdle(_vertexBuffer);
                _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVbSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic));
            }

            uint totalIbSize = (uint)(drawData.TotalIdxCount * sizeof(ushort));

            if (totalIbSize > _indexBuffer.SizeInBytes)
            {
                gd.DisposeWhenIdle(_indexBuffer);
                _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIbSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic));
            }

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

                cl.UpdateBuffer(
                    _vertexBuffer,
                    vertexOffsetInVertices * (uint)Unsafe.SizeOf <ImDrawVert>(),
                    cmdList.VtxBuffer.Data,
                    (uint)(cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()));

                cl.UpdateBuffer(
                    _indexBuffer,
                    indexOffsetInElements * sizeof(ushort),
                    cmdList.IdxBuffer.Data,
                    (uint)(cmdList.IdxBuffer.Size * sizeof(ushort)));

                vertexOffsetInVertices += (uint)cmdList.VtxBuffer.Size;
                indexOffsetInElements  += (uint)cmdList.IdxBuffer.Size;
            }

            // Setup orthographic projection matrix into our constant buffer
            ImGuiIOPtr io  = ImGui.GetIO();
            Matrix4x4  mvp = Matrix4x4.CreateOrthographicOffCenter(
                0f,
                io.DisplaySize.X,
                io.DisplaySize.Y,
                0.0f,
                -1.0f,
                1.0f);

            _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp);

            cl.SetVertexBuffer(0, _vertexBuffer);
            cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16);
            cl.SetPipeline(_pipeline);
            cl.SetGraphicsResourceSet(0, _mainResourceSet);

            drawData.ScaleClipRects(io.DisplayFramebufferScale);

            // Render command lists
            int vtxOffset = 0;
            int idxOffset = 0;

            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                ImDrawListPtr cmdList = drawData.CmdListsRange[n];
                for (int cmdI = 0; cmdI < cmdList.CmdBuffer.Size; cmdI++)
                {
                    ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdI];
                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        if (pcmd.TextureId != IntPtr.Zero)
                        {
                            if (pcmd.TextureId == _fontAtlasID)
                            {
                                cl.SetGraphicsResourceSet(1, _fontTextureResourceSet);
                            }
                            else
                            {
                                cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId));
                            }
                        }

                        cl.SetScissorRect(
                            0,
                            (uint)pcmd.ClipRect.X,
                            (uint)pcmd.ClipRect.Y,
                            (uint)(pcmd.ClipRect.Z - pcmd.ClipRect.X),
                            (uint)(pcmd.ClipRect.W - pcmd.ClipRect.Y));

                        cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idxOffset, vtxOffset, 0);
                    }

                    idxOffset += (int)pcmd.ElemCount;
                }
                vtxOffset += cmdList.VtxBuffer.Size;
            }
        }
Esempio n. 28
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;

                    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);
        }
Esempio n. 29
0
    void LateUpdate()
    {
        last_start = stopwatch.Elapsed.TotalSeconds;
        if (drawDebugWindow)
        {
            DrawDebugWindow();
        }
        ImGui.EndFrame();

        if (queue_font_rebuild)
        {
            RebuildFonts();
            queue_font_rebuild = false;
        }

        // custom cursors
        if (enableCustomCursors)
        {
            ImGuiMouseCursor cursor    = ImGui.GetMouseCursor();
            Texture2D        cursorTex = null;
            Vector2          hotspot   = cursorHotspot;
            switch (cursor)
            {
            case ImGuiMouseCursor.Arrow:
                cursorTex = customCursorArrow;
                break;

            case ImGuiMouseCursor.TextInput:
                cursorTex = customCursorTextInput;
                break;

            case ImGuiMouseCursor.ResizeEW:
                cursorTex = customCursorResizeEW;
                break;

            case ImGuiMouseCursor.ResizeNESW:
                cursorTex  = customCursorResizeNESW;
                hotspot.x += 5; hotspot.y += 5;
                break;

            case ImGuiMouseCursor.ResizeNS:
                cursorTex = customCursorResizeNS;
                break;

            case ImGuiMouseCursor.ResizeNWSE:
                cursorTex  = customCursorResizeNWSE;
                hotspot.x += 5; hotspot.y += 5;
                break;

            default:
                break;
            }
            // Don't set cursor if it has not actually changed
            if (currentCursorTex != cursorTex)
            {
                if (cursorTex != null)
                {
                    Cursor.SetCursor(cursorTex, hotspot, CursorMode.Auto);
                }
                else
                {
                    Cursor.SetCursor(null, cursorHotspot, CursorMode.Auto);
                }
                currentCursorTex = cursorTex;
            }
        }

        ImGui.Render();

        // render ImGui
        ImDrawDataPtr data = ImGui.GetDrawData();

        if (commandBuffer != null)
        {
            // Clear buffer regardless of whether we have something to render or not
            commandBuffer.Clear();
        }

        // Don't update meshes and Command Buffers if there is nothing to render
        if (data.CmdListsCount > 0)
        {
            // resize meshes array
            int numDrawCommands = 0;
            for (int i = 0; i < data.CmdListsCount; i++)
            {
                ImDrawListPtr cmdList   = data.getDrawListPtr(i);
                var           cmdBuffer = cmdList.CmdBuffer;
                numDrawCommands += cmdBuffer.Size;
            }

            if (meshes == null)
            {
                meshes = new List <ImGuiMesh>();
            }

            if (meshes.Count != numDrawCommands)
            {
                // add new meshes to list if needed
                for (int i = meshes.Count; i < numDrawCommands; i++)
                {
                    ImGuiMesh mesh = new ImGuiMesh();
                    meshes.Add(mesh);
                }
                // delete extra meshes if needed
                for (int i = meshes.Count - 1; i >= numDrawCommands; i--)
                {
                    Destroy(meshes[i].mesh);
                    meshes.RemoveAt(i);
                }
            }

            if (commandBuffer == null)
            {
                commandBuffer      = new CommandBuffer();
                commandBuffer.name = "ImGui Renderer";
                commandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
                guiCamera.AddCommandBuffer(CameraEvent.AfterEverything, commandBuffer);
            }

            commandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
            // orthogonal projection of GUI mesh to camera space
            Matrix4x4 matrix = Matrix4x4.Ortho(0, Screen.width, 0, Screen.height, 0, 0.1f);
            // negate world to camera transform and projection which Unity applies itself
            matrix = guiCamera.cameraToWorldMatrix * guiCamera.projectionMatrix.inverse * matrix;

            // update Command Buffers
            int count = 0;
            for (int i = 0; i < data.CmdListsCount; i++)
            {
                ImDrawListPtr cmdList   = data.getDrawListPtr(i);
                var           cmdBuffer = cmdList.CmdBuffer;

                uint startElement = 0;
                for (int j = 0; j < cmdBuffer.Size; j++)
                {
                    ImDrawCmd cmd  = cmdBuffer[j];
                    Rect      rect = new Rect
                    {
                        min = new Vector2(cmd.ClipRect.x, Screen.height - cmd.ClipRect.y),
                        max = new Vector2(cmd.ClipRect.z, Screen.height - cmd.ClipRect.w)
                    };
                    commandBuffer.EnableScissorRect(rect);

                    meshes[count].UpdateMesh(cmd, cmdList.IdxBuffer, cmdList.VtxBuffer, (int)startElement);
                    if (cmd.TextureId == fontTexturePtr)
                    {
                        mpb.SetTexture(main_tex_id, fontTexture);
                        commandBuffer.DrawMesh(meshes[count].mesh, matrix, material, 0, 0, mpb);
                    }
                    else if (textures.ContainsKey(cmd.TextureId))
                    {
                        mpb.SetTexture(main_tex_id, textures[cmd.TextureId]);
                        commandBuffer.DrawMesh(meshes[count].mesh, matrix, material, 0, 0, mpb);
                    }
                    else
                    {
                        Debug.LogWarning("Image texture missing!");
                    }

                    startElement += cmd.ElemCount;
                    count++;
                }
            }
        }
        else if (commandBuffer != null)
        {
            // Remove Command Buffer if there is nothing to render
            guiCamera.RemoveCommandBuffer(CameraEvent.AfterEverything, commandBuffer);
            commandBuffer = null;
        }

        textures.Clear();
        last_end = stopwatch.Elapsed.TotalSeconds;
    }
Esempio n. 30
0
        unsafe void RenderImDrawData(ImDrawDataPtr draw_data, RenderState rstate)
        {
            var io = ImGui.GetIO();
            //Set cursor
            var cur = ImGuiNative.igGetMouseCursor();

            switch (cur)
            {
            case ImGuiMouseCursor.Arrow:
                game.CursorKind = CursorKind.Arrow;
                break;

            case ImGuiMouseCursor.ResizeAll:
                game.CursorKind = CursorKind.Move;
                break;

            case ImGuiMouseCursor.TextInput:
                game.CursorKind = CursorKind.TextInput;
                break;

            case ImGuiMouseCursor.ResizeNS:
                game.CursorKind = CursorKind.ResizeNS;
                break;

            case ImGuiMouseCursor.ResizeNESW:
                game.CursorKind = CursorKind.ResizeNESW;
                break;

            case ImGuiMouseCursor.ResizeNWSE:
                game.CursorKind = CursorKind.ResizeNWSE;
                break;
            }
            //Render
            draw_data.ScaleClipRects(io.DisplayFramebufferScale);

            var    mat        = Matrix4.CreateOrthographicOffCenter(0, game.Width, game.Height, 0, 0, 1);
            Shader lastShader = textShader;

            textShader.SetMatrix(textShader.GetLocation("modelviewproj"), ref mat);
            textShader.SetInteger(textShader.GetLocation("tex"), 0);
            colorShader.SetMatrix(textShader.GetLocation("modelviewproj"), ref mat);
            colorShader.SetInteger(textShader.GetLocation("tex"), 0);
            textShader.UseProgram();
            rstate.Cull         = false;
            rstate.BlendMode    = BlendMode.Normal;
            rstate.DepthEnabled = false;
            for (int n = 0; n < draw_data.CmdListsCount; n++)
            {
                var     cmd_list   = draw_data.CmdListsRange[n];
                byte *  vtx_buffer = (byte *)cmd_list.VtxBuffer.Data;
                ushort *idx_buffer = (ushort *)cmd_list.IdxBuffer.Data;
                var     vtxCount   = cmd_list.VtxBuffer.Size;
                var     idxCount   = cmd_list.IdxBuffer.Size;
                if (vboSize < vtxCount || iboSize < idxCount)
                {
                    if (vbo != null)
                    {
                        vbo.Dispose();
                    }
                    if (ibo != null)
                    {
                        ibo.Dispose();
                    }
                    vboSize = Math.Max(vboSize, vtxCount);
                    iboSize = Math.Max(iboSize, idxCount);
                    vbo     = new VertexBuffer(typeof(Vertex2D), vboSize, true);
                    ibo     = new ElementBuffer(iboSize, true);
                    vbo.SetElementBuffer(ibo);
                    vbuffer = new Vertex2D[vboSize];
                    ibuffer = new ushort[iboSize];
                }
                for (int i = 0; i < cmd_list.IdxBuffer.Size; i++)
                {
                    ibuffer[i] = idx_buffer[i];
                }
                for (int i = 0; i < cmd_list.VtxBuffer.Size; i++)
                {
                    var ptr   = (ImDrawVert *)vtx_buffer;
                    var unint = ptr[i].col;
                    var a     = unint >> 24 & 0xFF;
                    var b     = unint >> 16 & 0xFF;
                    var g     = unint >> 8 & 0xFF;
                    var r     = unint & 0xFF;
                    vbuffer[i] = new Vertex2D(ptr[i].pos, ptr[i].uv, new Color4(r / 255f, g / 255f, b / 255f, a / 255f));
                }
                vbo.SetData(vbuffer, cmd_list.VtxBuffer.Size);
                ibo.SetData(ibuffer, cmd_list.IdxBuffer.Size);
                int startIndex = 0;
                for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++)
                {
                    var pcmd = cmd_list.CmdBuffer[cmd_i];
                    //TODO: Do something with pcmd->UserCallback ??
                    var       tid = pcmd.TextureId.ToInt32();
                    Texture2D tex;
                    if (tid == FONT_TEXTURE_ID)
                    {
                        if (lastShader != textShader)
                        {
                            textShader.UseProgram();
                            lastShader = textShader;
                        }
                        fontTexture.BindTo(0);
                    }
                    else if (textures.TryGetValue(tid, out tex))
                    {
                        if (lastShader != colorShader)
                        {
                            colorShader.UseProgram();
                            lastShader = colorShader;
                        }
                        tex.BindTo(0);
                    }
                    else
                    {
                        dot.BindTo(0);
                    }

                    GL.Enable(GL.GL_SCISSOR_TEST);
                    GL.Scissor(
                        (int)pcmd.ClipRect.X,
                        (int)(io.DisplaySize.Y - pcmd.ClipRect.W),
                        (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X),
                        (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y));
                    vbo.Draw(PrimitiveTypes.TriangleList, 0, startIndex, (int)pcmd.ElemCount / 3);
                    GL.Disable(GL.GL_SCISSOR_TEST);
                    startIndex += (int)pcmd.ElemCount;
                }
            }
        }