From 8078a8c33ce6e9825875218616ebd95b556c0d7e Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sat, 19 Apr 2025 19:28:53 +0900 Subject: [PATCH] add directx template --- engine/gf_version.c | 7 ++ engine/graphic/directx/dx11/gf_draw.c | 144 +++++++++++++++++++++++++ engine/graphic/directx/gf_driver.c | 71 ++++++++++++ engine/graphic/directx/gf_graphic.c | 34 ++++++ engine/include/gf_directx.h | 20 ++++ engine/include/gf_type/draw_driver.h | 9 ++ engine/include/gf_type/draw_platform.h | 11 ++ engine/premake5.lua | 9 ++ 8 files changed, 305 insertions(+) create mode 100644 engine/graphic/directx/dx11/gf_draw.c create mode 100644 engine/graphic/directx/gf_driver.c create mode 100644 engine/graphic/directx/gf_graphic.c create mode 100644 engine/include/gf_directx.h diff --git a/engine/gf_version.c b/engine/gf_version.c index 4c7a1a0..2de1e21 100644 --- a/engine/gf_version.c +++ b/engine/gf_version.c @@ -40,6 +40,13 @@ void gf_version_get(gf_version_t* version) { #endif #endif +#if defined(DRV_DIRECTX) + strcpy(version->driver, "DirectX"); +#if defined(USE_DX11) + strcpy(version->backend, "DirectX 11"); +#endif +#endif + #if defined(THREAD_WIN32) strcpy(version->thread, "Win32"); #elif defined(THREAD_POSIX) diff --git a/engine/graphic/directx/dx11/gf_draw.c b/engine/graphic/directx/dx11/gf_draw.c new file mode 100644 index 0000000..6e3ee44 --- /dev/null +++ b/engine/graphic/directx/dx11/gf_draw.c @@ -0,0 +1,144 @@ +#define GF_EXPOSE_DRAW_PLATFORM +#define GF_EXPOSE_DRAW + +#include + +/* External library */ +#include + +/* Interface */ +#include + +/* Engine */ +#include +#include +#include + +/* Standard */ +#include +#include + +void gf_draw_platform_begin(void) {} +void gf_draw_platform_end(void) {} + +LRESULT CALLBACK gf_draw_platform_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { + PAINTSTRUCT ps; + RECT rect; + gf_draw_t* draw = (gf_draw_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + switch(msg) { + case WM_PAINT: + BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + break; + case WM_SIZE: + if(draw->platform != NULL) { + GetClientRect(hWnd, &rect); + draw->x = rect.left; + draw->y = rect.top; + draw->width = rect.right - rect.left; + draw->height = rect.bottom - rect.top; + gf_draw_reshape(draw); + } + break; + case WM_CLOSE: + draw->close = 1; + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, msg, wp, lp); + } + return 0; +} + +int gf_draw_platform_has_extension(gf_draw_t* draw, const char* query) { return 0; } + +int gf_draw_platform_step(gf_draw_t* draw) { + MSG msg; + int ret = 0; + while(PeekMessage(&msg, draw->platform->window, 0, 0, PM_NOREMOVE)) { + if(GetMessage(&msg, draw->platform->window, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } else { + ret = 1; + break; + } + } + if(ret == 0) { + gf_draw_driver_before(draw); + gf_draw_frame(draw); + gf_draw_driver_after(draw); + + SwapBuffers(draw->platform->dc); + } + return ret; +} + +gf_draw_platform_t* gf_draw_platform_create(gf_engine_t* engine, gf_draw_t* draw) { + WNDCLASSEX wc; + RECT rect; + DWORD style; + gf_draw_platform_t* platform = malloc(sizeof(*platform)); + memset(platform, 0, sizeof(*platform)); + platform->engine = engine; + + platform->instance = (HINSTANCE)GetModuleHandle(NULL); + if(platform->instance == NULL) { + gf_log_function(engine, "Failed to get instance", ""); + gf_draw_platform_destroy(platform); + return NULL; + } + + wc.cbSize = sizeof(wc); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = gf_draw_platform_proc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = platform->instance; + wc.hIcon = LoadIcon(platform->instance, "GAME"); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "goldfish"; + wc.hIconSm = LoadIcon(platform->instance, "GAME"); + if(!RegisterClassEx(&wc)) { + gf_log_function(engine, "Failed to register class", ""); + gf_draw_platform_destroy(platform); + return NULL; + } + + platform->window = CreateWindow("goldfish", draw->title, (WS_OVERLAPPEDWINDOW), draw->x, draw->y, draw->width, draw->height, NULL, 0, platform->instance, NULL); + if(platform->window == NULL) { + gf_log_function(engine, "Failed to create window", ""); + gf_draw_platform_destroy(platform); + return NULL; + } + + SetWindowLongPtr(platform->window, GWLP_USERDATA, (LONG_PTR)draw); + + platform->dc = GetDC(platform->window); + + SetRect(&rect, 0, 0, draw->width, draw->height); + + style = (DWORD)GetWindowLongPtr(platform->window, GWL_STYLE); + AdjustWindowRect(&rect, style, FALSE); + SetWindowPos(platform->window, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE); + + ShowWindow(platform->window, SW_NORMAL); + UpdateWindow(platform->window); + + return platform; +} + +void gf_draw_platform_destroy(gf_draw_platform_t* platform) { + if(platform->dc != NULL) { + ReleaseDC(platform->window, platform->dc); + } + if(platform->window != NULL) { + DestroyWindow(platform->window); + } + gf_log_function(platform->engine, "Destroyed platform-dependent part of drawing driver", ""); + free(platform); +} diff --git a/engine/graphic/directx/gf_driver.c b/engine/graphic/directx/gf_driver.c new file mode 100644 index 0000000..932f019 --- /dev/null +++ b/engine/graphic/directx/gf_driver.c @@ -0,0 +1,71 @@ +#define GF_EXPOSE_DRAW_DRIVER +#define GF_EXPOSE_DRAW +#define GF_EXPOSE_TEXTURE + +#include + +/* External library */ +#include + +/* Interface */ +#include + +/* Engine */ +#include +#include +#include +#include +#include +#include + +/* Standard */ +#include +#include + +gf_draw_driver_texture_t* gf_draw_driver_register_texture(gf_draw_t* draw, int width, int height, int* iwidth, int* iheight, unsigned char* data) { + /* TODO: Implement this */ + return NULL; +} + +void gf_draw_driver_destroy_texture(gf_draw_driver_texture_t* t) { + /* TODO: Implement this */ + free(t); +} + +gf_draw_driver_t* gf_draw_driver_create(gf_engine_t* engine, gf_draw_t* draw) { + gf_draw_driver_t* draw_driver = malloc(sizeof(*draw_driver)); + memset(draw_driver, 0, sizeof(*draw_driver)); + draw_driver->engine = engine; + + /* TODO: Implement this */ + + return draw_driver; +} + +int gf_draw_driver_has_extension(gf_draw_t* draw, const char* query) { return 0; } + +void gf_draw_driver_reshape(gf_draw_t* draw) { /* TODO: Implement this */ } + +void gf_draw_driver_begin_texture_2d(gf_draw_t* draw, gf_texture_t* texture) { /* TODO: Implement this */ } + +void gf_draw_driver_end_texture_2d(gf_draw_t* draw) { /* TODO: Implement this */ } + +void gf_draw_driver_set_color(gf_draw_t* draw, gf_graphic_color_t color) { /* TODO: Implement this */ } + +void gf_draw_driver_destroy(gf_draw_driver_t* driver) { + /* TODO: Implement this */ + gf_log_function(driver->engine, "Destroyed drawing driver", ""); + free(driver); +} + +void gf_draw_driver_before(gf_draw_t* draw) { + /* TODO: Remove if needed, needed at least for OpenGL */ + gf_draw_driver_reshape(draw); + + /* TODO: Remove if needed, needed at least for OpenGL */ + gf_graphic_set_camera(draw); + + gf_graphic_clear(draw); +} + +void gf_draw_driver_after(gf_draw_t* draw) {} diff --git a/engine/graphic/directx/gf_graphic.c b/engine/graphic/directx/gf_graphic.c new file mode 100644 index 0000000..6684d7b --- /dev/null +++ b/engine/graphic/directx/gf_graphic.c @@ -0,0 +1,34 @@ +#define GF_EXPOSE_DRAW +#define GF_EXPOSE_TEXTURE + +#include + +/* External library */ +#include + +/* Interface */ +#include + +/* Engine */ +#include +#include +#include +#include + +/* Standard */ +#include +#include + +void gf_graphic_begin_2d(gf_draw_t* draw) { /* TODO: Implement this */ } + +void gf_graphic_end_2d(gf_draw_t* draw) { /* TODO: Implement this */ } + +void gf_graphic_clear(gf_draw_t* draw) { /* TODO: Implement this */ } + +void gf_graphic_draw_texture_polygon(gf_draw_t* draw, gf_texture_t* texture, gf_graphic_color_t color, int dim, int npair, ...) { /* TODO: Implement this */ } + +void gf_graphic_fill_polygon(gf_draw_t* draw, gf_graphic_color_t color, int dim, int npair, ...) { /* TODO: Implement this */ } + +void gf_graphic_perspective(gf_draw_t* draw, double fovy, double znear, double zfar) { /* TODO: Implement this */ } + +GF_EXPORT void gf_graphic_set_camera(gf_draw_t* draw) { /* TODO: Implement this */ } diff --git a/engine/include/gf_directx.h b/engine/include/gf_directx.h new file mode 100644 index 0000000..4ed8b86 --- /dev/null +++ b/engine/include/gf_directx.h @@ -0,0 +1,20 @@ +/** + * @file gf_directx.h + * @~english + * @brief DirectX headers + * @note User should not include this, this header is used internally + */ + +#ifndef __GF_DIRECTX_H__ +#define __GF_DIRECTX_H__ + +#ifdef _WIN32 +#include +#endif +#if defined(USE_DX11) +#include +#include +#include +#endif + +#endif diff --git a/engine/include/gf_type/draw_driver.h b/engine/include/gf_type/draw_driver.h index 66f0584..4c75c34 100644 --- a/engine/include/gf_type/draw_driver.h +++ b/engine/include/gf_type/draw_driver.h @@ -14,6 +14,8 @@ /* External library */ #if defined(DRV_OPENGL) #include +#elif defined(DRV_DIRECTX) +#include #endif /* Engine */ @@ -29,6 +31,13 @@ GF_DECLARE_TYPE(draw_driver_texture, { int width; int height; }); +#elif defined(DRV_DIRECTX) +GF_DECLARE_TYPE(draw_driver, { gf_engine_t* engine; }); +GF_DECLARE_TYPE(draw_driver_texture, { + gf_engine_t* engine; + int width; + int height; +}); #else /** * @struct gf_draw_driver_t diff --git a/engine/include/gf_type/draw_platform.h b/engine/include/gf_type/draw_platform.h index 8665690..a55dd6f 100644 --- a/engine/include/gf_type/draw_platform.h +++ b/engine/include/gf_type/draw_platform.h @@ -14,6 +14,8 @@ /* External library */ #if defined(DRV_OPENGL) #include +#elif defined(DRV_DIRECTX) +#include #endif /* Engine */ @@ -44,6 +46,15 @@ GF_DECLARE_TYPE(draw_platform, { GLFWwindow* window; }); #endif +#elif defined(DRV_DIRECTX) +#if defined(USE_DX11) +GF_DECLARE_TYPE(draw_platform, { + gf_engine_t* engine; + HINSTANCE instance; + HWND window; + HDC dc; +}); +#endif #else /** * @struct gf_draw_platform_t diff --git a/engine/premake5.lua b/engine/premake5.lua index ddbedb8..8323ff0 100644 --- a/engine/premake5.lua +++ b/engine/premake5.lua @@ -9,6 +9,15 @@ gf_backends = { wgl = {"WGL", {"gdi32"}}, glfw = {"GLFW", {"glfw"}} } + }, + directx = { + name = "DirectX", + default = "dx11", + unix = {}, + windows = {}, + backends = { + dx11 = {"DirectX 11", {"dxguid", "dxgi", "d3d11", "d3dcompiler", "gdi32"}} + } } }