support opengl

This commit is contained in:
ouczbs 2024-07-06 18:04:51 +08:00
parent b9cc541028
commit a00d3bba06
19 changed files with 119 additions and 20 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ vsxmake*/
engine/logs/zengine.log engine/logs/zengine.log
tools/ tools/
cpp_input.h

View File

@ -8,4 +8,4 @@ local utils = {
"spirv-cross-glsl","spirv-cross-cpp", "spirv-cross-core", "spirv-cross-reflect","spirv-cross-util" "spirv-cross-glsl","spirv-cross-cpp", "spirv-cross-core", "spirv-cross-reflect","spirv-cross-util"
} }
add_requires("vulkansdk",{configs = {utils = utils}}) add_requires("vulkansdk",{configs = {utils = utils}})
add_requires("opengl", "opencl-headers") add_requires("glew")

View File

@ -19,6 +19,10 @@ namespace engineapi {
#define UPROPERTY_dx(...) __dxMeta(__VA_ARGS__) #define UPROPERTY_dx(...) __dxMeta(__VA_ARGS__)
#define UFUNCTION_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(arg1, arg2) CONCATENATE_IMPL(arg1, arg2)
#define CONCATENATE_IMPL(arg1, arg2) arg1##arg2 #define CONCATENATE_IMPL(arg1, arg2) arg1##arg2
@ -46,4 +50,5 @@ namespace refl_impl {
struct Meta {}; struct Meta {};
struct vkMeta {}; struct vkMeta {};
struct dxMeta {}; struct dxMeta {};
struct glMeta {};
} }

View File

@ -6,7 +6,6 @@ using std::string;
using std::vector; using std::vector;
struct Guid struct Guid
{ {
using MyMeta = class Guid_Meta;
UPROPERTY({1}) UPROPERTY({1})
unsigned int Data1; unsigned int Data1;
UPROPERTY({}) UPROPERTY({})

View File

@ -38,13 +38,15 @@ namespace engineapi {
system->Shutdown(); system->Shutdown();
} }
} }
void App::Launch() int App::Launch()
{ {
Init(); Init();
while (Loop) { int code = 0;
while (Loop && Window::ProcessMessages(code)) {
Update(); Update();
Render(); Render();
} }
return code;
} }
void App::Update() void App::Update()
{ {

View File

@ -16,7 +16,7 @@ namespace engineapi
public: public:
void Init(); void Init();
void Shutdown(); void Shutdown();
void Launch(); int Launch();
void Update(); void Update();
void Render(); void Render();
}; };

View File

@ -9,6 +9,7 @@ namespace openglapi {
} }
ResourceBundle OpenGLGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta) ResourceBundle OpenGLGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta)
{ {
return {}; return {};
} }
} }

View File

@ -1,17 +1,38 @@
#include "openglapi.h" #include "openglapi.h"
#include "window.h" #include "window.h"
#include "zlog.h"
#include "GL/glew.h"
#include "loader/opengl_glsl_loader.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 { namespace openglapi {
void RenderOpenGLApi::SwitchContext() void RenderOpenGLApi::SwitchContext()
{ {
} }
void RenderOpenGLApi::Init() void RenderOpenGLApi::Init()
{ {
if (glewInit() != GLEW_OK) {
// 处理初始化错误
zlog::error("GLEW Initialization failed!");
}
RenderAPI::Init();
OpenGLGlslLoader::Init(); OpenGLGlslLoader::Init();
window = OpenGLWindow::GetSingletonPtr();
} }
void RenderOpenGLApi::InitRenderPass() 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) void RenderOpenGLApi::SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset)
{ {
mViewPortInfo.width = width; mViewPortInfo.width = width;
@ -33,10 +54,48 @@ namespace openglapi {
void RenderOpenGLApi::EndFrame() void RenderOpenGLApi::EndFrame()
{ {
glEnd(); glEnd();
OpenGLWindow::GetSingletonPtr()->Present(); window->Present();
} }
void RenderOpenGLApi::SetStaticMesh(Mesh& mesh) 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<glVertexMeta>();
GLvoid* offset = reinterpret_cast<GLvoid*>(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) void RenderOpenGLApi::DrawStaticMesh(Mesh& mesh)
{ {

View File

@ -1,13 +1,22 @@
#pragma once #pragma once
#include "render/renderapi.h" #include "render/renderapi.h"
#include "zstd/table.h"
#include "asset/render/asset_struct.h" #include "asset/render/asset_struct.h"
#include "gl/GL.h"
namespace openglapi { namespace openglapi {
using engineapi::RenderContext; using engineapi::RenderContext;
using engineapi::Mesh; using engineapi::Mesh;
using engineapi::Shader; using engineapi::Shader;
using engineapi::Guid;
using zstd::hash_table;
class OpenGLWindow;
struct OpenGLVAO {
int VAO;
};
class RenderOpenGLApi : public engineapi::RenderAPI { class RenderOpenGLApi : public engineapi::RenderAPI {
public:
RenderContext context; RenderContext context;
OpenGLWindow* window;
hash_table<Guid, OpenGLVAO> VAOTable;
public: public:
RenderContext* GetContext() override { RenderContext* GetContext() override {
return &context; return &context;
@ -18,6 +27,7 @@ namespace openglapi {
void Init() override; void Init() override;
void InitRenderPass()override; void InitRenderPass()override;
public: 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 SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override;
void BeginFrame()override; void BeginFrame()override;

View File

@ -1,5 +1,4 @@
#include "window.h" #include "window.h"
#include <gl/GL.h>
namespace openglapi { namespace openglapi {
void OpenGLWindow::SetupOpenGLContext() void OpenGLWindow::SetupOpenGLContext()
{ {
@ -36,9 +35,6 @@ namespace openglapi {
:engineapi::Window(width, height, title) :engineapi::Window(width, height, title)
{ {
SetupOpenGLContext(); SetupOpenGLContext();
// 设置视口和背景颜色
glViewport(0, 0, width, height);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
} }
void OpenGLWindow::Present() void OpenGLWindow::Present()
{ {

View File

@ -20,12 +20,16 @@ namespace engineapi {
}; };
struct BoneVertex : public Vertex struct BoneVertex : public Vertex
{ {
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT }) UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {}; Vector3 Position = {};
UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
UPROPERTY_vk() UPROPERTY_vk()
Vector2 TexCoords = {}; Vector2 TexCoords = {};
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_vk() UPROPERTY_vk()
Vector3 Normal = {}; Vector3 Normal = {};
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_vk() UPROPERTY_vk()
Vector3 Tangent = {}; Vector3 Tangent = {};
// 骨骼蒙皮数据 // 骨骼蒙皮数据

View File

@ -27,6 +27,7 @@ namespace engineapi
public: public:
virtual RenderContext* GetContext() = 0; virtual RenderContext* GetContext() = 0;
public: 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 SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0) = 0;
virtual void BeginFrame() = 0; virtual void BeginFrame() = 0;
virtual void Render(Camera& camera); virtual void Render(Camera& camera);

View File

@ -1,4 +1,5 @@
#include "window.h" #include "window.h"
#include "renderapi.h"
#include "data/engine_setting.h" #include "data/engine_setting.h"
#ifdef VULKAN_API #ifdef VULKAN_API
#include "vulkanapi/window.h" #include "vulkanapi/window.h"
@ -51,12 +52,16 @@ namespace engineapi {
AdjustWindowRectEx(&wr, dwStyle, FALSE, dwExStyle); AdjustWindowRectEx(&wr, dwStyle, FALSE, dwExStyle);
mPtr = CreateWindow( mPtr = CreateWindow(
WindowClass::GetName(), title, 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, CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,
nullptr, nullptr, WindowClass::GetInstance(), this nullptr, nullptr, WindowClass::GetInstance(), this
); );
ShowWindow(mPtr, SW_SHOW); ShowWindow(mPtr, SW_SHOW);
} }
void Window::OnResize(uint32_t width, uint32_t height)
{
RenderAPI::GetSingletonPtr()->OnWindowSizeChange(width, height);
}
bool Window::ProcessMessages(int& code) bool Window::ProcessMessages(int& code)
{ {
MSG msg; MSG msg;
@ -68,14 +73,14 @@ namespace engineapi {
{ {
// return optional wrapping int (arg to PostQuitMessage is in wparam) signals quit // return optional wrapping int (arg to PostQuitMessage is in wparam) signals quit
code = (int)msg.wParam; code = (int)msg.wParam;
return true; return false;
} }
// TranslateMessage will post auxilliary WM_CHAR messages from key msgs // TranslateMessage will post auxilliary WM_CHAR messages from key msgs
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
return false; return true;
} }
LRESULT CALLBACK Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept LRESULT CALLBACK Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
{ {
@ -108,10 +113,15 @@ namespace engineapi {
{ {
switch (msg) switch (msg)
{ {
// we don't want the DefProc to handle this message because case WM_SIZE:
// we want our destructor to destroy the window, so return 0 instead of break {
uint32_t width = LOWORD(lParam);
uint32_t height = HIWORD(lParam);
OnResize(width, height);
break;
}
case WM_CLOSE: case WM_CLOSE:
PostQuitMessage(0); PostQuitMessage(-1);
return 0; return 0;
// clear keystate when window loses focus to prevent input getting "stuck" // clear keystate when window loses focus to prevent input getting "stuck"
/************** END MOUSE MESSAGES **************/ /************** END MOUSE MESSAGES **************/

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Windows.h> #include <Windows.h>
#include <cstdint> #include <cstdint>
#include <optional>
#include "singleton.h" #include "singleton.h"
namespace engineapi { namespace engineapi {
class Window : public ISingleton<Window> { class Window : public ISingleton<Window> {
@ -37,6 +38,7 @@ namespace engineapi {
HWND Ptr() { HWND Ptr() {
return mPtr; return mPtr;
} }
void OnResize(uint32_t width, uint32_t height);
void GetSize(uint32_t& width, uint32_t& height) { void GetSize(uint32_t& width, uint32_t& height) {
width = mWidth; width = mWidth;
height = mHeight; height = mHeight;

View File

@ -48,6 +48,10 @@ namespace vulkanapi {
PassList[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer, output); 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) void RenderVulkanAPI::SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset)
{ {

View File

@ -33,6 +33,7 @@ namespace vulkanapi
void Init() override; void Init() override;
void InitRenderPass()override; void InitRenderPass()override;
public: 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 SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override;
void BeginFrame()override; void BeginFrame()override;

View File

@ -7,6 +7,5 @@ int main(int argc, char** argv)
{ {
const char* name = "zengine"; const char* name = "zengine";
App game(name); App game(name);
game.Launch(); return game.Launch();
return 0;
} }

View File

@ -14,7 +14,7 @@ target("zengine")
add_deps("zlog","zlib") add_deps("zlog","zlib")
add_defines("VULKAN_API", "OPENGL_API") add_defines("VULKAN_API", "OPENGL_API")
add_packages("vulkansdk","tinyobjloader","assimp","nlohmann_json") add_packages("vulkansdk","tinyobjloader","assimp","nlohmann_json")
add_packages("opencl", "opencl-headers") add_packages("glew")
add_includedirs("src/engine") add_includedirs("src/engine")
add_includedirs("src/3rdparty/volk", "src/3rdparty/vulkan-memory-allocator", "src/3rdparty/template") add_includedirs("src/3rdparty/volk", "src/3rdparty/vulkan-memory-allocator", "src/3rdparty/template")
add_syslinks("user32", "Ole32", "Gdi32","Opengl32") add_syslinks("user32", "Ole32", "Gdi32","Opengl32")

View File

@ -1,5 +1,9 @@
import("core.project.depend") import("core.project.depend")
local genList = {}
function cmd_compile(genfile, sourcefile, template, macro, define) function cmd_compile(genfile, sourcefile, template, macro, define)
if genList[genfile] then
return
end
import("find_sdk") import("find_sdk")
local meta = find_sdk.find_my_program("refl") local meta = find_sdk.find_my_program("refl")
template = template or path.join(meta.sdkdir, "template") 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, "-d")
table.insert(argv, define) table.insert(argv, define)
end end
genList[genfile] = true
print("cmd_meta_compile", genfile) print("cmd_meta_compile", genfile)
os.execv(meta.program, argv) os.execv(meta.program, argv)
return argv return argv