예제 #1
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;
    }