美文网首页
Dragon Engine:GUI

Dragon Engine:GUI

作者: Dragon_boy | 来源:发表于2020-08-15 16:09 被阅读0次

这一节介绍GUI的实现。我们这里使用开源库ImGui

首先我们将GUI分离为一个单独的层,创建ImGuiLayer:
ImGuiLayer.h:

#pragma once

#include "Dragon/Core/Layer.h"

#include "Dragon/Events/ApplicationEvent.h"
#include "Dragon/Events/KeyEvents.h"
#include "Dragon/Events/MouseEvent.h"

namespace Dragon
{
    class ImGuiLayer : public Layer
    {
    public:
        ImGuiLayer();
        ~ImGuiLayer() = default;

        virtual void OnAttach() override;
        virtual void OnDetach() override;
        virtual void OnImGuiRender() override;
        //virtual void OnEvent(Event& e) override;

        void Begin();
        void End();
    private:
        float m_Time = 0.0f;
    };
}

函数先不介绍,直接看实现:

namespace Dragon
{
    ImGuiLayer::ImGuiLayer()
        :Layer("ImGuiLayer")
    {

    }

    void ImGuiLayer::OnAttach()
    {
        // Setup Dear ImGui context
        IMGUI_CHECKVERSION();
        ImGui::CreateContext();
        ImGuiIO& io = ImGui::GetIO(); (void)io;
        io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;       // Enable Keyboard Controls
        //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
        io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;           // Enable Docking
        io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;         // Enable Multi-Viewport / Platform Windows
        //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;
        //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;

        //// Setup Dear ImGui style
        ImGui::StyleColorsDark();
        ////ImGui::StyleColorsClassic();

        //// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
        ImGuiStyle& style = ImGui::GetStyle();
        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
        {
            style.WindowRounding = 0.0f;
            style.Colors[ImGuiCol_WindowBg].w = 1.0f;
        }

        Application& app = Application::Get();
        GLFWwindow* window = static_cast<GLFWwindow*>(app.GetWindow().GetNativeWindow());

        // Setup Platform/Renderer bindings
        ImGui_ImplGlfw_InitForOpenGL(window, true);
        ImGui_ImplOpenGL3_Init("#version 410");
    }

    void ImGuiLayer::OnDetach()
    {
        ImGui_ImplOpenGL3_Shutdown();
        ImGui_ImplGlfw_Shutdown();
        ImGui::DestroyContext();
    }

    void ImGuiLayer::Begin()
    {
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();
    }

    void ImGuiLayer::End()
    {
        ImGuiIO& io = ImGui::GetIO();
        Application& app = Application::Get();
        io.DisplaySize = ImVec2((float)app.GetWindow().GetWidth(), (float)app.GetWindow().GetHeight());

        // Rendering
        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
        {
            GLFWwindow* backup_current_context = glfwGetCurrentContext();
            ImGui::UpdatePlatformWindows();
            ImGui::RenderPlatformWindowsDefault();
            glfwMakeContextCurrent(backup_current_context);
        }
    }

    void ImGuiLayer::OnImGuiRender()
    {
        /*static bool show = true;
        ImGui::ShowDemoWindow(&show);*/
    }

}

OnAttach()函数初始化ImGui,创建上下文,然后获取输入输出io,并设置io的标识,设置按键标识,Docking标识(即GUI窗口可以相互内嵌),视口标识(和OpenGL视口配套)。ImGui::StyleColorsDark()设置样式,默认有三种可选。然后获取样式,设置GUI窗口的背景以及圆角。ImGui_ImplGlfw_InitForOpenGL是ImGui为GLFW提供的一个方法,可以传入一个GLFW窗口指针,然后配置好所需的参数,ImGui_ImplOpenGL3_Init是ImGui为OpenGL提供的一个方法,可以为某一版本的OpenGL配置好所需的参数。

OnDetach()函数没什么好说的。

Begin()函数调用了三个NewFrame方法,这是必须的,相当于新建窗口的意思。

OnImGuiRender()函数是所绘制的GUI,大家可以把注释取消渲染一下ImGui自带的demo窗口看一下,里面提供了许多示例。

End()函数主要是渲染GUI数据,并更新,这是示例中的代码。

重点是OnImGuiRender()函数,它定义在Layer类中,这样我们可以在客户端类中定义同名函数来设置GUI,比如:

virtual void OnImGuiRender() override
    {
        ImGui::Begin("Inspector");
        if(m_GameObjectsName.size()!=0)
            GameObjectGui(m_GameObjectsName[m_GameObjectsItem]);
        ImGui::NewLine();
        ImGui::Text("Shader List");
        
        const char** shaderList = StringToChar(m_ShaderList);
        ImGui::Combo("", &m_ShaderListItem, shaderList, m_ShaderList.size());
        ShaderGui(m_ShaderList[m_ShaderListItem]);

        ImGui::NewLine();
        ImGui::Text("Post Effect");
        ImGui::Checkbox("Opposition", &m_Opposition);
        if (m_Opposition)
        {
            ImGui::SameLine();
            ImGui::SliderFloat("Opposition Weight", &m_OppositionWeight, 0.0f, 1.0f);
        }
        ImGui::Checkbox("Gray", &m_Gray);
        if (m_Gray)
        {
            ImGui::SameLine();
            ImGui::SliderFloat("Gray Weight", &m_GrayWeight, 0.0f, 1.0f);
        }
        ImGui::Checkbox("Kernel", &m_Kernel);
        if (m_Kernel)
        {
            ImGui::SameLine();
            ImGui::SliderFloat("Kernel Weight", &m_KernelWeight, 0.0f, 1.0);
        }
        ImGui::Checkbox("Blur", &m_Blur);
        if (m_Blur)
        {
            ImGui::SameLine();
            ImGui::SliderFloat("Blur Weight", &m_BlurWeight, 0.0f, 1.0f);
        }
        ImGui::Checkbox("Edge Detection", &m_EdgeDetection);
        if (m_EdgeDetection)
        {
            ImGui::SameLine();
            ImGui::SliderFloat("Edge Detection Weight", &m_EdgeDetectionWeight, 0.0f, 1.0f);
        }


        ImGui::End();

        ImGui::Begin("Game Object");
        ImGui::Text("Geometry");
        m_CubeButtonClicked = ImGui::Button("Cube");
        ImGui::SameLine();
        ImGui::Button("Sphere");
        ImGui::SameLine();
        ImGui::Button("Quad");
        ImGui::Button("Import Model");
        ImGui::NewLine();
        ImGui::Text("Light Source");
        ImGui::Button("Point Light");
        ImGui::SameLine();
        ImGui::Button("Directional Light");
        ImGui::SameLine();
        ImGui::Button("Spot Light");
        ImGui::SameLine();
        ImGui::Button("Area Light");
        ImGui::Button("Sky Box");
        ImGui::NewLine();
        ImGui::Button("Orthographic Camera");
        ImGui::SameLine();
        ImGui::Button("Perspective Camera");
        ImGui::End();

        ImGui::Begin("Outline View");
        const char** GameObjectList = StringToChar(m_GameObjectsName);
        ImGui::ListBox("", &m_GameObjectsItem, GameObjectList, m_GameObjectsName.size(), m_GameObjectsName.size());
        ImGui::End();
    }

这些组件函数可以从ImGui的文档里看到用法,都是GUI的那一套,这是我的GUI效果:


目前可以点击创建一些内置几何体,并调整TRS以及赋予shader,调整相关参数。

下一节介绍预编译模块(使用CMake或Premake),来方便整理外部模块,方便别人能够使用你的程序。

项目github地址:https://github.com/Dragon-Baby/Dragon

相关文章

  • Dragon Engine:GUI

    这一节介绍GUI的实现。我们这里使用开源库ImGui。 首先我们将GUI分离为一个单独的层,创建ImGuiLaye...

  • Dragon Engine:Debug

    本文同时发布在我的个人博客上:https://dragon_boy.gitee.io Debug,或者说日志系统,...

  • Dragon Engine:窗口

    本节介绍窗口的实现。这里使用开源库GLFW,之前也介绍过,只不过这里的主要任务就是将GLFW的API抽象出来,方便...

  • Dragon Engine:层

    本文同时发布在我的个人博客上:https://dragon_boy.gitee.io/ 层的概念在许多软件中都存在...

  • Dragon Engine:事件系统

    本文同时发布在我的个人博客上:https://dragon_boy.gitee.io 事件系统的范围很广,这里我暂...

  • Dragon Engine:编译项目

    编写大项目的时候,大部分文件可以复用,但构建项目的软件,使用的平台,可使用的外部资源因各种各不相同,所以大部分时候...

  • Dragon Engine:材质系统

    这一节介绍材质系统,主要是进行着色器类的抽象: 这里设计了两个类,一个着色器类,一个着色器库类。着色器类的成员函数...

  • Dragon Engine:纹理模块

    这一节介绍纹理模块的实现。首先是纹理类的抽象: 纹理基类的构造不用多说,这里衍生出了两个纹理类,2D和立方体贴图。...

  • Dragon Engine:帧缓冲

    之前相关的图形学文章介绍过,帧缓冲非常有用,可以用来实现Post-Processing效果,以及阴影效果等,在进行...

  • Dragon Engine:基础渲染架构

    本节的目的是在已有的基础上构建出一个基础渲染架构。主要任务就是抽象。 一个简单的渲染架构包含很多模块,我之前发了许...

网友评论

      本文标题:Dragon Engine:GUI

      本文链接:https://www.haomeiwen.com/subject/pweadktx.html