From 27aaa8e05d17fedca4bf4c889f08bd2cd48135d8 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 19 Sep 2023 02:55:37 +0000 Subject: [PATCH] Metal rendering works; high dpi rendering works; fix sokol_gfx_ext to work with metal without SDL --- Makefile | 5 +- scripts/entity.js | 9 ++- source/engine/debug/debugdraw.c | 4 +- source/engine/nuke.c | 16 ++-- source/engine/nuke.h | 5 +- source/engine/render.c | 74 ++++++++++++++----- source/engine/render.h | 3 +- source/engine/sprite.c | 7 +- .../engine/thirdparty/sokol/sokol_gfx_ext.h | 8 +- source/engine/window.c | 8 +- source/engine/window.h | 3 + source/engine/yugine.c | 26 +------ 12 files changed, 93 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 9daa5d9..e237a73 100755 --- a/Makefile +++ b/Makefile @@ -95,8 +95,7 @@ else ifeq ($(UNAME), Darwin) CFLAGS += -x objective-c LDFLAGS += -framework Cocoa -framework QuartzCore -framework AudioToolbox -# LDFLAGS += -framework Metal -framework MetalKit - LDFLAGS += -framework OpenGL + LDFLAGS += -framework Metal -framework MetalKit PLAT = osx-$(ARCH)$(INFO) endif endif @@ -117,7 +116,7 @@ includeflag := $(addprefix -I, $(includeflag)) WARNING_FLAGS = -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types -Wno-unused-function -Wno-unused-const-variable -NAME = yugine$(EXT) +NAME = primum$(EXT) SEM = 0.0.1 COM != fossil describe VER = $(SEM)-$(COM) diff --git a/scripts/entity.js b/scripts/entity.js index 11aecfb..ad966a4 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -562,14 +562,17 @@ prototypes.from_obj("camera2d", { speedmult: 1.0, selectable: false, + + world2this(pos) { return cmd(70, this.body, pos); }, + this2world(pos) { return cmd(71, this.body,pos); }, + view2world(pos) { - pos.y *= -1; - return pos.add([-Window.width,Window.height].scale(0.5)).scale(this.zoom).add(this.pos); + return cmd(137,pos); }, world2view(pos) { - return pos.sub(this.pos).scale(1/this.zoom).add(Window.dimensions.scale(0.5)); + return cmd(136,pos); }, }); diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 6d88506..edea6c9 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -554,8 +554,8 @@ void draw_grid(float width, float span, struct rgba color) float ubo[4]; ubo[0] = offset.x; ubo[1] = offset.y; - ubo[2] = mainwin.width; - ubo[3] = mainwin.height; + ubo[2] = mainwin.rwidth; + ubo[3] = mainwin.rheight; sg_apply_pipeline(grid_pipe); sg_apply_bindings(&grid_bind); diff --git a/source/engine/nuke.c b/source/engine/nuke.c index 4c0701b..e28d2bc 100644 --- a/source/engine/nuke.c +++ b/source/engine/nuke.c @@ -1,17 +1,14 @@ #include "nuke.h" #ifndef NO_EDITOR - -#define STBTT_STATIC - #include "config.h" -#include "sokol/sokol_gfx.h" - +#define NK_PRIVATE +#define STB_IMAGE_STATIC +#define STBTT_STATIC #define NK_IMPLEMENTATION -#define SOKOL_NUKLEAR_IMPL #include "nuklear.h" -#include "sokol/sokol_app.h" +#define SOKOL_NUKLEAR_IMPL #include "sokol/sokol_nuklear.h" #include @@ -27,7 +24,8 @@ struct nk_context *ctx; void nuke_init(struct window *win) { snk_setup(&(snk_desc_t){ - .no_default_font = false + .no_default_font = false, + .dpi_scale = sapp_dpi_scale(), }); ctx = snk_new_frame(); @@ -58,7 +56,7 @@ void nuke_start() { } void nuke_end() { - snk_render(mainwin.width,mainwin.height); + snk_render(sapp_width(), sapp_height()); } int nuke_begin(const char *lbl, struct rect rect) { diff --git a/source/engine/nuke.h b/source/engine/nuke.h index 467150e..1fc9370 100644 --- a/source/engine/nuke.h +++ b/source/engine/nuke.h @@ -13,9 +13,10 @@ #define NK_INCLUDE_DEFAULT_ALLOCATOR #define NK_INCLUDE_STANDARD_IO #define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#include "nuklear.h" -#include "sokol/sokol_app.h" + #include "sokol/sokol_gfx.h" +#include "sokol/sokol_app.h" +#include "nuklear.h" #include "sokol/sokol_nuklear.h" struct window; diff --git a/source/engine/render.c b/source/engine/render.c index 5cfaa26..d3777ca 100644 --- a/source/engine/render.c +++ b/source/engine/render.c @@ -16,22 +16,15 @@ #include "resources.h" #include "yugine.h" #include "sokol/sokol_app.h" - -#define SOKOL_GLUE_IMPL #include "sokol/sokol_glue.h" #include "crt.sglsl.h" #include "box.sglsl.h" #include "shadow.sglsl.h" -#define SOKOL_TRACE_HOOKS -#define SOKOL_GFX_IMPL #include "sokol/sokol_gfx.h" - -#define SOKOL_GFX_EXT_IMPL #include "sokol/sokol_gfx_ext.h" -#define MSF_GIF_IMPL #include "msf_gif.h" static struct { @@ -77,6 +70,7 @@ void gif_rec_start(int w, int h, int cpf, int bitdepth) .render_target = true, .width = gif.w, .height = gif.h, + .pixel_format = SG_PIXELFORMAT_RGBA8 }); sg_gif.depth = sg_make_image(&(sg_image_desc){ @@ -251,7 +245,8 @@ void render_init() { [0].format = SG_VERTEXFORMAT_FLOAT2, [1].format = SG_VERTEXFORMAT_FLOAT2 } - } + }, + .colors[0].pixel_format = SG_PIXELFORMAT_RGBA8 }); crt_post.pipe = sg_make_pipeline(&(sg_pipeline_desc){ @@ -282,6 +277,7 @@ void render_init() { .depth_stencil_attachment.image = crt_post.depth_img, }); +#if defined SOKOL_GLCORE33 || defined SOKOL_GLES3 float crt_quad[] = { -1, 1, 0, 1, -1, -1, 0, 0, @@ -290,6 +286,31 @@ void render_init() { 1, -1, 1, 0, 1, 1, 1, 1 }; +#else + float crt_quad[] = { + -1, 1, 0, 0, + -1, -1, 0, 1, + 1, -1, 1, 1, + -1, 1, 0, 0, + 1, -1, 1, 1, + 1, 1, 1, 0 + }; +#endif + float gif_quad[] = { + -1, 1, 0, 1, + -1, -1, 0, 0, + 1, -1, 1, 0, + -1, 1, 0, 1, + 1, -1, 1, 0, + 1, 1, 1, 1 + }; + + sg_gif.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ + .size = sizeof(gif_quad), + .data = gif_quad, + }); + sg_gif.bind.fs.images[0] = crt_post.img; + sg_gif.bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); crt_post.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ .size = sizeof(crt_quad), @@ -364,7 +385,8 @@ void render_winsize() .depth_stencil_attachment.image = crt_post.depth_img, }); - crt_post.bind.fs.images[0] = crt_post.img; + crt_post.bind.fs.images[0] = crt_post.img; + sg_gif.bind.fs.images[0] = crt_post.img; } static cpBody *camera = NULL; @@ -384,15 +406,18 @@ HMM_Vec2 world2screen(HMM_Vec2 pos) { pos = HMM_SubV2(pos, HMM_V2(cam_pos().x, cam_pos().y)); pos = HMM_ScaleV2(pos, 1.0/zoom); - pos = HMM_AddV2(pos, HMM_V2(mainwin.width/2.0, mainwin.height/2.0)); + pos = HMM_AddV2(pos, HMM_V2(mainwin.rwidth/2.0, mainwin.rheight/2.0)); return pos; } HMM_Vec2 screen2world(HMM_Vec2 pos) { - pos = HMM_AddV2(pos, HMM_V2(mainwin.width/2.0, mainwin.height/2.0)); - pos = HMM_MulV2(pos, HMM_V2(zoom,zoom)); - return HMM_AddV2(pos, HMM_V2(cam_pos().x, cam_pos().y)); + pos.Y *= -1; + pos = HMM_ScaleV2(pos, 1/mainwin.dpi); + pos = HMM_AddV2(pos, HMM_V2(-mainwin.rwidth/2.0, mainwin.rheight/2.0)); + pos = HMM_ScaleV2(pos, zoom); + pos = HMM_AddV2(pos, HMM_V2(cam_pos().x, cam_pos().y)); + return pos; } HMM_Mat4 projection = {0.f}; @@ -405,14 +430,23 @@ void full_2d_pass(struct window *window) //////////// 2D projection cpVect pos = cam_pos(); - projection = HMM_Orthographic_RH_NO( - pos.x - zoom * window->width / 2, - pos.x + zoom * window->width / 2, - pos.y - zoom * window->height / 2, - pos.y + zoom * window->height / 2, -1.f, 1.f); +#if defined SOKOL_GLCORE33 || defined SOKOL_GLES3 + projection = HMM_Orthographic_RH_ZO( + pos.x - zoom * window->rwidth / 2, + pos.x + zoom * window->rwidth / 2, + pos.y + zoom * window->rheight / 2, + pos.y - zoom * window->rheight / 2, -1.f, 1.f); - hudproj = HMM_Orthographic_RH_NO(0, window->width, 0, window->height, -1.f, 1.f); + hudproj = HMM_Orthographic_RH_ZO(0, window->width, window->height, 0, -1.f, 1.f); +#else + projection = HMM_Orthographic_LH_ZO( + pos.x - zoom * window->rwidth / 2, + pos.x + zoom * window->rwidth / 2, + pos.y - zoom * window->rheight / 2, + pos.y + zoom * window->rheight / 2, -1.f, 1.f); + hudproj = HMM_Orthographic_LH_ZO(0, window->rwidth, 0, window->rheight, -1.f, 1.f); +#endif sprite_draw_all(); call_draw(); @@ -473,7 +507,7 @@ void openglRender(struct window *window) { if (gif.rec && (appTime - gif.timer) > gif.spf) { sg_begin_pass(sg_gif.pass, &pass_action); sg_apply_pipeline(sg_gif.pipe); - sg_apply_bindings(&crt_post.bind); + sg_apply_bindings(&sg_gif.bind); sg_draw(0,6,1); sg_end_pass(); diff --git a/source/engine/render.h b/source/engine/render.h index 0afbfd2..5b42815 100644 --- a/source/engine/render.h +++ b/source/engine/render.h @@ -9,8 +9,7 @@ #define SOKOL_GLCORE33 #define SOKOL_WIN32_FORCE_MAIN #elif __APPLE__ -// #define SOKOL_METAL - #define SOKOL_GLCORE33 + #define SOKOL_METAL #endif #include "sokol/sokol_gfx.h" diff --git a/source/engine/sprite.c b/source/engine/sprite.c index 7b822ed..ac305a8 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -176,9 +176,10 @@ void sprite_initialize() { .layout = { .attrs = { [0].format = SG_VERTEXFORMAT_FLOAT2, - [1].format = SG_VERTEXFORMAT_USHORT4N, - [2].format = SG_VERTEXFORMAT_FLOAT2, - [3].format = SG_VERTEXFORMAT_UBYTE4N + [1].format = SG_VERTEXFORMAT_FLOAT2, + [2].format = SG_VERTEXFORMAT_USHORT4N, + [3].format = SG_VERTEXFORMAT_FLOAT2, + [4].format = SG_VERTEXFORMAT_UBYTE4N }}, .primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP, }); diff --git a/source/engine/thirdparty/sokol/sokol_gfx_ext.h b/source/engine/thirdparty/sokol/sokol_gfx_ext.h index 26f0c6a..7b3e14e 100644 --- a/source/engine/thirdparty/sokol/sokol_gfx_ext.h +++ b/source/engine/thirdparty/sokol/sokol_gfx_ext.h @@ -292,13 +292,7 @@ static void _sg_metal_encode_texture_pixels(int x, int y, int w, int h, bool ori [cmd_buffer waitUntilCompleted]; MTLRegion mtl_region = MTLRegionMake2D(0, 0, w, h); - void* temp_pixels = malloc(w * 4 * h); - SOKOL_ASSERT(temp_pixels); - [mtl_dst_texture getBytes:temp_pixels bytesPerRow:w * 4 fromRegion:mtl_region mipmapLevel:0]; - // int res = SDL_ConvertPixels(w, h, _sg_metal_texture_format_to_sdl_pixel_format(mtl_dst_texture_desc.pixelFormat), temp_pixels, w * 4, SDL_PIXELFORMAT_RGBA32, pixels, w * 4); - free(temp_pixels); - // SOKOL_ASSERT(res == 0); - // _SOKOL_UNUSED(res); + [mtl_dst_texture getBytes:pixels bytesPerRow:w * 4 fromRegion:mtl_region mipmapLevel:0]; } static void _sg_metal_query_image_pixels(_sg_image_t* img, void* pixels) { diff --git a/source/engine/window.c b/source/engine/window.c index 0a91027..da2c98d 100644 --- a/source/engine/window.c +++ b/source/engine/window.c @@ -24,8 +24,12 @@ struct Texture *icon = NULL; void window_resize(int width, int height) { - mainwin.width = width; - mainwin.height = height; + mainwin.dpi = sapp_dpi_scale(); + mainwin.width = sapp_width(); + mainwin.height = sapp_height(); + mainwin.rwidth = mainwin.width/mainwin.dpi; + mainwin.rheight = mainwin.height/mainwin.dpi; + render_winsize(); JSValue vals[2] = { int2js(width), int2js(height) }; diff --git a/source/engine/window.h b/source/engine/window.h index a28c835..6fde8ed 100644 --- a/source/engine/window.h +++ b/source/engine/window.h @@ -10,6 +10,9 @@ struct window { int id; int width; int height; + double dpi; + int rwidth; + int rheight; bool render; bool mouseFocus; bool keyboardFocus; diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 0756195..207d859 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -38,34 +38,16 @@ #include "nuke.h" #endif -#define SOKOL_TRACE_HOOKS -#define SOKOL_IMPL +#include "render.h" #include "sokol/sokol_app.h" #include "sokol/sokol_audio.h" #include "sokol/sokol_time.h" #include "sokol/sokol_args.h" - -#define STB_DS_IMPLEMENTATION #include - -#define STB_TRUETYPE_IMPLEMENTATION -#define STB_TRUETYPE_NO_STDIO #include - -#define STB_IMAGE_IMPLEMENTATION -#define STBI_FAILURE_USERMSG -#define STBI_NO_STDIO -#ifdef __TINYC__ -#define STBI_NO_SIMD -#endif #include "stb_image.h" - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_BOX #include "stb_image_write.h" - -#define PL_MPEG_IMPLEMENTATION #include #include "debug.h" @@ -151,7 +133,7 @@ static char **args; void c_init() { render_init(); - + window_resize(sapp_width(), sapp_height()); script_evalf("initialize();"); } @@ -207,7 +189,7 @@ void c_frame() } void c_clean() { - gif_rec_end("crash.gif"); + gif_rec_end("out.gif"); }; void c_event(const sapp_event *e) @@ -309,7 +291,7 @@ static sapp_desc start_desc = { .high_dpi = 0, .sample_count = 1, .fullscreen = 1, - .window_title = "Yugine", + .window_title = "Primum Machinam", .enable_clipboard = false, .clipboard_size = 0, .enable_dragndrop = true,