add vkn && libsdl

This commit is contained in:
ouczbs 2024-08-17 18:01:21 +08:00
parent f89424979e
commit 722396f613
54 changed files with 5500 additions and 174 deletions

View File

@ -1 +1 @@
add_requires("spdlog", "lemon")
add_requires("spdlog", "lemon", "libsdl", "vulkansdk")

View File

@ -0,0 +1,12 @@
#pragma once
#include "data/engine_config.h"
namespace api{
template<typename T>
class AppImpl;
class App {
public:
template<typename T>
void Run(EngineConfig config, AppImpl<T>& impl);
};
}
#include "app.inl"

View File

@ -0,0 +1,25 @@
namespace api {
template<typename T>
class AppImpl {
void Setup() {
static_cast<T*>(this)->Setup();
}
void CleanUp() {
static_cast<T*>(this)->CleanUp();
}
void ImGui() {
static_cast<T*>(this)->ImGui();
}
void PreRender() {
static_cast<T*>(this)->PreRender();
}
void PostRender() {
static_cast<T*>(this)->PostRender();
}
};
template<typename T>
inline void App::Run(EngineConfig config, AppImpl<T>& impl)
{
impl.Setup();
}
}

View File

@ -0,0 +1,7 @@
#pragma once
#include "render/type.h"
namespace api{
struct EngineConfig {
GraphicsAPI API = GraphicsAPI::Vulkan;
};
}

View File

@ -0,0 +1,5 @@
#pragma once
namespace api{
struct ProjectConfig {
};
}

View File

View File

@ -0,0 +1,4 @@
static_component("app","engine")
add_headerfiles("include/**.h", "include/**.inl","impl/*.inl")
add_files("src/**.cpp")
add_deps("core", "asset", "zlib", "render")

View File

@ -39,4 +39,4 @@ namespace api
};
}
#include "meta_bundle.inl"
#include "asset/meta_bundle_gen.inl"
#include ".asset/meta_bundle_gen.inl"

View File

@ -31,4 +31,4 @@ namespace api
};
}
#include "resource_handle.inl"
#include "asset/resource_handle_gen.inl"
#include ".asset/resource_handle_gen.inl"

View File

@ -31,6 +31,7 @@ namespace api {
void InitModule(Name name);
void ShutModule(Name name);
void MakeGraph(Name name, bool shared, int argc, char** argv);
void MainLoop();
void DestroyGraph();
public:
IModule* spawnDynamicModule(Name name, bool hotfix);
@ -109,6 +110,11 @@ namespace api {
CreateModule(name, shared);
InitModule(name);
}
inline void ModuleManagerImpl::MainLoop()
{
auto it = mModuleTable.find(mInfo.name);
dynamic_cast<IMainModule*>(it->second)->MainLoop();
}
void ModuleManagerImpl::DestroyGraph()
{
if(mInfo.isActive){
@ -129,7 +135,7 @@ namespace api {
if (!newFuncAddr) {
pmr::string libPath("/exe/");
libPath.reserve(10 + name_view.size());
libPath.append(name_view);
libPath.append(name == mInfo.name ? "mgame" : name_view);
libPath.append(SharedLibrary::GetExtensionName());
if (sharedLib.Load(libPath)) {
newFuncAddr = sharedLib.GetSymbol(newFuncName.data());
@ -220,6 +226,11 @@ namespace api {
impl->MakeGraph(name, shared, argc, argv);
}
inline void ModuleManager::MainLoop()
{
impl->MainLoop();
}
inline void ModuleManager::DestroyGraph()
{
impl->DestroyGraph();

View File

@ -9,7 +9,7 @@ namespace zlog {
std::shared_ptr<spdlog::logger> m_logger;
public:
zloger();
~zloger();
~zloger() noexcept;
template <typename... Args>
void log(level_enum level, format& fmt, Args &&...args) {
m_logger->log(fmt.loc, level, fmt::runtime(fmt.value), std::forward<Args>(args)...);
@ -19,6 +19,9 @@ namespace zlog {
}
};
CORE_API zloger& get_zlog();
inline void flush() {
get_zlog().flush();
}
template <typename... Args>
void info(format fmt, Args &&...args) {
get_zlog().log(level_enum::info, fmt, std::forward<Args>(args)...);
@ -36,16 +39,18 @@ namespace zlog {
get_zlog().log(level_enum::err, fmt, std::forward<Args>(args)...);
};
template <typename... Args>
void errorf(format fmt, Args &&...args) {
get_zlog().log(level_enum::err, fmt, std::forward<Args>(args)...);
get_zlog().flush();
};
template <typename... Args>
void fatal(format fmt, Args &&...args) {
get_zlog().log(level_enum::critical, fmt, std::forward<Args>(args)...);
const std::string format_str = fmt::format(std::forward<Args>(args)...);
throw std::runtime_error(format_str);
get_zlog().flush();
throw std::runtime_error(std::string(fmt.value));
};
inline void fatal(format fmt) {
get_zlog().log(level_enum::critical, fmt);
throw std::runtime_error(std::string(fmt.value));
};
inline void flush() {
get_zlog().flush();
}
};

View File

@ -86,4 +86,4 @@ namespace api {
};
}
#include "module.inl"
#include "core/module_gen.inl"
#include ".core/module_gen.inl"

View File

@ -17,9 +17,6 @@ namespace api {
template <typename ModuleClass>
struct ModuleRegistrantImpl;
struct IDynamicModule : public IModule {
virtual ~IDynamicModule() override
{
}
SharedLibrary mSharedLib;
};
struct DefaultDynamicModule : public IDynamicModule {
@ -35,6 +32,9 @@ namespace api {
virtual void OnBeginLoad() = 0;
virtual void OnEndLoad() = 0;
};
struct IMainModule : public IDynamicModule {
virtual void MainLoop() = 0;
};
class CORE_API CoreModule : public IStaticModule
{
public:

View File

@ -17,6 +17,7 @@ namespace api {
void InitModule(Name name);
void ShutModule(Name name);
void MakeGraph(Name name, bool shared, int argc, char** argv);
void MainLoop();
void DestroyGraph();
protected:
IModule* spawnDynamicModule(Name name, bool hotfix);

View File

@ -27,7 +27,7 @@ namespace zlog {
m_logger->set_pattern("[%Y-%m-%d %H:%M:%S][%s:%#] %-8l %^%v%$");
spdlog::register_logger(m_logger);
}
zloger::~zloger()
zloger::~zloger() noexcept
{
m_logger->flush();
spdlog::drop_all();

View File

@ -1,70 +1,11 @@
#include "render/window.h"
namespace api {
LRESULT Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
inline Window::Window(CreatePFN func, const Args& args, int width, int height) noexcept : mHeight(height), mWidth(width)
{
// use create parameter passed in from CreateWindow() to store window class pointer at WinAPI side
if (msg == WM_NCCREATE)
{
// extract ptr to window class from creation data
const CREATESTRUCTW* const pCreate = reinterpret_cast<CREATESTRUCTW*>(lParam);
Window* const pWnd = static_cast<Window*>(pCreate->lpCreateParams);
// set WinAPI-managed user data to store ptr to window instance
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd));
// set message proc to normal (non-setup) handler now that setup is finished
SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Window::HandleMsgThunk));
// forward message to window instance handler
return pWnd->HandleMsg(hWnd, msg, wParam, lParam);
}
// if we get a message before the WM_NCCREATE message, handle with default handler
return DefWindowProc(hWnd, msg, wParam, lParam);
}
LRESULT Window::HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
{
// retrieve ptr to window instance
Window* const pWnd = reinterpret_cast<Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
// forward message to window instance handler
return pWnd->HandleMsg(hWnd, msg, wParam, lParam);
}
bool Window::ProcessMessages(int& code)
{
MSG msg;
// while queue has messages, remove and dispatch them (but do not block on empty queue)
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
// check for quit because peekmessage does not signal this via return val
if (msg.message == WM_QUIT)
{
// return optional wrapping int (arg to PostQuitMessage is in wparam) signals quit
code = (int)msg.wParam;
return false;
}
// TranslateMessage will post auxilliary WM_CHAR messages from key msgs
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
LRESULT Window::HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
{
switch (msg)
{
case WM_SIZE:
{
uint32_t width = LOWORD(lParam);
uint32_t height = HIWORD(lParam);
OnResize(width, height);
break;
}
case WM_CLOSE:
PostQuitMessage(-1);
return 0;
/************** END MOUSE MESSAGES **************/
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
void Window::OnResize(uint32_t width, uint32_t height)
{
//RenderAPI::GetSingletonPtr()->OnWindowSizeChange(width, height);
uint32_t windowFlags = SDL_WINDOW_SHOWN;
windowFlags |= args.resizeable ? SDL_WINDOW_RESIZABLE : 0;
windowFlags |= args.headless ? SDL_WINDOW_HIDDEN : 0;
// Even if we're in headless mode, we still need to create a window, otherwise SDL will not poll events.
mPtr = func(args.title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, windowFlags);
}
}

View File

@ -1,11 +1,6 @@
#pragma once
#include "type.h"
namespace api {
enum class GraphicsAPI
{
OpenGL,
Vulkan,
D3D12
};
struct RenderContext {
};

View File

@ -15,7 +15,5 @@ namespace api {
public:
virtual void Init() = 0;
virtual void Shutdown() = 0;
public:
virtual RenderContext* GetContext() = 0;
};
}

View File

@ -0,0 +1,9 @@
#pragma once
namespace api {
enum class GraphicsAPI
{
OpenGL,
Vulkan,
D3D12
};
}

View File

@ -1,23 +1,20 @@
#pragma once
#include <Windows.h>
#include <cstdint>
#include <optional>
#include <SDL.h>
#include "singleton.h"
namespace api {
class RENDER_API Window : public Singleton<Window> {
protected:
using CreatePFN = decltype(&SDL_CreateWindow);
int mWidth;
int mHeight;
HWND mPtr;
protected:
LRESULT HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
SDL_Window* mPtr = nullptr;
struct Args {
const char* title;
bool resizeable = true;
bool headless = false;
};
public:
Window(int width, int height, HWND hwnd) noexcept :mWidth(width), mHeight(height), mPtr(hwnd){};
HWND Ptr() { return mPtr; }
void OnResize(uint32_t width, uint32_t height);
public:
static LRESULT CALLBACK HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
static LRESULT CALLBACK HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
static bool ProcessMessages(int& code);
Window(CreatePFN func, const Args& args, int width, int height) noexcept;
SDL_Window* GetPtr() { return mPtr; }
};
};

View File

@ -3,4 +3,4 @@ static_component("render","engine")
add_files("src/**.cpp")
add_deps("asset", "zlib", "core")
add_syslinks("user32", {public = true})
add_packages("lemon", {public = true})
add_packages("lemon", "libsdl", {public = true})

View File

@ -0,0 +1,6 @@
#pragma once
namespace vkn {
class Backend {
};
}

View File

@ -8,4 +8,4 @@ public:
void InitMetaData(void) override;
};
IMPLEMENT_DYNAMIC_MODULE(VULKAN_API, VulkanModule, vulkan)
#include "vulkan/vulkan.plugin.inl"
#include ".vulkan/vulkan.plugin.inl"

View File

@ -0,0 +1,10 @@
#pragma once
#include <Windows.h>
#include <functional>
#define VK_NO_PROTOTYPES
#include "volk/volk.h"
#include <string>
#include <vector>
namespace vkn {
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "type.h"
#include "render/renderapi.h"
namespace vkn {
class VulkanWindow;
class VulkanAPI : public api::RenderAPI {
private:
VulkanWindow* window;
public:
VulkanAPI();
void Init() override;
void Shutdown() override;
};
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "type.h"
#include "render/window.h"
namespace vkn {
class VulkanWindow : public api::Window {
private:
VkSurfaceKHR mSurfaceKHR;
public:
using api::Window::Window;
void CreateRender();
};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
#include "module.h"
#include "vkn/module.h"
#include "pmr/frame_allocator.h"
void VulkanModule::OnLoad(int argc, char** argv)
{

View File

@ -0,0 +1,17 @@
#include "vkn/vulkan_api.h"
#include "vkn/vulkan_window.h"
namespace vkn {
VulkanAPI::VulkanAPI()
{
window = (VulkanWindow*) api::Window::Ptr();
window->CreateRender();
}
void VulkanAPI::Init()
{
}
void VulkanAPI::Shutdown()
{
}
}

View File

@ -0,0 +1,7 @@
#include "vkn/vulkan_window.h"
namespace vkn {
void VulkanWindow::CreateRender()
{
}
}

View File

@ -1,5 +1,5 @@
shared_module("vulkan","engine")
add_includedirs("include/vulkan")
add_headerfiles("include/**.h")
add_files("src/**.cpp")
add_files("src/**.cpp", "include/volk/volk.c")
add_packages("vulkansdk", {public = true})
add_dependency("engine", {public = true})

View File

@ -42,12 +42,13 @@ function add_dependency(...)
end
function game_instance(name, opt)
target(name)
set_kind("shared")
set_kind("binary")
set_group("Games")
add_rules("engine.api")
add_rules("engine.plugin", {file = opt and opt.file or "src/" .. name .. ".h"})
add_defines("SDL_MAIN_HANDLED")
target(name .. "-editor")
set_kind("binary")
set_kind("shared")
set_group("Games")
add_deps(name)
end

View File

@ -8,6 +8,7 @@ public:
mInfo.dependencies = {
{"core", "1.0.1", "static" },
{"asset", "1.0.1", "static" },
{"render", "1.0.1", "static" },
};
};
};

View File

@ -51,7 +51,7 @@ function add_gen_dir(target)
os.mkdir(sourcedir)
end
target:add("includedirs", sourcedir, {public = true})
sourcedir = path.join(os.projectdir(), sourcedir, target:name())
sourcedir = path.join(os.projectdir(), sourcedir, "." .. target:name())
if not os.isdir(sourcedir) then
os.mkdir(sourcedir)
end

View File

@ -25,7 +25,7 @@ function add_gen_dir(target)
os.mkdir(sourcedir)
end
target:add("includedirs", sourcedir, {public = true})
sourcedir = path.join(os.projectdir(), sourcedir, target:name())
sourcedir = path.join(os.projectdir(), sourcedir, "." .. target:name())
if not os.isdir(sourcedir) then
os.mkdir(sourcedir)
end

View File

@ -1,60 +0,0 @@
#include <iostream>
#include <array>
#include <charconv>
#include "engine/api.h"
#include "asset/resource_system.h"
#include "os/file_manager.h"
#include "render/graph/frame_graph.h"
#include "render/pass/demo_pass.h"
#include "zlog.h"
#include "source_location.h"
void test(std::string_view str = "") {
std::cout << "test " << str << std::endl;
}
int main(int argc, char** argv) {
api::ModuleManager::Ptr()->MakeGraph("zworld", true, argc, argv);
auto ptr = api::ResourceSystem::Ptr();
auto ptr2 = api::FileManager::Ptr();
api::FrameGraph graph;
graph.AddRenderPass<api::DemoPass>();
graph.Compile();
graph.Execute();
graph.Clear();
zlog::info("hello world");
test("sss");
using namespace refl;
constexpr TStr str1{ "Hello" };
constexpr TStr str2{ " world" };
constexpr TStr str3 = detail::concat(str1, str2);
constexpr auto r1 = value_name<8 * sizeof(int)>();
constexpr int v = 12;
auto cls = refl::type_info<int>();
//auto str4 = concat(r1, str2);
auto t1 = refl::type_name<int>();
auto v1 = refl::type_name<int>().View();
auto v2 = t1.View();
if (v1 == t1.View()) {
auto t2 = refl::type_name<int16_t>();
auto t3 = refl::type_name<int8_t>();
}
auto t2 = refl::type_name<int16_t>();
auto t3 = refl::type_name<int8_t>();
pmr::FrameAllocatorPool pool;
pmr::Name name = "hello enginehello enginehello engine\n";
pmr::Name name2("hello enginehello enginehello engine\n");
pmr::Name name3("hello enginehello enginehello engine222\n");
if (name == name2) {
std::string s1 = name.ToString();
std::string s2 = name2.ToString();
if (s1.c_str() == s2.c_str()) {
new(&pool)int(1);
}
if (s1 == s2) {
new(&pool)int(1);
}
}
int* a = new(&pool)int(1);
int* b = new(&pool)int(2);
int* c = new(&pool)int(3);
std::cout << "hello engine\n";
}

View File

View File

15
game/zworld/src/main.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "SDL.h"
#include "engine/api.h"
#include "zlog.h"
#include <iostream>
int main(int argc,char* argv[]) {
// 初始化 SDL
if (SDL_Init(SDL_INIT_EVENTS) < 0) {
zlog::errorf("SDL_Init:: {}", SDL_GetError());
}
auto ptr = api::ModuleManager::Ptr();
ptr->MakeGraph("zworld", true, argc, argv);
ptr->MainLoop();
SDL_Quit();
return 0;
}

View File

@ -1,9 +1,51 @@
#include "zworld.h"
#include "vkn/vulkan_window.h"
#include "vkn/vulkan_api.h"
#include <iostream>
using namespace api;
void ZWorldModule::OnLoad(int argc, char** argv)
{
// 创建窗口
new (GlobalPool()) vkn::VulkanWindow(&SDL_CreateWindow, { "zengine" }, 1080, 720);
new (GlobalPool()) vkn::VulkanAPI();
}
void ZWorldModule::OnUnload()
{
}
void ZWorldModule::MainLoop()
{
bool running = true;
SDL_Event event_;
auto win = Window::Ptr();
auto ptr = Window::Ptr()->GetPtr();
SDL_Renderer* renderer = SDL_CreateRenderer(ptr, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
std::cerr << "无法创建渲染器: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(ptr);
SDL_Quit();
}
while (running) {
// 处理事件
while (SDL_PollEvent(&event_)) {
if (event_.type == SDL_QUIT) {
running = false;
}
}
// 清除屏幕
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // 黑色
SDL_RenderClear(renderer);
// 绘制一个红色矩形
SDL_Rect rect = { 200, 150, 400, 300 };
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 红色
SDL_RenderFillRect(renderer, &rect);
// 显示渲染内容
SDL_RenderPresent(renderer);
}
}

View File

@ -1,12 +1,13 @@
#pragma once
#include "module/module.h"
#include "module/module_manager.h"
class ZWORLD_API ZWorldModule : public api::IDynamicModule
class ZWORLD_API ZWorldModule : public api::IMainModule
{
public:
void OnLoad(int argc, char** argv) override;
void OnUnload() override;
void InitMetaData(void) override;
void MainLoop()override;
};
IMPLEMENT_DYNAMIC_MODULE(ZWORLD_API, ZWorldModule, zworld)
#include "zworld/zworld.plugin.inl"
#include ".zworld/zworld.plugin.inl"

View File

@ -4,4 +4,5 @@ target("zworld")
add_headerfiles("src/*.h")
add_dependency("engine", "editor", "vulkan", {public = true})
target("zworld-editor")
add_files("editor/main.cpp")
add_files("editor/*.cpp")
add_headerfiles("editor/*.h")