commit 061e549
uint
·
2026-07-21 19:39:14 +0000 UTC
parent 1286cb0
sokol opengl renderer this is still a big todo; still gotta do the vulkan one and probably create renderer_hard.c and renderer_soft.c
7 files changed,
+153,
-8
+5,
-2
1@@ -16,8 +16,7 @@ typedef uint64_t u64;
2
3 typedef SDL_Window MGWindow;
4
5-/* video backend !only OpenGL for now */
6-typedef struct {
7+typedef struct { /* video backend !only OpenGL for now */
8 SDL_GLContext gl;
9 } MGVidBE;
10
11@@ -31,6 +30,10 @@ typedef struct {
12 i32 height;
13 } MGContext;
14
15+/* get drawable screen size. usually different due to hi-dpi options
16+ > probably can stub out on software renderer */
17+void platform_get_drawable_size(MGContext* ctx, i32* width, i32* height);
18+
19 /* initialise resources */
20 void platform_init(MGContext* ctx);
21
+26,
-0
1@@ -0,0 +1,26 @@
2+#ifndef RENDERER_H
3+#define RENDERER_H
4+
5+#include <platform/platform.h>
6+
7+typedef struct {
8+ MGContext* ctx;
9+ i8 pass; /* basically a bool; in
10+ render pass or not */
11+} MGRenderer;
12+
13+/* create renderer with chosen context
14+ (just GL for now) */
15+void renderer_create(MGContext* ctx, MGRenderer* ren);
16+
17+/* start drawing to screen */
18+void renderer_begin(MGRenderer* ren);
19+
20+/* finish drawing to screen */
21+void renderer_end(MGRenderer* ren);
22+
23+/* destroy renderer resources */
24+void renderer_destroy(MGRenderer* ren);
25+
26+#endif /* RENDERER_H */
27+
+3,
-1
1@@ -3,12 +3,14 @@
2
3 #include <stdio.h>
4
5-typedef enum {
6+typedef enum { /* TODO: rename to MG_EC_... */
7 MG_ERR_EXIT_SUCCESS,
8 MG_ERR_EXIT_FAILURE,
9
10 MG_ERR_GL_CTX_CREATE,
11
12+ MG_ERR_REN_CREATE,
13+
14 MG_ERR_LAST
15 } MGErrorCodes;
16
+28,
-5
1@@ -9,33 +9,56 @@ project(
2
3 sources = [
4 'source/main.c',
5- 'source/platform/platform.c',
6 'source/util.c',
7+ 'source/platform/platform.c',
8+]
9+
10+include_dirs = [
11+ include_directories('include'),
12 ]
13
14 vendor_inc = [
15 include_directories('vendor'),
16 ]
17+
18+opengl_dep = dependency('opengl', required: false)
19+if not opengl_dep.found() # fallback (at least for alpine)
20+ opengl_dep = dependency('gl')
21+endif
22+
23 sokol_gfx_lib = static_library(
24 'sokol_gfx',
25 'vendor/sokol_gfx.c',
26 include_directories: vendor_inc,
27+ dependencies: opengl_dep,
28 override_options: [ 'c_std=c99' ],
29 )
30
31 sokol_gfx_dep = declare_dependency(
32 include_directories: vendor_inc,
33 link_with: sokol_gfx_lib,
34+ dependencies: opengl_dep,
35+)
36+
37+renderer_lib = static_library(
38+ 'renderer',
39+ 'source/renderer/renderer.c',
40+ include_directories: include_dirs,
41+ dependencies: sokol_gfx_dep,
42+ override_options: [ 'c_std=c99' ],
43+)
44+
45+renderer_dep = declare_dependency(
46+ include_directories: include_dirs,
47+ link_with: renderer_lib,
48+ dependencies: sokol_gfx_dep,
49 )
50
51 deps = [
52 dependency('sdl2'),
53- sokol_gfx_dep,
54+ renderer_dep,
55 ]
56
57-include_dirs = [
58- include_directories('include'),
59-]
60 executable(
61 'magnolia',
62 sources,
+9,
-0
1@@ -2,6 +2,7 @@
2
3 #include "util.h"
4 #include "platform/platform.h"
5+#include "renderer/renderer.h"
6
7 int main(void)
8 {
9@@ -12,6 +13,7 @@ int main(void)
10 0, 0, /* x, y */
11 1024, 768, /* w, h */
12 };
13+ MGRenderer ren;
14
15 mg_log(LOG_INF, "test log info");
16 mg_log(LOG_ERR, "test log error");
17@@ -19,12 +21,19 @@ int main(void)
18
19 platform_init(&ctx);
20 platform_window_create(&ctx);
21+ renderer_create(&ctx, &ren);
22
23 while (platform_poll(&ctx)) {
24+ renderer_begin(&ren);
25+
26+ /* ... */
27+
28+ renderer_end(&ren);
29 platform_present(&ctx);
30 SDL_Delay(1); /* TODO: replace with target fps */
31 }
32
33+ renderer_destroy(&ren);
34 platform_shutdown(&ctx);
35 return MG_ERR_EXIT_SUCCESS;
36 }
+5,
-0
1@@ -3,6 +3,11 @@
2 #include "util.h"
3 #include "platform/platform.h"
4
5+void platform_get_drawable_size(MGContext* ctx, i32* width, i32* height)
6+{
7+ SDL_GL_GetDrawableSize(ctx->win, width, height);
8+}
9+
10 void platform_init(MGContext* ctx)
11 {
12 (void) ctx;
+77,
-0
1@@ -0,0 +1,77 @@
2+#include <sokol_gfx.h>
3+
4+#include "util.h"
5+#include "platform/platform.h"
6+#include "renderer/renderer.h"
7+
8+void renderer_create(MGContext* ctx, MGRenderer* ren)
9+{
10+ sg_desc desc = {0};
11+
12+ ren->ctx = ctx;
13+ ren->pass = 0;
14+
15+ desc.environment.defaults.color_format = SG_PIXELFORMAT_RGBA8;
16+ desc.environment.defaults.depth_format = SG_PIXELFORMAT_DEPTH;
17+ desc.environment.defaults.sample_count = 1;
18+
19+ sg_setup(&desc);
20+
21+ if (!sg_isvalid())
22+ mg_die(MG_ERR_REN_CREATE, "Failed to initialise renderer");
23+}
24+
25+void renderer_begin(MGRenderer* ren)
26+{
27+ sg_pass pass = {0};
28+ i32 width;
29+ i32 height;
30+
31+ ren->pass = 0;
32+
33+ platform_get_drawable_size(ren->ctx, &width, &height);
34+ /* (minimized window?) no need to draw */
35+ if (width <= 0 || height <= 0)
36+ return;
37+
38+ pass.action.colors[0].load_action = SG_LOADACTION_CLEAR;
39+ pass.action.colors[0].clear_value.r = 0.90f;
40+ pass.action.colors[0].clear_value.g = 0.80f;
41+ pass.action.colors[0].clear_value.b = 0.70f;
42+ pass.action.colors[0].clear_value.a = 1.00f;
43+
44+ pass.action.depth.load_action = SG_LOADACTION_CLEAR;
45+ pass.action.depth.clear_value = 1.0f;
46+
47+ /* swapchain descriptor */
48+ pass.swapchain.width = width;
49+ pass.swapchain.height = height;
50+ pass.swapchain.sample_count = 1;
51+ pass.swapchain.color_format = SG_PIXELFORMAT_RGBA8;
52+ pass.swapchain.depth_format = SG_PIXELFORMAT_DEPTH;
53+
54+ pass.swapchain.gl.framebuffer = 0;
55+
56+ sg_begin_pass(&pass);
57+ ren->pass = 1;
58+}
59+
60+void renderer_end(MGRenderer* ren)
61+{
62+ if (!ren->pass)
63+ return;
64+
65+ sg_end_pass();
66+ sg_commit();
67+
68+ ren->pass = 0;
69+}
70+
71+void renderer_destroy(MGRenderer* ren)
72+{
73+ if (sg_isvalid())
74+ sg_shutdown();
75+ ren->ctx = NULL;
76+ ren->pass = 0;
77+}
78+