From a00d3bba0658f5502d452bdb84dd65bc779d3d42 Mon Sep 17 00:00:00 2001 From: ouczbs Date: Sat, 6 Jul 2024 18:04:51 +0800 Subject: [PATCH] support opengl --- .gitignore | 1 + engine/3rdparty/xmake.lua | 2 +- engine/3rdparty/zlib/include/refl/macro.h | 5 ++ engine/3rdparty/zlib/test/yaml/guid.h | 1 - engine/src/engine/app.cpp | 6 +- engine/src/engine/app.h | 2 +- .../openglapi/loader/opengl_glsl_loader.cpp | 1 + engine/src/engine/openglapi/openglapi.cpp | 61 ++++++++++++++++++- engine/src/engine/openglapi/openglapi.h | 12 +++- engine/src/engine/openglapi/window.cpp | 4 -- engine/src/engine/render/asset/vertex.h | 4 ++ engine/src/engine/render/renderapi.h | 1 + engine/src/engine/render/window.cpp | 22 +++++-- engine/src/engine/render/window.h | 2 + engine/src/engine/vulkanapi/vulkanapi.cpp | 4 ++ engine/src/engine/vulkanapi/vulkanapi.h | 1 + engine/src/main.cpp | 3 +- engine/xmake.lua | 2 +- engine/xmake/gen/meta_refl.lua | 5 ++ 19 files changed, 119 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 0f28dcb..f8cffef 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ vsxmake*/ engine/logs/zengine.log tools/ +cpp_input.h diff --git a/engine/3rdparty/xmake.lua b/engine/3rdparty/xmake.lua index f8008b6..eb80a33 100644 --- a/engine/3rdparty/xmake.lua +++ b/engine/3rdparty/xmake.lua @@ -8,4 +8,4 @@ local utils = { "spirv-cross-glsl","spirv-cross-cpp", "spirv-cross-core", "spirv-cross-reflect","spirv-cross-util" } add_requires("vulkansdk",{configs = {utils = utils}}) -add_requires("opengl", "opencl-headers") +add_requires("glew") diff --git a/engine/3rdparty/zlib/include/refl/macro.h b/engine/3rdparty/zlib/include/refl/macro.h index f62a2f1..e5939a9 100644 --- a/engine/3rdparty/zlib/include/refl/macro.h +++ b/engine/3rdparty/zlib/include/refl/macro.h @@ -19,6 +19,10 @@ namespace engineapi { #define UPROPERTY_dx(...) __dxMeta(__VA_ARGS__) #define UFUNCTION_dx(...) __dxMeta(__VA_ARGS__) +#define __glMeta(...) __cppast(glMeta=__VA_ARGS__) +#define UPROPERTY_gl(...) __glMeta(__VA_ARGS__) +#define UFUNCTION_gl(...) __glMeta(__VA_ARGS__) + // 辅助宏,用于实际拼接 #define CONCATENATE(arg1, arg2) CONCATENATE_IMPL(arg1, arg2) #define CONCATENATE_IMPL(arg1, arg2) arg1##arg2 @@ -46,4 +50,5 @@ namespace refl_impl { struct Meta {}; struct vkMeta {}; struct dxMeta {}; + struct glMeta {}; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/test/yaml/guid.h b/engine/3rdparty/zlib/test/yaml/guid.h index 95871b6..1f36686 100644 --- a/engine/3rdparty/zlib/test/yaml/guid.h +++ b/engine/3rdparty/zlib/test/yaml/guid.h @@ -6,7 +6,6 @@ using std::string; using std::vector; struct Guid { - using MyMeta = class Guid_Meta; UPROPERTY({1}) unsigned int Data1; UPROPERTY({}) diff --git a/engine/src/engine/app.cpp b/engine/src/engine/app.cpp index a019eb1..523c24d 100644 --- a/engine/src/engine/app.cpp +++ b/engine/src/engine/app.cpp @@ -38,13 +38,15 @@ namespace engineapi { system->Shutdown(); } } - void App::Launch() + int App::Launch() { Init(); - while (Loop) { + int code = 0; + while (Loop && Window::ProcessMessages(code)) { Update(); Render(); } + return code; } void App::Update() { diff --git a/engine/src/engine/app.h b/engine/src/engine/app.h index cf2bec3..0547198 100644 --- a/engine/src/engine/app.h +++ b/engine/src/engine/app.h @@ -16,7 +16,7 @@ namespace engineapi public: void Init(); void Shutdown(); - void Launch(); + int Launch(); void Update(); void Render(); }; diff --git a/engine/src/engine/openglapi/loader/opengl_glsl_loader.cpp b/engine/src/engine/openglapi/loader/opengl_glsl_loader.cpp index b454ce2..0a711f7 100644 --- a/engine/src/engine/openglapi/loader/opengl_glsl_loader.cpp +++ b/engine/src/engine/openglapi/loader/opengl_glsl_loader.cpp @@ -9,6 +9,7 @@ namespace openglapi { } ResourceBundle OpenGLGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta) { + return {}; } } diff --git a/engine/src/engine/openglapi/openglapi.cpp b/engine/src/engine/openglapi/openglapi.cpp index deeeec2..66f2b5e 100644 --- a/engine/src/engine/openglapi/openglapi.cpp +++ b/engine/src/engine/openglapi/openglapi.cpp @@ -1,17 +1,38 @@ #include "openglapi.h" #include "window.h" +#include "zlog.h" +#include "GL/glew.h" #include "loader/opengl_glsl_loader.h" +#include "render/asset/mesh.h" +struct glVertexMeta { + GLint size; + GLenum type; + GLboolean normalized; +}; +#include "glmeta_vertex_gen.inl" namespace openglapi { void RenderOpenGLApi::SwitchContext() { } void RenderOpenGLApi::Init() { + if (glewInit() != GLEW_OK) { + // 处理初始化错误 + zlog::error("GLEW Initialization failed!"); + } + RenderAPI::Init(); OpenGLGlslLoader::Init(); + window = OpenGLWindow::GetSingletonPtr(); } void RenderOpenGLApi::InitRenderPass() { } + void RenderOpenGLApi::OnWindowSizeChange(uint32_t width, uint32_t height) + { + // 设置视口和背景颜色 + glViewport(0, 0, width, height); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + } void RenderOpenGLApi::SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset) { mViewPortInfo.width = width; @@ -33,10 +54,48 @@ namespace openglapi { void RenderOpenGLApi::EndFrame() { glEnd(); - OpenGLWindow::GetSingletonPtr()->Present(); + window->Present(); } void RenderOpenGLApi::SetStaticMesh(Mesh& mesh) { + auto Indices = mesh.GetIndices(); + auto Vertices = mesh.GetVertices(); + unsigned int VBO, VAO, EBO; + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); + + // 绑定顶点数组对象 + glBindVertexArray(VAO); + + // 绑定顶点缓冲对象 + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, Vertices.size(), Vertices.data(), GL_STATIC_DRAW); + + // 绑定索引缓冲对象 + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, Indices.size(), Indices.data(), GL_STATIC_DRAW); + + auto meta = Vertices.uclass()->vtable.GetMeta("glMeta"); + { + uint32_t count = 0; + uint32_t size = meta->size; + for (auto& field : meta->GetFields(refl::FIND_ALL_MEMBER, FName(""))) { + // 设置顶点属性指针 + refl::Any field_meta = field.GetMeta(); + if (!field_meta) continue; + glVertexMeta v_meta = field_meta.CastTo(); + GLvoid* offset = reinterpret_cast(field.GetOffset()); + glEnableVertexAttribArray(count); + glVertexAttribPointer(count, v_meta.size, v_meta.type, v_meta.normalized, size, offset); + count++; + } + } + // 解绑VBO(不是EBO!) + glBindBuffer(GL_ARRAY_BUFFER, 0); + // 解绑VAO + glBindVertexArray(0); + VAOTable[mesh.GetGuid()] = VAO; } void RenderOpenGLApi::DrawStaticMesh(Mesh& mesh) { diff --git a/engine/src/engine/openglapi/openglapi.h b/engine/src/engine/openglapi/openglapi.h index 15bf900..42610ae 100644 --- a/engine/src/engine/openglapi/openglapi.h +++ b/engine/src/engine/openglapi/openglapi.h @@ -1,13 +1,22 @@ #pragma once #include "render/renderapi.h" +#include "zstd/table.h" #include "asset/render/asset_struct.h" -#include "gl/GL.h" namespace openglapi { using engineapi::RenderContext; using engineapi::Mesh; using engineapi::Shader; + using engineapi::Guid; + using zstd::hash_table; + class OpenGLWindow; + struct OpenGLVAO { + int VAO; + }; class RenderOpenGLApi : public engineapi::RenderAPI { + public: RenderContext context; + OpenGLWindow* window; + hash_table VAOTable; public: RenderContext* GetContext() override { return &context; @@ -18,6 +27,7 @@ namespace openglapi { void Init() override; void InitRenderPass()override; public: + void OnWindowSizeChange(uint32_t width, uint32_t height) override; void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override; void BeginFrame()override; diff --git a/engine/src/engine/openglapi/window.cpp b/engine/src/engine/openglapi/window.cpp index 3e187f4..341a6b4 100644 --- a/engine/src/engine/openglapi/window.cpp +++ b/engine/src/engine/openglapi/window.cpp @@ -1,5 +1,4 @@ #include "window.h" -#include namespace openglapi { void OpenGLWindow::SetupOpenGLContext() { @@ -36,9 +35,6 @@ namespace openglapi { :engineapi::Window(width, height, title) { SetupOpenGLContext(); - // 设置视口和背景颜色 - glViewport(0, 0, width, height); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } void OpenGLWindow::Present() { diff --git a/engine/src/engine/render/asset/vertex.h b/engine/src/engine/render/asset/vertex.h index 6b8ea6f..3565020 100644 --- a/engine/src/engine/render/asset/vertex.h +++ b/engine/src/engine/render/asset/vertex.h @@ -20,12 +20,16 @@ namespace engineapi { }; struct BoneVertex : public Vertex { + UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE }) UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT }) Vector3 Position = {}; + UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE }) UPROPERTY_vk() Vector2 TexCoords = {}; + UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE }) UPROPERTY_vk() Vector3 Normal = {}; + UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE }) UPROPERTY_vk() Vector3 Tangent = {}; // 骨骼蒙皮数据 diff --git a/engine/src/engine/render/renderapi.h b/engine/src/engine/render/renderapi.h index 045e020..bebe3b0 100644 --- a/engine/src/engine/render/renderapi.h +++ b/engine/src/engine/render/renderapi.h @@ -27,6 +27,7 @@ namespace engineapi public: virtual RenderContext* GetContext() = 0; public: + virtual void OnWindowSizeChange(uint32_t width, uint32_t height) = 0; virtual void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0) = 0; virtual void BeginFrame() = 0; virtual void Render(Camera& camera); diff --git a/engine/src/engine/render/window.cpp b/engine/src/engine/render/window.cpp index ffe21a3..1fda7ba 100644 --- a/engine/src/engine/render/window.cpp +++ b/engine/src/engine/render/window.cpp @@ -1,4 +1,5 @@ #include "window.h" +#include "renderapi.h" #include "data/engine_setting.h" #ifdef VULKAN_API #include "vulkanapi/window.h" @@ -51,12 +52,16 @@ namespace engineapi { AdjustWindowRectEx(&wr, dwStyle, FALSE, dwExStyle); mPtr = CreateWindow( WindowClass::GetName(), title, - WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, + WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, WindowClass::GetInstance(), this ); ShowWindow(mPtr, SW_SHOW); } + void Window::OnResize(uint32_t width, uint32_t height) + { + RenderAPI::GetSingletonPtr()->OnWindowSizeChange(width, height); + } bool Window::ProcessMessages(int& code) { MSG msg; @@ -68,14 +73,14 @@ namespace engineapi { { // return optional wrapping int (arg to PostQuitMessage is in wparam) signals quit code = (int)msg.wParam; - return true; + return false; } // TranslateMessage will post auxilliary WM_CHAR messages from key msgs TranslateMessage(&msg); DispatchMessage(&msg); } - return false; + return true; } LRESULT CALLBACK Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept { @@ -108,10 +113,15 @@ namespace engineapi { { switch (msg) { - // we don't want the DefProc to handle this message because - // we want our destructor to destroy the window, so return 0 instead of break + case WM_SIZE: + { + uint32_t width = LOWORD(lParam); + uint32_t height = HIWORD(lParam); + OnResize(width, height); + break; + } case WM_CLOSE: - PostQuitMessage(0); + PostQuitMessage(-1); return 0; // clear keystate when window loses focus to prevent input getting "stuck" /************** END MOUSE MESSAGES **************/ diff --git a/engine/src/engine/render/window.h b/engine/src/engine/render/window.h index 6e1510d..772a7c3 100644 --- a/engine/src/engine/render/window.h +++ b/engine/src/engine/render/window.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "singleton.h" namespace engineapi { class Window : public ISingleton { @@ -37,6 +38,7 @@ namespace engineapi { HWND Ptr() { return mPtr; } + void OnResize(uint32_t width, uint32_t height); void GetSize(uint32_t& width, uint32_t& height) { width = mWidth; height = mHeight; diff --git a/engine/src/engine/vulkanapi/vulkanapi.cpp b/engine/src/engine/vulkanapi/vulkanapi.cpp index c852731..39522ee 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.cpp +++ b/engine/src/engine/vulkanapi/vulkanapi.cpp @@ -48,6 +48,10 @@ namespace vulkanapi { PassList[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer, output); } } + } + void RenderVulkanAPI::OnWindowSizeChange(uint32_t width, uint32_t height) + { + } void RenderVulkanAPI::SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset) { diff --git a/engine/src/engine/vulkanapi/vulkanapi.h b/engine/src/engine/vulkanapi/vulkanapi.h index e4a1ef1..feae040 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.h +++ b/engine/src/engine/vulkanapi/vulkanapi.h @@ -33,6 +33,7 @@ namespace vulkanapi void Init() override; void InitRenderPass()override; public: + void OnWindowSizeChange(uint32_t width, uint32_t height) override; void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override; void BeginFrame()override; diff --git a/engine/src/main.cpp b/engine/src/main.cpp index 77ccd0f..2a6b716 100644 --- a/engine/src/main.cpp +++ b/engine/src/main.cpp @@ -7,6 +7,5 @@ int main(int argc, char** argv) { const char* name = "zengine"; App game(name); - game.Launch(); - return 0; + return game.Launch(); } diff --git a/engine/xmake.lua b/engine/xmake.lua index e441487..81c896e 100644 --- a/engine/xmake.lua +++ b/engine/xmake.lua @@ -14,7 +14,7 @@ target("zengine") add_deps("zlog","zlib") add_defines("VULKAN_API", "OPENGL_API") add_packages("vulkansdk","tinyobjloader","assimp","nlohmann_json") - add_packages("opencl", "opencl-headers") + add_packages("glew") add_includedirs("src/engine") add_includedirs("src/3rdparty/volk", "src/3rdparty/vulkan-memory-allocator", "src/3rdparty/template") add_syslinks("user32", "Ole32", "Gdi32","Opengl32") diff --git a/engine/xmake/gen/meta_refl.lua b/engine/xmake/gen/meta_refl.lua index 2e4a65f..bcf8a79 100644 --- a/engine/xmake/gen/meta_refl.lua +++ b/engine/xmake/gen/meta_refl.lua @@ -1,5 +1,9 @@ import("core.project.depend") +local genList = {} function cmd_compile(genfile, sourcefile, template, macro, define) + if genList[genfile] then + return + end import("find_sdk") local meta = find_sdk.find_my_program("refl") template = template or path.join(meta.sdkdir, "template") @@ -14,6 +18,7 @@ function cmd_compile(genfile, sourcefile, template, macro, define) table.insert(argv, "-d") table.insert(argv, define) end + genList[genfile] = true print("cmd_meta_compile", genfile) os.execv(meta.program, argv) return argv