Esempio n. 1
0
    public void UpdateMesh(ImDrawCmd cmd, ImVector_ushort idxBuffer, ImVector_ImDrawVert vtxBuffer, int startIndex)
    {
        mesh.Clear();

        // recreate arrays only if too small
        if (vertices.Length < vtxBuffer.Size)
        {
            vertices = new Vector3[vtxBuffer.Size];
            uv       = new Vector2[vtxBuffer.Size];
            colors   = new Color32[vtxBuffer.Size];
        }

        // Unity can't hoist Screen.height fetch from the loop
        // Fine, we'll do it ourselves
        int screenHeight = Screen.height;

        // populate mesh from draw data
        for (int i = 0; i < vtxBuffer.Size; i++)
        {
            ImDrawVert vertex = vtxBuffer[i];
            vertices[i].x = vertex.pos.x;
            vertices[i].y = screenHeight - vertex.pos.y;
            vertices[i].z = 0.0f;
            uv[i].x       = vertex.uv.x;
            uv[i].y       = vertex.uv.y;
            colors[i].a   = (byte)((vertex.col >> 24) & 255);
            colors[i].b   = (byte)((vertex.col >> 16) & 255);
            colors[i].g   = (byte)((vertex.col >> 8) & 255);
            colors[i].r   = (byte)((vertex.col) & 255);
        }

        if (triangles.Length != cmd.ElemCount)
        {
            triangles = new int[cmd.ElemCount];
        }
        for (int i = 0; i < cmd.ElemCount; i++)
        {
            triangles[i] = idxBuffer[i + startIndex];
        }

        mesh.vertices  = vertices;
        mesh.uv        = uv;
        mesh.colors32  = colors;
        mesh.triangles = triangles;
    }
Esempio n. 2
0
        public static void RenderDrawData(ImDrawData 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)
            ImGuiIO io = ImGui.GetIO();

            ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale);

            // 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++)
            {
                ImDrawList            cmdList   = drawData[n];
                ImVector <ImDrawVert> vtxBuffer = cmdList.VtxBuffer;
                ImVector <ushort>     idxBuffer = cmdList.IdxBuffer;

                GL.VertexPointer(2, GL.Enum.GL_FLOAT, ImDrawVert.Size, new IntPtr((long)vtxBuffer.Data + ImDrawVert.PosOffset));
                GL.TexCoordPointer(2, GL.Enum.GL_FLOAT, ImDrawVert.Size, new IntPtr((long)vtxBuffer.Data + ImDrawVert.UVOffset));
                GL.ColorPointer(4, GL.Enum.GL_UNSIGNED_BYTE, ImDrawVert.Size, new IntPtr((long)vtxBuffer.Data + ImDrawVert.ColOffset));

                long idxBufferOffset = 0;
                for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                {
                    ImDrawCmd pcmd = cmdList.CmdBuffer[cmdi];
                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        pcmd.InvokeUserCallback(ref cmdList, ref pcmd);
                    }
                    else
                    {
                        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));
                    }
                    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);
        }
Esempio n. 3
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. 4
0
        public void RenderDrawData(ImDrawData drawData)
        {
            GraphicsDevice device = Game.GraphicsDevice;

            // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
            Viewport  lastViewport   = device.Viewport;
            Rectangle lastScissorBox = device.ScissorRectangle;

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

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

            ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale);

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

            if (Effect == null)
            {
                Effect = new BasicEffect(device);
            }
            Effect effect = Effect;

            SetupEffect(this, effect);

            // Render command lists
            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                ImDrawList cmdList = drawData[n];

                ImVector <ImDrawVertXNA> vtxBuffer;
                unsafe
                {
                    vtxBuffer = new ImVector <ImDrawVertXNA>(cmdList.VtxBuffer.Native);
                }
                ImDrawVertXNA[] vtxArray = new ImDrawVertXNA[vtxBuffer.Size];
                for (int i = 0; i < vtxBuffer.Size; i++)
                {
                    vtxArray[i] = vtxBuffer[i];
                }

                ImVector <short> idxBuffer;
                unsafe
                {
                    idxBuffer = new ImVector <short>(cmdList.IdxBuffer.Native);
                }

                /*
                 * short[] idxArray = new short[idxBuffer.Size];
                 * for (int i = 0; i < idxBuffer.Size; i++)
                 *  idxArray[i] = idxBuffer[i];
                 */

                uint offset = 0;
                for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
                {
                    ImDrawCmd pcmd = cmdList.CmdBuffer[cmdi];
                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        pcmd.InvokeUserCallback(ref cmdList, ref pcmd);
                    }
                    else
                    {
                        // Instead of uploading the complete idxBuffer again and again, just upload what's required.
                        short[] idxArray = new short[pcmd.ElemCount];
                        for (int i = 0; i < pcmd.ElemCount; i++)
                        {
                            idxArray[i] = idxBuffer[(int)offset + i];
                        }
                        SetEffectTexture(this, effect, GetTexture((int)pcmd.TextureId));
                        device.ScissorRectangle = new Rectangle(
                            (int)pcmd.ClipRect.X,
                            (int)pcmd.ClipRect.Y,
                            (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X),
                            (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y)
                            );
                        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                        {
                            pass.Apply();
                            device.DrawUserIndexedPrimitives(
                                PrimitiveType.TriangleList,
                                vtxArray, 0, vtxBuffer.Size,
                                idxArray, 0, (int)pcmd.ElemCount / 3,
                                ImDrawVertXNA._VertexDeclaration
                                );
                        }
                    }
                    offset += pcmd.ElemCount;
                }
            }

            // Restore modified state
            device.Viewport         = lastViewport;
            device.ScissorRectangle = lastScissorBox;
        }