From 68666af0ccf686093adc79e1558443579dd0dc59 Mon Sep 17 00:00:00 2001 From: Patrick Cleavelin Date: Sat, 25 May 2024 16:26:43 -0500 Subject: [PATCH] stub all directx wrappers --- justfile | 31 ++++++-- src/gfx/gfx.odin | 7 +- vendor/pcleavelin/gfx.h | 156 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 178 insertions(+), 16 deletions(-) diff --git a/justfile b/justfile index 90c1f3e..7fb8550 100644 --- a/justfile +++ b/justfile @@ -1,3 +1,5 @@ +set shell := ["cmd.exe", "/c"] + alias b := build alias r := run @@ -5,13 +7,16 @@ c_flags := if os() == "macos" { "$(curl-config --libs) -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC" } else if os_family() == "unix" { "$(curl-config --libs) -lEGL -lGLESv2 -lGL -lm -lwayland-client -lwayland-egl -lX11 -lXi -lXcursor -Wno-implicit-function-declaration" +} else if os_family() == "windows" { + "" } else { "" } +[macos] build: build_gfx odin build src/ -out:bin/chat_client -debug -lld -extra-linker-flags:"-framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit" [macos] -build_gfx: transpile_shaders_metal +build_gfx: compile_shaders_metal mkdir -p bin cc -O0 -g -c -ObjC -Wall -Wextra -D_FONT_WIDTH=12 -D_FONT_HEIGHT=24 -DED_GFX_IMPLEMENTATION vendor/pcleavelin/gfx.h -o bin/libgfx.a @@ -20,8 +25,24 @@ run: build ./bin/chat_client [macos] -transpile_shaders_metal: - mkdir -p bin/transpiled_shaders +compile_shaders_metal: + mkdir -p bin/compiled_shaders - xcrun -sdk macosx metal -o bin/transpiled_shaders/text_atlas.ir -c shaders/text_atlas.metal - xcrun -sdk macosx metallib -o bin/shaders.metallib bin/transpiled_shaders/text_atlas.ir + xcrun -sdk macosx metal -o bin/compiled_shaders/text_atlas.ir -c shaders/text_atlas.metal + xcrun -sdk macosx metallib -o bin/shaders.metallib bin/compiled_shaders/text_atlas.ir + +[windows] +build: build_gfx + odin build src\ -out:bin\chat_client.exe -debug -lld + +[windows] +run: build + +[windows] +build_gfx: compile_shaders_directx + if not exist bin\ mkdir bin + cl /nologo -Zi /c /Fdbin\ /Fobin\ /D_FONT_WIDTH=12 /D_FONT_HEIGHT=24 /DED_GFX_IMPLEMENTATION /std:c11 /TC vendor\pcleavelin\gfx.h + +[windows] +compile_shaders_directx: + if not exist bin\compiled_shaders\ mkdir bin\compiled_shaders diff --git a/src/gfx/gfx.odin b/src/gfx/gfx.odin index b88b214..0be9b6c 100644 --- a/src/gfx/gfx.odin +++ b/src/gfx/gfx.odin @@ -3,7 +3,12 @@ package gfx; import "core:strings" import c "core:c" -foreign import gfx "../../bin/libgfx.a" +when ODIN_OS_STRING == "unix" { + foreign import gfx "../../bin/libgfx.a" +} +when ODIN_OS_STRING == "windows" { + foreign import gfx "../../bin/gfx.obj" +} GfxFrameFunc :: proc "c" (mouse_x: int, mouse_y: int, mouse_left_down: bool, mouse_right_down: bool) diff --git a/vendor/pcleavelin/gfx.h b/vendor/pcleavelin/gfx.h index 49d9e5b..53db9c7 100644 --- a/vendor/pcleavelin/gfx.h +++ b/vendor/pcleavelin/gfx.h @@ -134,6 +134,16 @@ typedef struct { Window window; int screen; } _opengl_gfx_context_x11; +#elif _WIN32 || WIN32 +typedef struct { + int mouse_x, mouse_y; + int mouse_left_down, mouse_right_down; + + array(uint8_t) buffers; + array(uint8_t) textures; +} _directx_gfx_context; + +static void _directx_gfx_present(_directx_gfx_context *cx); #endif typedef void (*_gfx_frame_func)(int mouse_x, int mouse_y, bool mouse_left_down, @@ -144,6 +154,8 @@ typedef struct { #elif __linux__ // TODO: be able to use X11 or Wayland at runtime _opengl_gfx_context_wayland backend; +#elif _WIN32 || WIN32 + _directx_gfx_context backend; #else #error "Unsupported platform" #endif @@ -159,14 +171,13 @@ typedef struct { static gfx_context_t _gfx_context; #ifdef ED_GFX_IMPLEMENTATION +void gfx_update_buffer(gfx_context_t *cx, size_t buffer_index, const void *data, + size_t len); #if defined(__APPLE__) static void _metal_gfx_present(_metal_gfx_context *cx); static void _metal_gfx_send_events(_metal_gfx_context *cx); -void gfx_update_buffer(gfx_context_t *cx, size_t buffer_index, const void *data, - size_t len); - @implementation AppDelegate - (NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication *)sender { @@ -1169,13 +1180,127 @@ static void _opengl_gfx_update_buffer_wayland(_opengl_gfx_context_wayland *cx, const void *data, size_t len) { glNamedBufferSubData(cx->buffers.data[buffer_index], 0, len, data); } +#elif _WIN32 || WIN32 +static _directx_gfx_context +_directx_gfx_init_context(uint32_t width, uint32_t height) { + _directx_gfx_context cx = {0}; + + cx.buffers = newArray(uint8_t, 8); + cx.textures = newArray(uint8_t, 8); + + return cx; +} + +static void _directx_gfx_send_events(_directx_gfx_context *cx) { + // _directx_gfx_present(cx); +} + +static void _directx_gfx_present(_directx_gfx_context *cx) { + _gfx_context.gpu_glyphs.size = 0; + _gfx_context.gpu_ui_rects.size = 0; + _gfx_context.frame_func(cx->mouse_x, cx->mouse_y, cx->mouse_left_down, + cx->mouse_right_down); + + if (_gfx_context.gpu_glyphs.size > 0) { + gfx_update_buffer(&_gfx_context, 2, _gfx_context.gpu_glyphs.data, + _gfx_context.gpu_glyphs.size * sizeof(GpuGlyph)); + } + if (_gfx_context.gpu_ui_rects.size > 0) { + gfx_update_buffer(&_gfx_context, 4, _gfx_context.gpu_ui_rects.data, + _gfx_context.gpu_ui_rects.size * sizeof(GpuUiRect)); + } + + GpuUniformParams gpu_uniform_params = { + .screen_size = + { + (float)_gfx_context.frame_width, + (float)_gfx_context.frame_height, + }, + .font_size = + { + (float)_FONT_WIDTH, + (float)_FONT_HEIGHT, + }, + }; + + gfx_update_buffer(&_gfx_context, 3, &gpu_uniform_params, + sizeof(GpuUniformParams)); + // TODO: clear viewport + + if (_gfx_context.gpu_ui_rects.size > 0) { + // glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, cx->buffers.data[0]); + // glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, cx->buffers.data[4]); + // glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, cx->buffers.data[3]); + // glUseProgram(cx->ui_rect_shader_program); + + // const uint16_t indices[] = {0, 1, 2, 0, 2, 3}; + // glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices, + // _gfx_context.gpu_ui_rects.size); + } + + if (_gfx_context.gpu_glyphs.size > 0) { + // glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, cx->buffers.data[0]); + // glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, cx->buffers.data[2]); + // glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, cx->buffers.data[3]); + // glUseProgram(cx->text_atlas_shader_program); + + // const uint16_t indices[] = {0, 1, 2, 0, 2, 3}; + // glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices, + // _gfx_context.gpu_glyphs.size); + } + + // TODO: commit commands + + // TODO: swap buffers + // if (eglSwapBuffers(cx->egl_display, cx->egl_surface) != EGL_TRUE) { + // fprintf(stderr, "eglSwapBuffers() failed\n"); + // } +} + +static size_t +_directx_gfx_push_texture_buffer(_directx_gfx_context *cx, + uint32_t width, uint32_t height, + const void *data, size_t len) { + pushArray(uint8_t, &cx->textures, 0); + + return cx->textures.size - 1; +} + +static void +_directx_gfx_resize_texture_buffer(_directx_gfx_context *cx, + uint32_t width, size_t texture_index, + uint32_t height) { + // TODO + assert(false && "_directx_gfx_resize_texture_buffer unimplemented"); +} + +size_t _directx_gfx_push_vertex_buffer(_directx_gfx_context *cx, + const void *data, size_t len) { + pushArray(uint8_t, &cx->buffers, 0); + + return cx->buffers.size - 1; +} +static size_t +_directx_gfx_allocate_vertex_buffer(_directx_gfx_context *cx, + size_t len) { + pushArray(uint8_t, &cx->buffers, 0); + + return cx->buffers.size - 1; +} +static int _directx_gfx_update_buffer(_directx_gfx_context *cx, + size_t buffer_index, + const void *data, size_t len) { + return 0; +} #endif void gfx_run_events(gfx_context_t *cx) { #if defined(__APPLE__) - return _metal_gfx_send_events(&cx->backend); + _metal_gfx_send_events(&cx->backend); #elif __linux__ - return _opengl_gfx_send_events_wayland(&cx->backend); + _opengl_gfx_send_events_wayland(&cx->backend); +#elif _WIN32 || WIN32 + _directx_gfx_send_events(&cx->backend); #else #error "Unsupported graphics backend" #endif @@ -1188,6 +1313,9 @@ size_t gfx_push_texture_buffer(gfx_context_t *cx, uint32_t width, #elif __linux__ return _opengl_gfx_push_texture_buffer_wayland(&cx->backend, width, height, data, len); +#elif _WIN32 || WIN32 + return _directx_gfx_push_texture_buffer(&cx->backend, width, height, + data, len); #else #error "Unsupported graphics backend" #endif @@ -1198,6 +1326,8 @@ size_t gfx_push_vertex_buffer(gfx_context_t *cx, const void *data, size_t len) { return _metal_gfx_push_vertex_buffer(&cx->backend, data, len); #elif __linux__ return _opengl_gfx_push_vertex_buffer_wayland(&cx->backend, data, len); +#elif _WIN32 || WIN32 + return _directx_gfx_push_vertex_buffer(&cx->backend, data, len); #else #error "Unsupported graphics backend" #endif @@ -1208,6 +1338,8 @@ size_t gfx_allocate_vertex_buffer(gfx_context_t *cx, size_t len) { return _metal_gfx_allocate_vertex_buffer(&cx->backend, len); #elif __linux__ return _opengl_gfx_allocate_vertex_buffer_wayland(&cx->backend, len); +#elif _WIN32 || WIN32 + return _directx_gfx_allocate_vertex_buffer(&cx->backend, len); #else #error "Unsupported graphics backend" #endif @@ -1217,9 +1349,12 @@ size_t gfx_allocate_vertex_buffer(gfx_context_t *cx, size_t len) { void gfx_update_buffer(gfx_context_t *cx, size_t buffer_index, const void *data, size_t len) { #if defined(__APPLE__) - return _metal_gfx_update_buffer(&cx->backend, buffer_index, data, len); + _metal_gfx_update_buffer(&cx->backend, buffer_index, data, len); #elif __linux__ - return _opengl_gfx_update_buffer_wayland(&cx->backend, buffer_index, data, + _opengl_gfx_update_buffer_wayland(&cx->backend, buffer_index, data, + len); +#elif _WIN32 || WIN32 + _directx_gfx_update_buffer(&cx->backend, buffer_index, data, len); #else #error "Unsupported graphics backend" @@ -1306,11 +1441,12 @@ void gfx_add_glyph(gfx_context_t *cx, GpuGlyph glyph) { void *gfx_init_context(_gfx_frame_func frame_func, uint32_t width, uint32_t height) { - __auto_type backend = #if defined(__APPLE__) - _metal_gfx_init_context(width, height); + _metal_gfx_context backend = _metal_gfx_init_context(width, height); #elif __linux__ - _opengl_gfx_init_context_wayland(width, height); + _opengl_gfx_context_wayland backend = _opengl_gfx_init_context_wayland(width, height); +#elif _WIN32 || WIN32 + _directx_gfx_context backend = _directx_gfx_init_context(width, height); #else #error "Unsupported graphics backend" #endif