美文网首页
从零开发游戏引擎系列(七)窗口

从零开发游戏引擎系列(七)窗口

作者: zaintan | 来源:发表于2021-02-24 10:41 被阅读0次

    该系列教程源自youtube的cherno的视频-GAME ENGINE series!

    视频地址: https://www.youtube.com/watch?v=vtWdgtMo1T4

    引擎源代码地址: https://github.com/TheCherno/Hazel

    将使用第三方库glfw: https://github.com/glfw/glfw

    当前cmd目录下E:\GitResp\GameEngine\Hazel 执行

    git submodule add https://github.com/glfw/glfw Hazel/vendor/glfw
    

    premake5.lua 中projectHazel增加链接库配置

        links
        {
            "glfw",
            "opengl32.lib"
        }
    

    includedirs增加glfw的头文件包含路径

        includedirs
        {
            "%{prj.name}/src",
            "%{prj.name}/vendor/spdlog/include"
            "%{prj.name}/vendor/glfw/include"
        }
    

    新增配置工程Hazel/vendor/glfw/premake5.lua

    project "glfw"
        kind "StaticLib"
        language "C"
    
        targetdir ("bin/" .. outputdir .. "/%{prj.name}")
        objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
    
        files
        {
            "include/GLFW/glfw3.h",
            "include/GLFW/glfw3native.h",
            "src/glfw_config.h",
            "src/context.c",
            "src/init.c",
            "src/input.c",
            "src/monitor.c",
            "src/vulkan.c",
            "src/window.c"
        }
        filter "system:linux"
            pic "On"
    
            systemversion "latest"
            staticruntime "On"
    
            files
            {
                "src/x11_init.c",
                "src/x11_monitor.c",
                "src/x11_window.c",
                "src/xkb_unicode.c",
                "src/posix_time.c",
                "src/posix_thread.c",
                "src/glx_context.c",
                "src/egl_context.c",
                "src/osmesa_context.c",
                "src/linux_joystick.c"
            }
    
            defines
            {
                "_GLFW_X11"
            }
    
        filter "system:windows"
            systemversion "latest"
            staticruntime "On"
    
            files
            {
                "src/win32_init.c",
                "src/win32_joystick.c",
                "src/win32_monitor.c",
                "src/win32_time.c",
                "src/win32_thread.c",
                "src/win32_window.c",
                "src/wgl_context.c",
                "src/egl_context.c",
                "src/osmesa_context.c"
            }
    
            defines 
            { 
                "_GLFW_WIN32",
                "_CRT_SECURE_NO_WARNINGS"
            }
    
        filter "configurations:Debug"
            runtime "Debug"
            symbols "on"
    
        filter "configurations:Release"
            runtime "Release"
            optimize "on"
    

    Hazel/src/hzpch.h 增加

    #include "Hazel/Log.h"
    

    Hazel/src/Hazel/Core.h 增加 自定义assert宏

    #ifdef HZ_ENABLE_ASSERTS
        #define HZ_ASSERT(x, ...) { if(!(x)) { HZ_ERROR("Assertion Failed: {0}", __VA_ARGS__); __debugbreak(); } }
        #define HZ_CORE_ASSERT(x, ...) { if(!(x)) { HZ_CORE_ERROR("Assertion Failed: {0}", __VA_ARGS__); __debugbreak(); } }
    #else
        #define HZ_ASSERT(x, ...)
        #define HZ_CORE_ASSERT(x, ...)
    #endif
    

    新增文件Hazel/src/Hazel/Window.h,定义了抽象窗口基类

    #pragma once
    
    #include "hzpch.h"
    
    #include "Hazel/Core.h"
    #include "Hazel/Events/Event.h"
    
    namespace Hazel {
    
        struct WindowProps//窗口属性
        {
            std::string Title;
            unsigned int Width;
            unsigned int Height;
    
            WindowProps(const std::string& title = "Hazel Engine",
                        unsigned int width = 1280,
                        unsigned int height = 720)
                : Title(title), Width(width), Height(height)
            {
            }
        };
    
        // Interface representing a desktop system based Window
        class HAZEL_API Window //窗口抽象类
        {
        public:
            using EventCallbackFn = std::function<void(Event&)>;
    
            virtual ~Window() {}
    
            virtual void OnUpdate() = 0;//每一帧调用
    
            virtual unsigned int GetWidth() const = 0;
            virtual unsigned int GetHeight() const = 0;
    
            // Window attributes
            virtual void SetEventCallback(const EventCallbackFn& callback) = 0;//设置窗口事件回调,平台触发
            virtual void SetVSync(bool enabled) = 0;
            virtual bool IsVSync() const = 0;
    
            static Window* Create(const WindowProps& props = WindowProps());
        };
    
    }
    

    实现windows平台的窗口类:
    Hazel/src/Platform/Windows/WindowsWindow.h

    #pragma once
    
    #include "Hazel/Window.h"
    
    #include <GLFW/glfw3.h>
    
    namespace Hazel {
    
        class WindowsWindow : public Window
        {
        public:
            WindowsWindow(const WindowProps& props);
            virtual ~WindowsWindow();
    
            void OnUpdate() override;
    
            inline unsigned int GetWidth() const override { return m_Data.Width; }
            inline unsigned int GetHeight() const override { return m_Data.Height; }
    
            // Window attributes
            inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
            void SetVSync(bool enabled) override;
            bool IsVSync() const override;
        private:
            virtual void Init(const WindowProps& props);
            virtual void Shutdown();
        private:
            GLFWwindow* m_Window;
    
            struct WindowData
            {
                std::string Title;
                unsigned int Width, Height;
                bool VSync;
    
                EventCallbackFn EventCallback;
            };
    
            WindowData m_Data;
        };
    
    } 
    

    Hazel/src/Platform/Windows/WindowsWindow.cpp

    #include "hzpch.h"
    #include "WindowsWindow.h"
    
    namespace Hazel {
    
        static bool s_GLFWInitialized = false;
    
        Window* Window::Create(const WindowProps& props)
        {
            return new WindowsWindow(props);
        }
    
        WindowsWindow::WindowsWindow(const WindowProps& props)
        {
            Init(props);
        }
    
        WindowsWindow::~WindowsWindow()
        {
            Shutdown();
        }
    
        void WindowsWindow::Init(const WindowProps& props)
        {
            m_Data.Title = props.Title;
            m_Data.Width = props.Width;
            m_Data.Height = props.Height;
    
            HZ_CORE_INFO("Creating window {0} ({1}, {2})", props.Title, props.Width, props.Height);
    
            if (!s_GLFWInitialized)
            {
                // TODO: glfwTerminate on system shutdown
                int success = glfwInit();
                HZ_CORE_ASSERT(success, "Could not intialize GLFW!");
    
                s_GLFWInitialized = true;
            }
    
            m_Window = glfwCreateWindow((int)props.Width, (int)props.Height, m_Data.Title.c_str(), nullptr, nullptr);
            glfwMakeContextCurrent(m_Window);
            glfwSetWindowUserPointer(m_Window, &m_Data);
            SetVSync(true);
        }
    
        void WindowsWindow::Shutdown()
        {
            glfwDestroyWindow(m_Window);
        }
    
        void WindowsWindow::OnUpdate()
        {
            glfwPollEvents();
            glfwSwapBuffers(m_Window);
        }
    
        void WindowsWindow::SetVSync(bool enabled)
        {
            if (enabled)
                glfwSwapInterval(1);
            else
                glfwSwapInterval(0);
    
            m_Data.VSync = enabled;
        }
    
        bool WindowsWindow::IsVSync() const
        {
            return m_Data.VSync;
        }
    
    }
    

    在Application类中 创建窗口,分发事件:
    Hazel/src/Hazel/Application.h

    #include "Window.h"
    
        ...
    
        private:
            std::unique_ptr<Window> m_Window;
            bool m_Running = true;
    
    

    Hazel/src/Hazel/Application.cpp

    #include <GLFW/glfw3.h>
        ...
        Application::Application()
        {
            m_Window = std::unique_ptr<Window>(Window::Create());
        }
        ...
    
        void Application::Run()
        {
    
            while (m_Running)
            {
                glClearColor(1, 0, 1, 1);
                glClear(GL_COLOR_BUFFER_BIT);
                m_Window->OnUpdate();
            }
        }
    
    

    相关文章

      网友评论

          本文标题:从零开发游戏引擎系列(七)窗口

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