Ejemplo n.º 1
0
 /// <summary>
 /// Set rendering states used to draw primitives.
 /// </summary>
 /// <param name="state">The set of states to set.</param>
 /// <param name="colorRgba">The color used for "factor" blending modes.</param>
 public static void SetRenderState(RenderState state, int colorRgba)
 {
     NativeMethods.bgfx_set_state((ulong)state, colorRgba);
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Set rendering states used to draw primitives.
 /// </summary>
 /// <param name="state">The set of states to set.</param>
 public static void SetRenderState(RenderState state)
 {
     NativeMethods.bgfx_set_state((ulong)state, 0);
 }
Ejemplo n.º 3
0
        private void BgfxRender(ImDrawDataPtr drawData)
        {
            var io = ImGui.GetIO();

            var width  = io.DisplaySize.X;
            var height = io.DisplaySize.Y;

            Bgfx.SetViewName(_bgfxId, "ImGui");
            Bgfx.SetViewMode(_bgfxId, ViewMode.Sequential);

            // Bgfx implementation now gets the capabilities and creates a orthogonal matrix with bx. Bx is not wrapped, so I just create a identity matrix.
            // Works as intended on my side.
            // Bgfx Cpp:
            //

            /*const bgfx::Caps* caps = bgfx::getCaps();
             * {
             *      float ortho[16];
             *      bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, 0.0f, 1000.0f, 0.0f, caps->homogeneousDepth);
             *      bgfx::setViewTransform(m_viewId, NULL, ortho);
             *      bgfx::setViewRect(m_viewId, 0, 0, uint16_t(width), uint16_t(height));
             * }*/

            unsafe
            {
                var identityMatrix = Matrix4x4.Identity;
                Bgfx.SetViewTransform(_bgfxId, null, &identityMatrix.M11);
            }

            Bgfx.SetViewRect(_bgfxId, 0, 0, (int)width, (int)height);

            for (var ii = 0; ii < drawData.CmdListsCount; ++ii)
            {
                TransientVertexBuffer tvb;
                TransientIndexBuffer  tib;

                var drawList    = drawData.CmdListsRange[ii];
                var numVertices = drawList.VtxBuffer.Size;
                var numIndices  = drawList.IdxBuffer.Size;

                // Bgfx now checks if the transient buffer has enough space to draw the rest.
                // The Method uses bgfx::getAvailTransientVertexBuffer and bgfx::getAvailTransientVertexBuffer, which are not wrapped?
                // So I just skip the test.

                Bgfx.AllocateTransientBuffers(numVertices, _vertexLayout, numIndices, out tvb, out tib);

                unsafe
                {
                    var vertices = tvb.Data;
                    Buffer.MemoryCopy(drawList.VtxBuffer.Data.ToPointer(), vertices.ToPointer(),
                                      numVertices * sizeof(ImDrawVert), numVertices * sizeof(ImDrawVert));

                    var indices = tib.Data;
                    Buffer.MemoryCopy(drawList.IdxBuffer.Data.ToPointer(), indices.ToPointer(),
                                      numIndices * sizeof(ushort), numIndices * sizeof(ushort));
                }

                var offset = 0;
                for (var cmdIndex = 0; cmdIndex < drawList.CmdBuffer.Size; cmdIndex++)
                {
                    var cmd = drawList.CmdBuffer[cmdIndex];

                    if (cmd.UserCallback != IntPtr.Zero)
                    {
                        //cmd->UserCallback(drawList, cmd);
                        // I have no idea how to do the above in C#.
                        throw new NotImplementedException();
                    }
                    else if (0 != cmd.ElemCount)
                    {
                        var state = 0
                                    | RenderState.WriteRGB
                                    | RenderState.WriteA
                                    | RenderState.Multisampling
                        ;

                        var th      = FontAtlas;
                        var program = _imguiProgram;

                        // Check if the TextureId is not the one of the FontAtlas
                        // Short: We give imgui a IntPtr to identify the texture. In c++ we can give the pointer to the texture,
                        // but I've dont't know if thats possible to do in c#.
                        // My solution: Cast the hashcode of the texture to a IntPtr and use it as an identifier and store the IntPtrs and the Textures in a dictionary.
                        // See imgui textureID/texId for more information.
                        if (cmd.TextureId != (IntPtr)FontAtlas.GetHashCode())
                        {
                            // Bgfx sets the state dependent on the texture flags. Getting these flags is not implemented?, so I ignore the check.
                            state |= RenderState.BlendFunction(RenderState.BlendSourceAlpha,
                                                               RenderState.BlendInverseSourceAlpha);

                            th = _textures[cmd.TextureId];
                            if (0 != th.MipLevels)
                            {
                                float[] lodEnabled      = { 1.0f, 0.0f, 0.0f, 0.0f };
                                var     imageLodEnabled = new Uniform("u_params", UniformType.Vector4);
                                unsafe
                                {
                                    fixed(void *lodEnabledPtr = lodEnabled)
                                    {
                                        Bgfx.SetUniform(imageLodEnabled, lodEnabledPtr);
                                    }
                                }
                                // If I use the texture shader from bgfx, the images aren't drawn
                                //program = _textureProgram;
                            }
                        }
                        else
                        {
                            state |= RenderState.BlendFunction(RenderState.BlendSourceAlpha,
                                                               RenderState.BlendInverseSourceAlpha);
                        }

                        // I've splitted the declaration and the usage, so it's clearer
                        var x = (int)Math.Max(cmd.ClipRect.X, 0.0f);
                        var y = (int)Math.Max(cmd.ClipRect.Y, 0.0f);
                        var z = (int)Math.Min(cmd.ClipRect.Z, 65535.0f);
                        var w = (int)Math.Min(cmd.ClipRect.W, 65535.0f);
                        Bgfx.SetScissor(x, y, z - x, w - y);

                        Bgfx.SetRenderState(state);
                        Bgfx.SetTexture(0, _texUniform, th);
                        Bgfx.SetVertexBuffer(0, tvb, 0, numVertices);
                        Bgfx.SetIndexBuffer(tib, offset, (int)cmd.ElemCount);
                        Bgfx.Submit(_bgfxId, program);
                    }

                    offset += (int)cmd.ElemCount;
                }
            }
        }