stub all directx wrappers

main
Patrick Cleavelin 2024-05-25 16:26:43 -05:00
parent f47ad817f1
commit 68666af0cc
3 changed files with 178 additions and 16 deletions

View File

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

View File

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

View File

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