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
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"
}
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 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 {};
}

View File

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

View File

@ -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()
{

View File

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

View File

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

View File

@ -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<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)
{

View File

@ -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<Guid, OpenGLVAO> 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;

View File

@ -1,5 +1,4 @@
#include "window.h"
#include <gl/GL.h>
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()
{

View File

@ -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 = {};
// 骨骼蒙皮数据

View File

@ -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);

View File

@ -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 **************/

View File

@ -1,6 +1,7 @@
#pragma once
#include <Windows.h>
#include <cstdint>
#include <optional>
#include "singleton.h"
namespace engineapi {
class Window : public ISingleton<Window> {
@ -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;

View File

@ -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)
{

View File

@ -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;

View File

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

View File

@ -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")

View File

@ -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