summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-03-09 09:29:52 -0800
committer3gg <3gg@shellblade.net>2024-03-09 09:29:52 -0800
commit88ab79e436aec6ede0fca4949570f534ffb1b853 (patch)
tree4b362ac106f8cc7aa49013cad9d288aba6b1d4d2
parentf9e38bf24e1874d773083d06ca443cce9bd92d56 (diff)
Rename RenderBackend -> GfxCore.
-rw-r--r--game/src/game.c12
-rw-r--r--game/src/plugins/texture_view.c8
-rw-r--r--game/src/plugins/viewer.c22
-rw-r--r--gfx-iso/src/app.c36
-rw-r--r--gfx/CMakeLists.txt2
-rw-r--r--gfx/include/gfx/asset.h2
-rw-r--r--gfx/include/gfx/core.h (renamed from gfx/include/gfx/render_backend.h)49
-rw-r--r--gfx/include/gfx/gfx.h10
-rw-r--r--gfx/include/gfx/renderer.h6
-rw-r--r--gfx/include/gfx/scene/material.h2
-rw-r--r--gfx/include/gfx/util/geometry.h6
-rw-r--r--gfx/include/gfx/util/ibl.h21
-rw-r--r--gfx/include/gfx/util/shader.h26
-rw-r--r--gfx/include/gfx/util/skyquad.h14
-rw-r--r--gfx/src/asset/asset_cache.c4
-rw-r--r--gfx/src/asset/model.c69
-rw-r--r--gfx/src/asset/texture.c9
-rw-r--r--gfx/src/asset/texture.h2
-rw-r--r--gfx/src/gfx.c22
-rw-r--r--gfx/src/render/buffer.c4
-rw-r--r--gfx/src/render/buffer.h2
-rw-r--r--gfx/src/render/core.c (renamed from gfx/src/render/render_backend.c)209
-rw-r--r--gfx/src/render/core_impl.h (renamed from gfx/src/render/render_backend_impl.h)10
-rw-r--r--gfx/src/render/framebuffer.h2
-rw-r--r--gfx/src/render/geometry.c101
-rw-r--r--gfx/src/render/geometry.h6
-rw-r--r--gfx/src/render/renderbuffer.h2
-rw-r--r--gfx/src/render/shader.h2
-rw-r--r--gfx/src/render/shader_program.h6
-rw-r--r--gfx/src/render/texture.h2
-rw-r--r--gfx/src/renderer/imm_renderer.c29
-rw-r--r--gfx/src/renderer/imm_renderer_impl.h4
-rw-r--r--gfx/src/renderer/renderer.c62
-rw-r--r--gfx/src/renderer/renderer_impl.h8
-rw-r--r--gfx/src/scene/material.c2
-rw-r--r--gfx/src/scene/object.c2
-rw-r--r--gfx/src/util/geometry.c12
-rw-r--r--gfx/src/util/ibl.c106
-rw-r--r--gfx/src/util/shader.c76
-rw-r--r--gfx/src/util/skyquad.c22
40 files changed, 473 insertions, 518 deletions
diff --git a/game/src/game.c b/game/src/game.c
index bc85691..425119f 100644
--- a/game/src/game.c
+++ b/game/src/game.c
@@ -11,8 +11,8 @@
11#include "plugins/plugin.h" 11#include "plugins/plugin.h"
12 12
13#include <gfx/app.h> 13#include <gfx/app.h>
14#include <gfx/core.h>
14#include <gfx/gfx.h> 15#include <gfx/gfx.h>
15#include <gfx/render_backend.h>
16#include <gfx/renderer.h> 16#include <gfx/renderer.h>
17#include <gfx/scene/camera.h> 17#include <gfx/scene/camera.h>
18#include <gfx/scene/node.h> 18#include <gfx/scene/node.h>
@@ -204,18 +204,18 @@ void app_update(Game* game, double t, double dt) {
204} 204}
205 205
206void app_render(const Game* game) { 206void app_render(const Game* game) {
207 RenderBackend* render_backend = gfx_get_render_backend(game->gfx); 207 GfxCore* gfxcore = gfx_get_core(game->gfx);
208 gfx_start_frame(render_backend); 208 gfx_start_frame(gfxcore);
209 render_plugin(game); 209 render_plugin(game);
210 gfx_end_frame(render_backend); 210 gfx_end_frame(gfxcore);
211} 211}
212 212
213void app_resize(Game* game, int width, int height) { 213void app_resize(Game* game, int width, int height) {
214 game->width = width; 214 game->width = width;
215 game->height = height; 215 game->height = height;
216 216
217 RenderBackend* render_backend = gfx_get_render_backend(game->gfx); 217 GfxCore* gfxcore = gfx_get_core(game->gfx);
218 gfx_set_viewport(render_backend, width, height); 218 gfx_set_viewport(gfxcore, width, height);
219 219
220 resize_plugin(game, width, height); 220 resize_plugin(game, width, height);
221} 221}
diff --git a/game/src/plugins/texture_view.c b/game/src/plugins/texture_view.c
index 52dff57..a8b2a94 100644
--- a/game/src/plugins/texture_view.c
+++ b/game/src/plugins/texture_view.c
@@ -1,7 +1,7 @@
1#include "plugin.h" 1#include "plugin.h"
2 2
3#include <gfx/asset.h> 3#include <gfx/asset.h>
4#include <gfx/render_backend.h> 4#include <gfx/core.h>
5#include <gfx/renderer.h> 5#include <gfx/renderer.h>
6#include <gfx/scene.h> 6#include <gfx/scene.h>
7#include <gfx/util/geometry.h> 7#include <gfx/util/geometry.h>
@@ -33,7 +33,7 @@ bool init(Game* game, State** pp_state) {
33 // Usage: [texture file] 33 // Usage: [texture file]
34 const char* texture_file = game->argc > 1 ? game->argv[1] : DEFAULT_TEXTURE; 34 const char* texture_file = game->argc > 1 ? game->argv[1] : DEFAULT_TEXTURE;
35 35
36 RenderBackend* render_backend = gfx_get_render_backend(game->gfx); 36 GfxCore* gfxcore = gfx_get_core(game->gfx);
37 37
38 const Texture* texture = gfx_load_texture( 38 const Texture* texture = gfx_load_texture(
39 game->gfx, &(LoadTextureCmd){ 39 game->gfx, &(LoadTextureCmd){
@@ -46,12 +46,12 @@ bool init(Game* game, State** pp_state) {
46 goto cleanup; 46 goto cleanup;
47 } 47 }
48 48
49 ShaderProgram* shader = gfx_make_view_texture_shader(render_backend); 49 ShaderProgram* shader = gfx_make_view_texture_shader(gfxcore);
50 if (!shader) { 50 if (!shader) {
51 goto cleanup; 51 goto cleanup;
52 } 52 }
53 53
54 Geometry* geometry = gfx_make_quad_11(render_backend); 54 Geometry* geometry = gfx_make_quad_11(gfxcore);
55 if (!geometry) { 55 if (!geometry) {
56 goto cleanup; 56 goto cleanup;
57 } 57 }
diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c
index 5e8d7d3..f621b00 100644
--- a/game/src/plugins/viewer.c
+++ b/game/src/plugins/viewer.c
@@ -58,14 +58,14 @@ static SceneNode* load_skyquad(Gfx* gfx, SceneNode* root) {
58 assert(gfx); 58 assert(gfx);
59 assert(root); 59 assert(root);
60 60
61 RenderBackend* render_backend = gfx_get_render_backend(gfx); 61 GfxCore* gfxcore = gfx_get_core(gfx);
62 62
63 const Texture* environment_map = load_environment_map(gfx); 63 const Texture* environment_map = load_environment_map(gfx);
64 if (!environment_map) { 64 if (!environment_map) {
65 return 0; 65 return 0;
66 } 66 }
67 67
68 return gfx_setup_skyquad(render_backend, root, environment_map); 68 return gfx_setup_skyquad(gfxcore, root, environment_map);
69} 69}
70 70
71/// Load the 3D scene. 71/// Load the 3D scene.
@@ -222,17 +222,17 @@ static void render_bounding_boxes(const Game* game, const State* state) {
222 assert(game); 222 assert(game);
223 assert(state); 223 assert(state);
224 224
225 RenderBackend* render_backend = gfx_get_render_backend(game->gfx); 225 GfxCore* gfxcore = gfx_get_core(game->gfx);
226 ImmRenderer* imm = gfx_get_imm_renderer(game->gfx); 226 ImmRenderer* imm = gfx_get_imm_renderer(game->gfx);
227 assert(render_backend); 227 assert(gfxcore);
228 assert(imm); 228 assert(imm);
229 229
230 const mat4 id = mat4_id(); 230 const mat4 id = mat4_id();
231 Anima* anima = 0; 231 Anima* anima = 0;
232 232
233 gfx_set_blending(render_backend, true); 233 gfx_set_blending(gfxcore, true);
234 gfx_set_depth_mask(render_backend, false); 234 gfx_set_depth_mask(gfxcore, false);
235 gfx_set_polygon_offset(render_backend, -1.5f, -1.0f); 235 gfx_set_polygon_offset(gfxcore, -1.5f, -1.0f);
236 236
237 gfx_imm_start(imm); 237 gfx_imm_start(imm);
238 gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera)); 238 gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera));
@@ -240,9 +240,9 @@ static void render_bounding_boxes(const Game* game, const State* state) {
240 render_bounding_boxes_rec(imm, anima, &id, gfx_get_scene_root(state->scene)); 240 render_bounding_boxes_rec(imm, anima, &id, gfx_get_scene_root(state->scene));
241 gfx_imm_end(imm); 241 gfx_imm_end(imm);
242 242
243 gfx_reset_polygon_offset(render_backend); 243 gfx_reset_polygon_offset(gfxcore);
244 gfx_set_depth_mask(render_backend, true); 244 gfx_set_depth_mask(gfxcore, true);
245 gfx_set_blending(render_backend, false); 245 gfx_set_blending(gfxcore, false);
246} 246}
247 247
248void render(const Game* game, const State* state) { 248void render(const Game* game, const State* state) {
diff --git a/gfx-iso/src/app.c b/gfx-iso/src/app.c
index 8e0a45a..e07f318 100644
--- a/gfx-iso/src/app.c
+++ b/gfx-iso/src/app.c
@@ -2,8 +2,8 @@
2#include <isogfx/isogfx.h> 2#include <isogfx/isogfx.h>
3 3
4#include <gfx/app.h> 4#include <gfx/app.h>
5#include <gfx/core.h>
5#include <gfx/gfx.h> 6#include <gfx/gfx.h>
6#include <gfx/render_backend.h>
7#include <gfx/renderer.h> 7#include <gfx/renderer.h>
8#include <gfx/scene.h> 8#include <gfx/scene.h>
9#include <gfx/util/geometry.h> 9#include <gfx/util/geometry.h>
@@ -58,26 +58,26 @@ static bool init(GfxAppState* gfx_app_state, int argc, const char** argv) {
58 if (!(state->gfx = gfx_init())) { 58 if (!(state->gfx = gfx_init())) {
59 goto cleanup; 59 goto cleanup;
60 } 60 }
61 RenderBackend* render_backend = gfx_get_render_backend(state->gfx); 61 GfxCore* gfxcore = gfx_get_core(state->gfx);
62 62
63 if (!(state->screen_texture = gfx_make_texture( 63 if (!(state->screen_texture = gfx_make_texture(
64 render_backend, &(TextureDesc){ 64 gfxcore, &(TextureDesc){
65 .width = texture_width, 65 .width = texture_width,
66 .height = texture_height, 66 .height = texture_height,
67 .dimension = Texture2D, 67 .dimension = Texture2D,
68 .format = TextureSRGBA8, 68 .format = TextureSRGBA8,
69 .filtering = NearestFiltering, 69 .filtering = NearestFiltering,
70 .wrap = ClampToEdge, 70 .wrap = ClampToEdge,
71 .mipmaps = false}))) { 71 .mipmaps = false}))) {
72 goto cleanup; 72 goto cleanup;
73 } 73 }
74 74
75 ShaderProgram* shader = gfx_make_view_texture_shader(render_backend); 75 ShaderProgram* shader = gfx_make_view_texture_shader(gfxcore);
76 if (!shader) { 76 if (!shader) {
77 goto cleanup; 77 goto cleanup;
78 } 78 }
79 79
80 Geometry* geometry = gfx_make_quad_11(render_backend); 80 Geometry* geometry = gfx_make_quad_11(gfxcore);
81 if (!geometry) { 81 if (!geometry) {
82 goto cleanup; 82 goto cleanup;
83 } 83 }
@@ -155,22 +155,22 @@ static void render(GfxAppState* gfx_app_state) {
155 gfx_update_texture( 155 gfx_update_texture(
156 state->screen_texture, &(TextureDataDesc){.pixels = screen}); 156 state->screen_texture, &(TextureDataDesc){.pixels = screen});
157 157
158 RenderBackend* render_backend = gfx_get_render_backend(state->gfx); 158 GfxCore* gfxcore = gfx_get_core(state->gfx);
159 Renderer* renderer = gfx_get_renderer(state->gfx); 159 Renderer* renderer = gfx_get_renderer(state->gfx);
160 160
161 gfx_start_frame(render_backend); 161 gfx_start_frame(gfxcore);
162 gfx_render_scene( 162 gfx_render_scene(
163 renderer, &(RenderSceneParams){ 163 renderer, &(RenderSceneParams){
164 .mode = RenderDefault, .scene = state->scene, .camera = 0}); 164 .mode = RenderDefault, .scene = state->scene, .camera = 0});
165 gfx_end_frame(render_backend); 165 gfx_end_frame(gfxcore);
166} 166}
167 167
168static void resize(GfxAppState* gfx_app_state, int width, int height) { 168static void resize(GfxAppState* gfx_app_state, int width, int height) {
169 assert(gfx_app_state); 169 assert(gfx_app_state);
170 AppState* state = &gfx_app_state->state; 170 AppState* state = &gfx_app_state->state;
171 171
172 RenderBackend* render_backend = gfx_get_render_backend(state->gfx); 172 GfxCore* gfxcore = gfx_get_core(state->gfx);
173 gfx_set_viewport(render_backend, width, height); 173 gfx_set_viewport(gfxcore, width, height);
174} 174}
175 175
176void iso_run(int argc, const char** argv, IsoGfxApp* app) { 176void iso_run(int argc, const char** argv, IsoGfxApp* app) {
diff --git a/gfx/CMakeLists.txt b/gfx/CMakeLists.txt
index 6c8640c..c835bd9 100644
--- a/gfx/CMakeLists.txt
+++ b/gfx/CMakeLists.txt
@@ -37,9 +37,9 @@ add_library(gfx SHARED
37 src/asset/model.c 37 src/asset/model.c
38 src/asset/texture.c 38 src/asset/texture.c
39 src/render/buffer.c 39 src/render/buffer.c
40 src/render/core.c
40 src/render/framebuffer.c 41 src/render/framebuffer.c
41 src/render/geometry.c 42 src/render/geometry.c
42 src/render/render_backend.c
43 src/render/renderbuffer.c 43 src/render/renderbuffer.c
44 src/render/shader_program.c 44 src/render/shader_program.c
45 src/render/shader.c 45 src/render/shader.c
diff --git a/gfx/include/gfx/asset.h b/gfx/include/gfx/asset.h
index 1a4e551..caf40c1 100644
--- a/gfx/include/gfx/asset.h
+++ b/gfx/include/gfx/asset.h
@@ -1,7 +1,7 @@
1/* Asset Management */ 1/* Asset Management */
2#pragma once 2#pragma once
3 3
4#include <gfx/render_backend.h> 4#include <gfx/core.h>
5 5
6#include <stddef.h> 6#include <stddef.h>
7 7
diff --git a/gfx/include/gfx/render_backend.h b/gfx/include/gfx/core.h
index 8d3c42b..7d31cca 100644
--- a/gfx/include/gfx/render_backend.h
+++ b/gfx/include/gfx/core.h
@@ -20,11 +20,11 @@
20typedef struct Buffer Buffer; 20typedef struct Buffer Buffer;
21typedef struct FrameBuffer FrameBuffer; 21typedef struct FrameBuffer FrameBuffer;
22typedef struct Geometry Geometry; 22typedef struct Geometry Geometry;
23typedef struct GfxCore GfxCore;
23typedef struct RenderBuffer RenderBuffer; 24typedef struct RenderBuffer RenderBuffer;
24typedef struct Shader Shader; 25typedef struct Shader Shader;
25typedef struct ShaderProgram ShaderProgram; 26typedef struct ShaderProgram ShaderProgram;
26typedef struct Texture Texture; 27typedef struct Texture Texture;
27typedef struct RenderBackend RenderBackend;
28 28
29/// Data type for vertex indices. 29/// Data type for vertex indices.
30/// Might need U32 for bigger models. 30/// Might need U32 for bigger models.
@@ -315,41 +315,41 @@ typedef struct FrameBufferDesc {
315// ----------------------------------------------------------------------------- 315// -----------------------------------------------------------------------------
316 316
317/// Start a new frame. 317/// Start a new frame.
318void gfx_start_frame(RenderBackend*); 318void gfx_start_frame(GfxCore*);
319 319
320/// End a frame. 320/// End a frame.
321void gfx_end_frame(RenderBackend*); 321void gfx_end_frame(GfxCore*);
322 322
323/// Set the render backend's viewport dimensions. 323/// Set the render backend's viewport dimensions.
324void gfx_set_viewport(RenderBackend*, int width, int height); 324void gfx_set_viewport(GfxCore*, int width, int height);
325 325
326/// Get the render backend's viewport dimensions. 326/// Get the render backend's viewport dimensions.
327void gfx_get_viewport(RenderBackend*, int* width, int* height); 327void gfx_get_viewport(GfxCore*, int* width, int* height);
328 328
329/// Set blending state. 329/// Set blending state.
330void gfx_set_blending(RenderBackend*, bool enable); 330void gfx_set_blending(GfxCore*, bool enable);
331 331
332/// Set depth mask. 332/// Set depth mask.
333void gfx_set_depth_mask(RenderBackend*, bool enable); 333void gfx_set_depth_mask(GfxCore*, bool enable);
334 334
335/// Set cull mode. 335/// Set cull mode.
336void gfx_set_culling(RenderBackend*, bool enable); 336void gfx_set_culling(GfxCore*, bool enable);
337 337
338/// Set polygon offset. 338/// Set polygon offset.
339void gfx_set_polygon_offset(RenderBackend*, float scale, float bias); 339void gfx_set_polygon_offset(GfxCore*, float scale, float bias);
340 340
341/// Reset the polygon offset. 341/// Reset the polygon offset.
342void gfx_reset_polygon_offset(RenderBackend*); 342void gfx_reset_polygon_offset(GfxCore*);
343 343
344// ----------------------------------------------------------------------------- 344// -----------------------------------------------------------------------------
345// Buffers. 345// Buffers.
346// ----------------------------------------------------------------------------- 346// -----------------------------------------------------------------------------
347 347
348/// Create a buffer from raw data. 348/// Create a buffer from raw data.
349Buffer* gfx_make_buffer(RenderBackend*, const BufferDesc*); 349Buffer* gfx_make_buffer(GfxCore*, const BufferDesc*);
350 350
351/// Destroy the buffer. 351/// Destroy the buffer.
352void gfx_destroy_buffer(RenderBackend*, Buffer**); 352void gfx_destroy_buffer(GfxCore*, Buffer**);
353 353
354/// Update the buffer's data. 354/// Update the buffer's data.
355void gfx_update_buffer(Buffer*, const BufferDataDesc*); 355void gfx_update_buffer(Buffer*, const BufferDataDesc*);
@@ -359,10 +359,10 @@ void gfx_update_buffer(Buffer*, const BufferDataDesc*);
359// ----------------------------------------------------------------------------- 359// -----------------------------------------------------------------------------
360 360
361/// Create geometry. 361/// Create geometry.
362Geometry* gfx_make_geometry(RenderBackend*, const GeometryDesc*); 362Geometry* gfx_make_geometry(GfxCore*, const GeometryDesc*);
363 363
364/// Destroy the geometry. 364/// Destroy the geometry.
365void gfx_destroy_geometry(RenderBackend*, Geometry**); 365void gfx_destroy_geometry(GfxCore*, Geometry**);
366 366
367/// Upload new vertex data for the geometry. 367/// Upload new vertex data for the geometry.
368/// 368///
@@ -393,10 +393,10 @@ aabb3 gfx_get_geometry_aabb(const Geometry*);
393// ----------------------------------------------------------------------------- 393// -----------------------------------------------------------------------------
394 394
395/// Create a texture. 395/// Create a texture.
396Texture* gfx_make_texture(RenderBackend*, const TextureDesc*); 396Texture* gfx_make_texture(GfxCore*, const TextureDesc*);
397 397
398/// Destroy the texture. 398/// Destroy the texture.
399void gfx_destroy_texture(RenderBackend*, Texture**); 399void gfx_destroy_texture(GfxCore*, Texture**);
400 400
401/// Update the texture. 401/// Update the texture.
402void gfx_update_texture(Texture*, const TextureDataDesc*); 402void gfx_update_texture(Texture*, const TextureDataDesc*);
@@ -406,20 +406,20 @@ void gfx_update_texture(Texture*, const TextureDataDesc*);
406// ----------------------------------------------------------------------------- 406// -----------------------------------------------------------------------------
407 407
408/// Create a renderbuffer. 408/// Create a renderbuffer.
409RenderBuffer* gfx_make_renderbuffer(RenderBackend*, const RenderBufferDesc*); 409RenderBuffer* gfx_make_renderbuffer(GfxCore*, const RenderBufferDesc*);
410 410
411/// Destroy the renderbuffer. 411/// Destroy the renderbuffer.
412void gfx_destroy_renderbuffer(RenderBackend*, RenderBuffer**); 412void gfx_destroy_renderbuffer(GfxCore*, RenderBuffer**);
413 413
414// ----------------------------------------------------------------------------- 414// -----------------------------------------------------------------------------
415// Framebuffers. 415// Framebuffers.
416// ----------------------------------------------------------------------------- 416// -----------------------------------------------------------------------------
417 417
418/// Create a framebuffer. 418/// Create a framebuffer.
419FrameBuffer* gfx_make_framebuffer(RenderBackend*, const FrameBufferDesc*); 419FrameBuffer* gfx_make_framebuffer(GfxCore*, const FrameBufferDesc*);
420 420
421/// Destroy the framebuffer. 421/// Destroy the framebuffer.
422void gfx_destroy_framebuffer(RenderBackend*, FrameBuffer**); 422void gfx_destroy_framebuffer(GfxCore*, FrameBuffer**);
423 423
424/// Attach a colour buffer to the framebuffer. 424/// Attach a colour buffer to the framebuffer.
425bool gfx_framebuffer_attach_colour(FrameBuffer*, const FrameBufferAttachment*); 425bool gfx_framebuffer_attach_colour(FrameBuffer*, const FrameBufferAttachment*);
@@ -445,17 +445,16 @@ void gfx_framebuffer_set_viewport(
445// ----------------------------------------------------------------------------- 445// -----------------------------------------------------------------------------
446 446
447/// Create a shader. 447/// Create a shader.
448Shader* gfx_make_shader(RenderBackend*, const ShaderDesc*); 448Shader* gfx_make_shader(GfxCore*, const ShaderDesc*);
449 449
450/// Destroy the shader. 450/// Destroy the shader.
451void gfx_destroy_shader(RenderBackend*, Shader**); 451void gfx_destroy_shader(GfxCore*, Shader**);
452 452
453/// Create a shader program. 453/// Create a shader program.
454ShaderProgram* gfx_make_shader_program( 454ShaderProgram* gfx_make_shader_program(GfxCore*, const ShaderProgramDesc*);
455 RenderBackend*, const ShaderProgramDesc*);
456 455
457/// Destroy the shader program. 456/// Destroy the shader program.
458void gfx_destroy_shader_program(RenderBackend*, ShaderProgram**); 457void gfx_destroy_shader_program(GfxCore*, ShaderProgram**);
459 458
460/// Activate the shader program. 459/// Activate the shader program.
461void gfx_activate_shader_program(const ShaderProgram*); 460void gfx_activate_shader_program(const ShaderProgram*);
diff --git a/gfx/include/gfx/gfx.h b/gfx/include/gfx/gfx.h
index bfc457f..7c670a5 100644
--- a/gfx/include/gfx/gfx.h
+++ b/gfx/include/gfx/gfx.h
@@ -1,9 +1,9 @@
1#pragma once 1#pragma once
2 2
3typedef struct AssetCache AssetCache; 3typedef struct AssetCache AssetCache;
4typedef struct ImmRenderer ImmRenderer; 4typedef struct GfxCore GfxCore;
5typedef struct RenderBackend RenderBackend; 5typedef struct ImmRenderer ImmRenderer;
6typedef struct Renderer Renderer; 6typedef struct Renderer Renderer;
7 7
8typedef struct Gfx Gfx; 8typedef struct Gfx Gfx;
9 9
@@ -14,7 +14,7 @@ Gfx* gfx_init(void);
14void gfx_destroy(Gfx**); 14void gfx_destroy(Gfx**);
15 15
16/// Get the render backend. 16/// Get the render backend.
17RenderBackend* gfx_get_render_backend(Gfx*); 17GfxCore* gfx_get_core(Gfx*);
18 18
19/// Get the renderer. 19/// Get the renderer.
20Renderer* gfx_get_renderer(Gfx*); 20Renderer* gfx_get_renderer(Gfx*);
diff --git a/gfx/include/gfx/renderer.h b/gfx/include/gfx/renderer.h
index 9236e3f..2a4ada1 100644
--- a/gfx/include/gfx/renderer.h
+++ b/gfx/include/gfx/renderer.h
@@ -8,9 +8,9 @@
8#include <math/vec3.h> 8#include <math/vec3.h>
9#include <math/vec4.h> 9#include <math/vec4.h>
10 10
11typedef struct RenderBackend RenderBackend; 11typedef struct GfxCore GfxCore;
12typedef struct Scene Scene; 12typedef struct Scene Scene;
13typedef struct SceneCamera SceneCamera; 13typedef struct SceneCamera SceneCamera;
14 14
15typedef struct ImmRenderer ImmRenderer; 15typedef struct ImmRenderer ImmRenderer;
16typedef struct Renderer Renderer; 16typedef struct Renderer Renderer;
diff --git a/gfx/include/gfx/scene/material.h b/gfx/include/gfx/scene/material.h
index 07e31d4..bca664e 100644
--- a/gfx/include/gfx/scene/material.h
+++ b/gfx/include/gfx/scene/material.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <gfx/sizes.h> 4#include <gfx/sizes.h>
5 5
6typedef struct Material Material; 6typedef struct Material Material;
diff --git a/gfx/include/gfx/util/geometry.h b/gfx/include/gfx/util/geometry.h
index c62022b..a962291 100644
--- a/gfx/include/gfx/util/geometry.h
+++ b/gfx/include/gfx/util/geometry.h
@@ -1,13 +1,13 @@
1/// Functions to construct geometry procedurally. 1/// Functions to construct geometry procedurally.
2#pragma once 2#pragma once
3 3
4#include <gfx/render_backend.h> 4#include <gfx/core.h>
5 5
6#include <math/vec2.h> 6#include <math/vec2.h>
7#include <math/vec3.h> 7#include <math/vec3.h>
8 8
9/// Construct a quad with positions in the range [-1, 1]^2. 9/// Construct a quad with positions in the range [-1, 1]^2.
10Geometry* gfx_make_quad_11(RenderBackend*); 10Geometry* gfx_make_quad_11(GfxCore*);
11 11
12/// Construct a quad with positions in the range [0, 1]^2. 12/// Construct a quad with positions in the range [0, 1]^2.
13Geometry* gfx_make_quad_01(RenderBackend*); 13Geometry* gfx_make_quad_01(GfxCore*);
diff --git a/gfx/include/gfx/util/ibl.h b/gfx/include/gfx/util/ibl.h
index 5d76e54..6e39180 100644
--- a/gfx/include/gfx/util/ibl.h
+++ b/gfx/include/gfx/util/ibl.h
@@ -3,26 +3,23 @@
3 3
4typedef struct IBL IBL; 4typedef struct IBL IBL;
5 5
6typedef struct RenderBackend RenderBackend; 6typedef struct GfxCore GfxCore;
7typedef struct Texture Texture; 7typedef struct Texture Texture;
8 8
9/// Create an environment map filterer for IBL. 9/// Create an environment map filterer for IBL.
10IBL* gfx_make_ibl(RenderBackend*); 10IBL* gfx_make_ibl(GfxCore*);
11 11
12/// Destroy the environment map filterer. 12/// Destroy the environment map filterer.
13void gfx_destroy_ibl(RenderBackend*, IBL**); 13void gfx_destroy_ibl(GfxCore*, IBL**);
14 14
15/// Create a BRDF integration map for IBL. 15/// Create a BRDF integration map for IBL.
16Texture* gfx_make_brdf_integration_map(IBL*, RenderBackend*, int width, 16Texture* gfx_make_brdf_integration_map(IBL*, GfxCore*, int width, int height);
17 int height);
18 17
19/// Create an irradiance map (cubemap) from an environment map for IBL. 18/// Create an irradiance map (cubemap) from an environment map for IBL.
20Texture* gfx_make_irradiance_map(IBL*, RenderBackend*, 19Texture* gfx_make_irradiance_map(
21 const Texture* environment_map, int width, 20 IBL*, GfxCore*, const Texture* environment_map, int width, int height);
22 int height);
23 21
24/// Create a prefiltered environment map (cubemap) for IBL. 22/// Create a prefiltered environment map (cubemap) for IBL.
25Texture* gfx_make_prefiltered_environment_map(IBL*, RenderBackend*, 23Texture* gfx_make_prefiltered_environment_map(
26 const Texture* environment_map, 24 IBL*, GfxCore*, const Texture* environment_map, int width, int height,
27 int width, int height, 25 int* max_mip_level);
28 int* max_mip_level);
diff --git a/gfx/include/gfx/util/shader.h b/gfx/include/gfx/util/shader.h
index 9bde8cf..bd058f4 100644
--- a/gfx/include/gfx/util/shader.h
+++ b/gfx/include/gfx/util/shader.h
@@ -3,44 +3,44 @@
3 3
4#include <stddef.h> 4#include <stddef.h>
5 5
6typedef struct RenderBackend RenderBackend; 6typedef struct GfxCore GfxCore;
7typedef struct ShaderCompilerDefine ShaderCompilerDefine; 7typedef struct ShaderCompilerDefine ShaderCompilerDefine;
8typedef struct ShaderProgram ShaderProgram; 8typedef struct ShaderProgram ShaderProgram;
9 9
10/// Create a BRDF integration map shader. 10/// Create a BRDF integration map shader.
11ShaderProgram* gfx_make_brdf_integration_map_shader(RenderBackend*); 11ShaderProgram* gfx_make_brdf_integration_map_shader(GfxCore*);
12 12
13/// Create a Cook-Torrance shader. 13/// Create a Cook-Torrance shader.
14ShaderProgram* gfx_make_cook_torrance_shader(RenderBackend*); 14ShaderProgram* gfx_make_cook_torrance_shader(GfxCore*);
15 15
16/// Create a Cook-Torrance shader with additional shader compiler defines. 16/// Create a Cook-Torrance shader with additional shader compiler defines.
17/// This function can be used to create shader permutations. 17/// This function can be used to create shader permutations.
18ShaderProgram* gfx_make_cook_torrance_shader_perm( 18ShaderProgram* gfx_make_cook_torrance_shader_perm(
19 RenderBackend*, const ShaderCompilerDefine*, size_t num_defines); 19 GfxCore*, const ShaderCompilerDefine*, size_t num_defines);
20 20
21/// Create a 3D debugging shader. 21/// Create a 3D debugging shader.
22ShaderProgram* gfx_make_debug3d_shader(RenderBackend*); 22ShaderProgram* gfx_make_debug3d_shader(GfxCore*);
23 23
24/// Create a shader for drawing in immediate mode. 24/// Create a shader for drawing in immediate mode.
25ShaderProgram* gfx_make_immediate_mode_shader(RenderBackend*); 25ShaderProgram* gfx_make_immediate_mode_shader(GfxCore*);
26 26
27/// Create a shader for computing irradiance maps from cube maps. 27/// Create a shader for computing irradiance maps from cube maps.
28ShaderProgram* gfx_make_irradiance_map_shader(RenderBackend*); 28ShaderProgram* gfx_make_irradiance_map_shader(GfxCore*);
29 29
30/// Create a shader for computing prefiltered environment maps from cube maps. 30/// Create a shader for computing prefiltered environment maps from cube maps.
31ShaderProgram* gfx_make_prefiltered_environment_map_shader(RenderBackend*); 31ShaderProgram* gfx_make_prefiltered_environment_map_shader(GfxCore*);
32 32
33/// Create a skyquad shader. 33/// Create a skyquad shader.
34ShaderProgram* gfx_make_skyquad_shader(RenderBackend*); 34ShaderProgram* gfx_make_skyquad_shader(GfxCore*);
35 35
36/// Create a shader to view normal-mapped normals. 36/// Create a shader to view normal-mapped normals.
37ShaderProgram* gfx_make_view_normal_mapped_normals_shader(RenderBackend*); 37ShaderProgram* gfx_make_view_normal_mapped_normals_shader(GfxCore*);
38 38
39/// Create a shader to view vertex normals. 39/// Create a shader to view vertex normals.
40ShaderProgram* gfx_make_view_normals_shader(RenderBackend*); 40ShaderProgram* gfx_make_view_normals_shader(GfxCore*);
41 41
42/// Create a shader to view vertex tangents. 42/// Create a shader to view vertex tangents.
43ShaderProgram* gfx_make_view_tangents_shader(RenderBackend*); 43ShaderProgram* gfx_make_view_tangents_shader(GfxCore*);
44 44
45/// Create a shader to view textures. 45/// Create a shader to view textures.
46ShaderProgram* gfx_make_view_texture_shader(RenderBackend*); 46ShaderProgram* gfx_make_view_texture_shader(GfxCore*);
diff --git a/gfx/include/gfx/util/skyquad.h b/gfx/include/gfx/util/skyquad.h
index 923c6e5..2b3fe17 100644
--- a/gfx/include/gfx/util/skyquad.h
+++ b/gfx/include/gfx/util/skyquad.h
@@ -1,14 +1,14 @@
1/// A skyquad is like a skybox but with a single quad. 1/// A skyquad is like a skybox but with a single quad.
2#pragma once 2#pragma once
3 3
4typedef struct RenderBackend RenderBackend; 4typedef struct GfxCore GfxCore;
5typedef struct Scene Scene; 5typedef struct Scene Scene;
6typedef struct SceneNode SceneNode; 6typedef struct SceneNode SceneNode;
7typedef struct SceneObject SceneObject; 7typedef struct SceneObject SceneObject;
8typedef struct Texture Texture; 8typedef struct Texture Texture;
9 9
10/// Create a skyquad. 10/// Create a skyquad.
11SceneObject* gfx_make_skyquad(RenderBackend*, const Texture*); 11SceneObject* gfx_make_skyquad(GfxCore*, const Texture*);
12 12
13/// Set up a skyquad in the scene. 13/// Set up a skyquad in the scene.
14/// 14///
@@ -19,4 +19,4 @@ SceneObject* gfx_make_skyquad(RenderBackend*, const Texture*);
19/// Return the light node under which objects affected by the light can be 19/// Return the light node under which objects affected by the light can be
20/// rooted. 20/// rooted.
21SceneNode* gfx_setup_skyquad( 21SceneNode* gfx_setup_skyquad(
22 RenderBackend*, SceneNode* root, const Texture* environment_map); 22 GfxCore*, SceneNode* root, const Texture* environment_map);
diff --git a/gfx/src/asset/asset_cache.c b/gfx/src/asset/asset_cache.c
index d077421..16c4d5c 100644
--- a/gfx/src/asset/asset_cache.c
+++ b/gfx/src/asset/asset_cache.c
@@ -237,8 +237,8 @@ const Texture* gfx_load_texture(Gfx* gfx, const LoadTextureCmd* cmd) {
237 237
238 // Asset not found in the cache. 238 // Asset not found in the cache.
239 // Load it, insert it into the cache, and return it. 239 // Load it, insert it into the cache, and return it.
240 RenderBackend* render_backend = gfx_get_render_backend(gfx); 240 GfxCore* gfxcore = gfx_get_core(gfx);
241 const Texture* texture = gfx_texture_load(render_backend, cmd); 241 const Texture* texture = gfx_texture_load(gfxcore, cmd);
242 if (texture) { 242 if (texture) {
243 *(Asset*)mempool_alloc(&cache->assets) = (Asset){ 243 *(Asset*)mempool_alloc(&cache->assets) = (Asset){
244 .type = TextureAsset, 244 .type = TextureAsset,
diff --git a/gfx/src/asset/model.c b/gfx/src/asset/model.c
index 2053dc4..75f922f 100644
--- a/gfx/src/asset/model.c
+++ b/gfx/src/asset/model.c
@@ -82,8 +82,8 @@
82#include "asset/model.h" 82#include "asset/model.h"
83 83
84#include "asset/texture.h" 84#include "asset/texture.h"
85#include "gfx/core.h"
85#include "gfx/gfx.h" 86#include "gfx/gfx.h"
86#include "gfx/render_backend.h"
87#include "gfx/scene/animation.h" 87#include "gfx/scene/animation.h"
88#include "gfx/scene/camera.h" 88#include "gfx/scene/camera.h"
89#include "gfx/scene/material.h" 89#include "gfx/scene/material.h"
@@ -208,7 +208,7 @@ static size_t make_defines(
208 208
209/// Compile a shader permutation. 209/// Compile a shader permutation.
210static ShaderProgram* make_shader_permutation( 210static ShaderProgram* make_shader_permutation(
211 RenderBackend* render_backend, MeshPermutation perm) { 211 GfxCore* gfxcore, MeshPermutation perm) {
212 LOGD( 212 LOGD(
213 "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: " 213 "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: "
214 "%d, tangents: %d, joints: %d, weights: %d, albedo map: %d, " 214 "%d, tangents: %d, joints: %d, weights: %d, albedo map: %d, "
@@ -221,8 +221,7 @@ static ShaderProgram* make_shader_permutation(
221 221
222 ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; 222 ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES];
223 const size_t num_defines = make_defines(perm, defines); 223 const size_t num_defines = make_defines(perm, defines);
224 return gfx_make_cook_torrance_shader_perm( 224 return gfx_make_cook_torrance_shader_perm(gfxcore, defines, num_defines);
225 render_backend, defines, num_defines);
226} 225}
227 226
228/// Map a texture type to the name of the shader uniform used to access the 227/// Map a texture type to the name of the shader uniform used to access the
@@ -570,20 +569,20 @@ static size_t get_total_primitives(const cgltf_data* data) {
570/// TODO: There is no need to load the inverse bind matrices buffer into the 569/// TODO: There is no need to load the inverse bind matrices buffer into the
571/// GPU. Might need to lazily load buffers. 570/// GPU. Might need to lazily load buffers.
572static bool load_buffers( 571static bool load_buffers(
573 const cgltf_data* data, RenderBackend* render_backend, Buffer** buffers) { 572 const cgltf_data* data, GfxCore* gfxcore, Buffer** buffers) {
574 assert(data); 573 assert(data);
575 assert(render_backend); 574 assert(gfxcore);
576 assert(buffers); 575 assert(buffers);
577 576
578 for (cgltf_size i = 0; i < data->buffers_count; ++i) { 577 for (cgltf_size i = 0; i < data->buffers_count; ++i) {
579 const cgltf_buffer* buffer = &data->buffers[i]; 578 const cgltf_buffer* buffer = &data->buffers[i];
580 assert(buffer->data); 579 assert(buffer->data);
581 buffers[i] = gfx_make_buffer( 580 buffers[i] = gfx_make_buffer(
582 render_backend, &(BufferDesc){ 581 gfxcore, &(BufferDesc){
583 .usage = BufferStatic, 582 .usage = BufferStatic,
584 .type = BufferUntyped, 583 .type = BufferUntyped,
585 .data.data = buffer->data, 584 .data.data = buffer->data,
586 .data.count = buffer->size}); 585 .data.count = buffer->size});
587 if (!buffers[i]) { 586 if (!buffers[i]) {
588 return false; 587 return false;
589 } 588 }
@@ -595,21 +594,21 @@ static bool load_buffers(
595/// Load tangent buffers. 594/// Load tangent buffers.
596static bool load_tangent_buffers( 595static bool load_tangent_buffers(
597 const cgltfTangentBuffer* cgltf_tangent_buffers, 596 const cgltfTangentBuffer* cgltf_tangent_buffers,
598 cgltf_size num_tangent_buffers, RenderBackend* render_backend, 597 cgltf_size num_tangent_buffers, GfxCore* gfxcore,
599 Buffer** tangent_buffers) { 598 Buffer** tangent_buffers) {
600 assert(cgltf_tangent_buffers); 599 assert(cgltf_tangent_buffers);
601 assert(render_backend); 600 assert(gfxcore);
602 assert(tangent_buffers); 601 assert(tangent_buffers);
603 602
604 for (cgltf_size i = 0; i < num_tangent_buffers; ++i) { 603 for (cgltf_size i = 0; i < num_tangent_buffers; ++i) {
605 const cgltfTangentBuffer* buffer = &cgltf_tangent_buffers[i]; 604 const cgltfTangentBuffer* buffer = &cgltf_tangent_buffers[i];
606 assert(buffer->data); 605 assert(buffer->data);
607 tangent_buffers[i] = gfx_make_buffer( 606 tangent_buffers[i] = gfx_make_buffer(
608 render_backend, &(BufferDesc){ 607 gfxcore, &(BufferDesc){
609 .usage = BufferStatic, 608 .usage = BufferStatic,
610 .type = BufferUntyped, 609 .type = BufferUntyped,
611 .data.data = buffer->data, 610 .data.data = buffer->data,
612 .data.count = buffer->size_bytes}); 611 .data.count = buffer->size_bytes});
613 if (!tangent_buffers[i]) { 612 if (!tangent_buffers[i]) {
614 return false; 613 return false;
615 } 614 }
@@ -631,10 +630,10 @@ static bool load_tangent_buffers(
631/// Return an array of LoadTextureCmds such that the index of each cmd matches 630/// Return an array of LoadTextureCmds such that the index of each cmd matches
632/// the index of each glTF texture in the scene. 631/// the index of each glTF texture in the scene.
633static void load_textures_lazy( 632static void load_textures_lazy(
634 const cgltf_data* data, RenderBackend* render_backend, 633 const cgltf_data* data, GfxCore* gfxcore, const char* directory,
635 const char* directory, LoadTextureCmd* load_texture_cmds) { 634 LoadTextureCmd* load_texture_cmds) {
636 assert(data); 635 assert(data);
637 assert(render_backend); 636 assert(gfxcore);
638 assert(load_texture_cmds); 637 assert(load_texture_cmds);
639 638
640 for (cgltf_size i = 0; i < data->textures_count; ++i) { 639 for (cgltf_size i = 0; i < data->textures_count; ++i) {
@@ -908,7 +907,7 @@ aabb3 compute_aabb(const cgltf_accessor* accessor) {
908 907
909/// Load all meshes from the glTF scene. 908/// Load all meshes from the glTF scene.
910static bool load_meshes( 909static bool load_meshes(
911 const cgltf_data* data, RenderBackend* render_backend, Buffer** buffers, 910 const cgltf_data* data, GfxCore* gfxcore, Buffer** buffers,
912 Buffer** tangent_buffers, const cgltfTangentBuffer* cgltf_tangent_buffers, 911 Buffer** tangent_buffers, const cgltfTangentBuffer* cgltf_tangent_buffers,
913 cgltf_size num_tangent_buffers, Material** materials, 912 cgltf_size num_tangent_buffers, Material** materials,
914 ShaderProgram* const shader, size_t primitive_count, Geometry** geometries, 913 ShaderProgram* const shader, size_t primitive_count, Geometry** geometries,
@@ -924,7 +923,7 @@ static bool load_meshes(
924 // Accessor + buffer view BufferView 923 // Accessor + buffer view BufferView
925 // Buffer Buffer 924 // Buffer Buffer
926 assert(data); 925 assert(data);
927 assert(render_backend); 926 assert(gfxcore);
928 assert(buffers); 927 assert(buffers);
929 assert(materials); 928 assert(materials);
930 assert(geometries); 929 assert(geometries);
@@ -1175,7 +1174,7 @@ static bool load_meshes(
1175 } 1174 }
1176 assert(material); 1175 assert(material);
1177 1176
1178 geometries[next_mesh] = gfx_make_geometry(render_backend, &geometry_desc); 1177 geometries[next_mesh] = gfx_make_geometry(gfxcore, &geometry_desc);
1179 if (!geometries[next_mesh]) { 1178 if (!geometries[next_mesh]) {
1180 return false; 1179 return false;
1181 } 1180 }
@@ -1190,7 +1189,7 @@ static bool load_meshes(
1190 // values. Also, changing uniforms is much faster than swapping shaders, 1189 // values. Also, changing uniforms is much faster than swapping shaders,
1191 // so shader caching is the most important thing here. 1190 // so shader caching is the most important thing here.
1192 ShaderProgram* mesh_shader = 1191 ShaderProgram* mesh_shader =
1193 shader ? shader : make_shader_permutation(render_backend, perm); 1192 shader ? shader : make_shader_permutation(gfxcore, perm);
1194 assert(mesh_shader); 1193 assert(mesh_shader);
1195 1194
1196 meshes[next_mesh] = gfx_make_mesh(&(MeshDesc){ 1195 meshes[next_mesh] = gfx_make_mesh(&(MeshDesc){
@@ -1277,7 +1276,7 @@ static void compute_joint_bounding_boxes(
1277 for (int i = 0; i < 4; ++i) { 1276 for (int i = 0; i < 4; ++i) {
1278 const size_t joint_index = j[i]; 1277 const size_t joint_index = j[i];
1279 assert((size_t)joint_index < num_joints); 1278 assert((size_t)joint_index < num_joints);
1280 1279
1281 joint_descs[joint_index].box = 1280 joint_descs[joint_index].box =
1282 aabb3_add(joint_descs[joint_index].box, p); 1281 aabb3_add(joint_descs[joint_index].box, p);
1283 } 1282 }
@@ -1699,8 +1698,8 @@ static Model* load_scene(
1699 1698
1700 bool success = false; 1699 bool success = false;
1701 1700
1702 RenderBackend* render_backend = gfx_get_render_backend(gfx); 1701 GfxCore* gfxcore = gfx_get_core(gfx);
1703 const size_t primitive_count = get_total_primitives(data); 1702 const size_t primitive_count = get_total_primitives(data);
1704 1703
1705 const mstring directory = mstring_dirname(*filepath); 1704 const mstring directory = mstring_dirname(*filepath);
1706 LOGD("Filepath: %s", mstring_cstr(filepath)); 1705 LOGD("Filepath: %s", mstring_cstr(filepath));
@@ -1745,18 +1744,18 @@ static Model* load_scene(
1745 1744
1746 if ((num_tangent_buffers > 0) && 1745 if ((num_tangent_buffers > 0) &&
1747 !load_tangent_buffers( 1746 !load_tangent_buffers(
1748 cgltf_tangent_buffers, num_tangent_buffers, render_backend, 1747 cgltf_tangent_buffers, num_tangent_buffers, gfxcore,
1749 tangent_buffers)) { 1748 tangent_buffers)) {
1750 goto cleanup; 1749 goto cleanup;
1751 } 1750 }
1752 1751
1753 if (!load_buffers(data, render_backend, buffers)) { 1752 if (!load_buffers(data, gfxcore, buffers)) {
1754 goto cleanup; 1753 goto cleanup;
1755 } 1754 }
1756 1755
1757 if (data->textures_count > 0) { 1756 if (data->textures_count > 0) {
1758 load_textures_lazy( 1757 load_textures_lazy(
1759 data, render_backend, mstring_cstr(&directory), load_texture_cmds); 1758 data, gfxcore, mstring_cstr(&directory), load_texture_cmds);
1760 } 1759 }
1761 1760
1762 if (!load_materials(data, gfx, load_texture_cmds, textures, materials)) { 1761 if (!load_materials(data, gfx, load_texture_cmds, textures, materials)) {
@@ -1764,7 +1763,7 @@ static Model* load_scene(
1764 } 1763 }
1765 1764
1766 if (!load_meshes( 1765 if (!load_meshes(
1767 data, render_backend, buffers, tangent_buffers, cgltf_tangent_buffers, 1766 data, gfxcore, buffers, tangent_buffers, cgltf_tangent_buffers,
1768 num_tangent_buffers, materials, shader, primitive_count, geometries, 1767 num_tangent_buffers, materials, shader, primitive_count, geometries,
1769 meshes, scene_objects)) { 1768 meshes, scene_objects)) {
1770 goto cleanup; 1769 goto cleanup;
@@ -1823,7 +1822,7 @@ cleanup:
1823 if (!success) { 1822 if (!success) {
1824 for (cgltf_size i = 0; i < num_tangent_buffers; ++i) { 1823 for (cgltf_size i = 0; i < num_tangent_buffers; ++i) {
1825 if (tangent_buffers[i]) { 1824 if (tangent_buffers[i]) {
1826 gfx_destroy_buffer(render_backend, &tangent_buffers[i]); 1825 gfx_destroy_buffer(gfxcore, &tangent_buffers[i]);
1827 } 1826 }
1828 } 1827 }
1829 } 1828 }
@@ -1833,7 +1832,7 @@ cleanup:
1833 if (!success) { 1832 if (!success) {
1834 for (cgltf_size i = 0; i < data->buffers_count; ++i) { 1833 for (cgltf_size i = 0; i < data->buffers_count; ++i) {
1835 if (buffers[i]) { 1834 if (buffers[i]) {
1836 gfx_destroy_buffer(render_backend, &buffers[i]); 1835 gfx_destroy_buffer(gfxcore, &buffers[i]);
1837 } 1836 }
1838 } 1837 }
1839 } 1838 }
@@ -1859,7 +1858,7 @@ cleanup:
1859 if (!success) { 1858 if (!success) {
1860 for (size_t i = 0; i < primitive_count; ++i) { 1859 for (size_t i = 0; i < primitive_count; ++i) {
1861 if (geometries[i]) { 1860 if (geometries[i]) {
1862 gfx_destroy_geometry(render_backend, &geometries[i]); 1861 gfx_destroy_geometry(gfxcore, &geometries[i]);
1863 } 1862 }
1864 } 1863 }
1865 } 1864 }
diff --git a/gfx/src/asset/texture.c b/gfx/src/asset/texture.c
index 3a82788..c790394 100644
--- a/gfx/src/asset/texture.c
+++ b/gfx/src/asset/texture.c
@@ -1,6 +1,6 @@
1#include "texture.h" 1#include "texture.h"
2 2
3#include "gfx/render_backend.h" 3#include "gfx/core.h"
4 4
5#include "error.h" 5#include "error.h"
6 6
@@ -43,9 +43,8 @@ static void flip_horizontally(
43// For this reason, we do X and Y flips when doing cubemap textures so that we 43// For this reason, we do X and Y flips when doing cubemap textures so that we
44// can sample cubemaps as if they were given in the usual OpenGL coordinate 44// can sample cubemaps as if they were given in the usual OpenGL coordinate
45// system. 45// system.
46Texture* gfx_texture_load( 46Texture* gfx_texture_load(GfxCore* gfxcore, const LoadTextureCmd* cmd) {
47 RenderBackend* render_backend, const LoadTextureCmd* cmd) { 47 assert(gfxcore);
48 assert(render_backend);
49 assert(cmd); 48 assert(cmd);
50 assert(cmd->origin == AssetFromFile || cmd->origin == AssetFromMemory); 49 assert(cmd->origin == AssetFromFile || cmd->origin == AssetFromMemory);
51 assert(cmd->type == LoadTexture || cmd->type == LoadCubemap); 50 assert(cmd->type == LoadTexture || cmd->type == LoadCubemap);
@@ -168,7 +167,7 @@ Texture* gfx_texture_load(
168 break; 167 break;
169 } 168 }
170 169
171 Texture* texture = gfx_make_texture(render_backend, &desc); 170 Texture* texture = gfx_make_texture(gfxcore, &desc);
172 for (int i = 0; i < 6; ++i) { 171 for (int i = 0; i < 6; ++i) {
173 if (pixels[i]) { 172 if (pixels[i]) {
174 stbi_image_free(pixels[i]); 173 stbi_image_free(pixels[i]);
diff --git a/gfx/src/asset/texture.h b/gfx/src/asset/texture.h
index a3239fe..0d38bd9 100644
--- a/gfx/src/asset/texture.h
+++ b/gfx/src/asset/texture.h
@@ -4,4 +4,4 @@
4#include <gfx/asset.h> 4#include <gfx/asset.h>
5 5
6/// Load a texture. 6/// Load a texture.
7Texture* gfx_texture_load(RenderBackend*, const LoadTextureCmd*); 7Texture* gfx_texture_load(GfxCore*, const LoadTextureCmd*);
diff --git a/gfx/src/gfx.c b/gfx/src/gfx.c
index 7095ea1..8c513a1 100644
--- a/gfx/src/gfx.c
+++ b/gfx/src/gfx.c
@@ -1,7 +1,7 @@
1#include <gfx/gfx.h> 1#include <gfx/gfx.h>
2 2
3#include "asset/asset_cache.h" 3#include "asset/asset_cache.h"
4#include "render/render_backend_impl.h" 4#include "render/core_impl.h"
5#include "renderer/imm_renderer_impl.h" 5#include "renderer/imm_renderer_impl.h"
6#include "renderer/renderer_impl.h" 6#include "renderer/renderer_impl.h"
7#include "scene/scene_graph.h" 7#include "scene/scene_graph.h"
@@ -15,10 +15,10 @@
15#include <stdlib.h> 15#include <stdlib.h>
16 16
17typedef struct Gfx { 17typedef struct Gfx {
18 AssetCache asset_cache; 18 AssetCache asset_cache;
19 RenderBackend render_backend; 19 GfxCore gfxcore;
20 Renderer renderer; 20 Renderer renderer;
21 ImmRenderer imm_renderer; 21 ImmRenderer imm_renderer;
22} Gfx; 22} Gfx;
23 23
24Gfx* gfx_init(void) { 24Gfx* gfx_init(void) {
@@ -31,12 +31,12 @@ Gfx* gfx_init(void) {
31 if (!gfx) { 31 if (!gfx) {
32 return 0; 32 return 0;
33 } 33 }
34 gfx_init_render_backend(&gfx->render_backend); 34 gfx_init_gfxcore(&gfx->gfxcore);
35 if (!renderer_make(&gfx->renderer, &gfx->render_backend)) { 35 if (!renderer_make(&gfx->renderer, &gfx->gfxcore)) {
36 gfx_destroy(&gfx); 36 gfx_destroy(&gfx);
37 return 0; 37 return 0;
38 } 38 }
39 if (!imm_renderer_make(&gfx->imm_renderer, &gfx->render_backend)) { 39 if (!imm_renderer_make(&gfx->imm_renderer, &gfx->gfxcore)) {
40 // TODO: Add error logs to the initialization failure cases here and inside 40 // TODO: Add error logs to the initialization failure cases here and inside
41 // the renderers. 41 // the renderers.
42 gfx_destroy(&gfx); 42 gfx_destroy(&gfx);
@@ -55,14 +55,14 @@ void gfx_destroy(Gfx** gfx) {
55 gfx_destroy_asset_cache(&(*gfx)->asset_cache); 55 gfx_destroy_asset_cache(&(*gfx)->asset_cache);
56 renderer_destroy(&(*gfx)->renderer); 56 renderer_destroy(&(*gfx)->renderer);
57 imm_renderer_destroy(&(*gfx)->imm_renderer); 57 imm_renderer_destroy(&(*gfx)->imm_renderer);
58 gfx_del_render_backend(&(*gfx)->render_backend); 58 gfx_del_gfxcore(&(*gfx)->gfxcore);
59 free(*gfx); 59 free(*gfx);
60 *gfx = 0; 60 *gfx = 0;
61} 61}
62 62
63RenderBackend* gfx_get_render_backend(Gfx* gfx) { 63GfxCore* gfx_get_core(Gfx* gfx) {
64 assert(gfx); 64 assert(gfx);
65 return &gfx->render_backend; 65 return &gfx->gfxcore;
66} 66}
67 67
68Renderer* gfx_get_renderer(Gfx* gfx) { 68Renderer* gfx_get_renderer(Gfx* gfx) {
diff --git a/gfx/src/render/buffer.c b/gfx/src/render/buffer.c
index 28877bb..3b7e4bc 100644
--- a/gfx/src/render/buffer.c
+++ b/gfx/src/render/buffer.c
@@ -1,6 +1,6 @@
1#include "buffer.h" 1#include "buffer.h"
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <gfx_assert.h> 4#include <gfx_assert.h>
5 5
6#include <math/vec2.h> 6#include <math/vec2.h>
@@ -57,7 +57,7 @@ bool gfx_init_buffer(Buffer* buffer, const BufferDesc* desc) {
57 glBufferData(GL_ARRAY_BUFFER, buffer->size_bytes, desc->data.data, usage); 57 glBufferData(GL_ARRAY_BUFFER, buffer->size_bytes, desc->data.data, usage);
58 glBindBuffer(GL_ARRAY_BUFFER, 0); 58 glBindBuffer(GL_ARRAY_BUFFER, 0);
59 ASSERT_GL; 59 ASSERT_GL;
60 60
61 return true; 61 return true;
62} 62}
63 63
diff --git a/gfx/src/render/buffer.h b/gfx/src/render/buffer.h
index 3adfd8e..b9080f0 100644
--- a/gfx/src/render/buffer.h
+++ b/gfx/src/render/buffer.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "gl_util.h" 5#include "gl_util.h"
6 6
diff --git a/gfx/src/render/render_backend.c b/gfx/src/render/core.c
index 8e88feb..7a6d9cc 100644
--- a/gfx/src/render/render_backend.c
+++ b/gfx/src/render/core.c
@@ -1,4 +1,4 @@
1#include "render_backend_impl.h" 1#include "core_impl.h"
2 2
3#include "gl_util.h" 3#include "gl_util.h"
4 4
@@ -6,19 +6,19 @@
6 6
7#include <assert.h> 7#include <assert.h>
8 8
9void gfx_init_render_backend(RenderBackend* render_backend) { 9void gfx_init_gfxcore(GfxCore* gfxcore) {
10 assert(render_backend); 10 assert(gfxcore);
11 11
12 mempool_make(&render_backend->buffers); 12 mempool_make(&gfxcore->buffers);
13 mempool_make(&render_backend->framebuffers); 13 mempool_make(&gfxcore->framebuffers);
14 mempool_make(&render_backend->geometries); 14 mempool_make(&gfxcore->geometries);
15 mempool_make(&render_backend->renderbuffers); 15 mempool_make(&gfxcore->renderbuffers);
16 mempool_make(&render_backend->shaders); 16 mempool_make(&gfxcore->shaders);
17 mempool_make(&render_backend->shader_programs); 17 mempool_make(&gfxcore->shader_programs);
18 mempool_make(&render_backend->textures); 18 mempool_make(&gfxcore->textures);
19 19
20 mempool_make(&render_backend->shader_cache); 20 mempool_make(&gfxcore->shader_cache);
21 mempool_make(&render_backend->program_cache); 21 mempool_make(&gfxcore->program_cache);
22 22
23 glEnable(GL_CULL_FACE); 23 glEnable(GL_CULL_FACE);
24 glFrontFace(GL_CCW); 24 glFrontFace(GL_CCW);
@@ -33,70 +33,65 @@ void gfx_init_render_backend(RenderBackend* render_backend) {
33 33
34// Conveniently destroy any objects that have not been destroyed by the 34// Conveniently destroy any objects that have not been destroyed by the
35// application. 35// application.
36void gfx_del_render_backend(RenderBackend* render_backend) { 36void gfx_del_gfxcore(GfxCore* gfxcore) {
37 assert(render_backend); 37 assert(gfxcore);
38 38
39 mempool_foreach( 39 mempool_foreach(&gfxcore->buffers, buffer, { gfx_del_buffer(buffer); });
40 &render_backend->buffers, buffer, { gfx_del_buffer(buffer); });
41 40
42 mempool_foreach(&render_backend->framebuffers, framebuffer, { 41 mempool_foreach(&gfxcore->framebuffers, framebuffer, {
43 gfx_del_framebuffer(framebuffer); 42 gfx_del_framebuffer(framebuffer);
44 }); 43 });
45 44
46 mempool_foreach( 45 mempool_foreach(
47 &render_backend->geometries, geometry, { gfx_del_geometry(geometry); }); 46 &gfxcore->geometries, geometry, { gfx_del_geometry(geometry); });
48 47
49 mempool_foreach(&render_backend->renderbuffers, renderbuffer, { 48 mempool_foreach(&gfxcore->renderbuffers, renderbuffer, {
50 gfx_del_renderbuffer(renderbuffer); 49 gfx_del_renderbuffer(renderbuffer);
51 }); 50 });
52 51
53 mempool_foreach(&render_backend->shader_programs, prog, {
54 gfx_del_shader_program(prog);
55 });
56
57 mempool_foreach( 52 mempool_foreach(
58 &render_backend->shaders, shader, { gfx_del_shader(shader); }); 53 &gfxcore->shader_programs, prog, { gfx_del_shader_program(prog); });
59 54
60 mempool_foreach( 55 mempool_foreach(&gfxcore->shaders, shader, { gfx_del_shader(shader); });
61 &render_backend->textures, texture, { gfx_del_texture(texture); }); 56
57 mempool_foreach(&gfxcore->textures, texture, { gfx_del_texture(texture); });
62} 58}
63 59
64// ----------------------------------------------------------------------------- 60// -----------------------------------------------------------------------------
65// Render commands. 61// Render commands.
66// ----------------------------------------------------------------------------- 62// -----------------------------------------------------------------------------
67 63
68void gfx_start_frame(RenderBackend* render_backend) { 64void gfx_start_frame(GfxCore* gfxcore) {
69 assert(render_backend); 65 assert(gfxcore);
70 66
71 glViewport( 67 glViewport(0, 0, gfxcore->viewport.width, gfxcore->viewport.height);
72 0, 0, render_backend->viewport.width, render_backend->viewport.height);
73 glClearColor(0, 0, 0, 0); 68 glClearColor(0, 0, 0, 0);
74 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 69 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
75 70
76 ASSERT_GL; 71 ASSERT_GL;
77} 72}
78 73
79void gfx_end_frame(RenderBackend* render_backend) { 74void gfx_end_frame(GfxCore* gfxcore) {
80 assert(render_backend); 75 assert(gfxcore);
81 ASSERT_GL; 76 ASSERT_GL;
82} 77}
83 78
84void gfx_set_viewport(RenderBackend* render_backend, int width, int height) { 79void gfx_set_viewport(GfxCore* gfxcore, int width, int height) {
85 assert(render_backend); 80 assert(gfxcore);
86 render_backend->viewport.width = width; 81 gfxcore->viewport.width = width;
87 render_backend->viewport.height = height; 82 gfxcore->viewport.height = height;
88} 83}
89 84
90void gfx_get_viewport(RenderBackend* render_backend, int* width, int* height) { 85void gfx_get_viewport(GfxCore* gfxcore, int* width, int* height) {
91 assert(render_backend); 86 assert(gfxcore);
92 assert(width); 87 assert(width);
93 assert(height); 88 assert(height);
94 *width = render_backend->viewport.width; 89 *width = gfxcore->viewport.width;
95 *height = render_backend->viewport.height; 90 *height = gfxcore->viewport.height;
96} 91}
97 92
98void gfx_set_blending(RenderBackend* render_backend, bool enable) { 93void gfx_set_blending(GfxCore* gfxcore, bool enable) {
99 assert(render_backend); 94 assert(gfxcore);
100 if (enable) { 95 if (enable) {
101 glEnable(GL_BLEND); 96 glEnable(GL_BLEND);
102 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 97 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -105,13 +100,13 @@ void gfx_set_blending(RenderBackend* render_backend, bool enable) {
105 } 100 }
106} 101}
107 102
108void gfx_set_depth_mask(RenderBackend* render_backend, bool enable) { 103void gfx_set_depth_mask(GfxCore* gfxcore, bool enable) {
109 assert(render_backend); 104 assert(gfxcore);
110 glDepthMask(enable ? GL_TRUE : GL_FALSE); 105 glDepthMask(enable ? GL_TRUE : GL_FALSE);
111} 106}
112 107
113void gfx_set_culling(RenderBackend* render_backend, bool enable) { 108void gfx_set_culling(GfxCore* gfxcore, bool enable) {
114 assert(render_backend); 109 assert(gfxcore);
115 if (enable) { 110 if (enable) {
116 glEnable(GL_CULL_FACE); 111 glEnable(GL_CULL_FACE);
117 } else { 112 } else {
@@ -119,9 +114,8 @@ void gfx_set_culling(RenderBackend* render_backend, bool enable) {
119 } 114 }
120} 115}
121 116
122void gfx_set_polygon_offset( 117void gfx_set_polygon_offset(GfxCore* gfxcore, float scale, float bias) {
123 RenderBackend* render_backend, float scale, float bias) { 118 assert(gfxcore);
124 assert(render_backend);
125 if ((scale != 0.0f) || (bias != 0.0f)) { 119 if ((scale != 0.0f) || (bias != 0.0f)) {
126 glEnable(GL_POLYGON_OFFSET_FILL); 120 glEnable(GL_POLYGON_OFFSET_FILL);
127 } else { 121 } else {
@@ -130,8 +124,8 @@ void gfx_set_polygon_offset(
130 glPolygonOffset(scale, bias); 124 glPolygonOffset(scale, bias);
131} 125}
132 126
133void gfx_reset_polygon_offset(RenderBackend* render_backend) { 127void gfx_reset_polygon_offset(GfxCore* gfxcore) {
134 assert(render_backend); 128 assert(gfxcore);
135 glPolygonOffset(0, 0); 129 glPolygonOffset(0, 0);
136 glDisable(GL_POLYGON_OFFSET_FILL); 130 glDisable(GL_POLYGON_OFFSET_FILL);
137} 131}
@@ -140,24 +134,24 @@ void gfx_reset_polygon_offset(RenderBackend* render_backend) {
140// Buffers. 134// Buffers.
141// ----------------------------------------------------------------------------- 135// -----------------------------------------------------------------------------
142 136
143Buffer* gfx_make_buffer(RenderBackend* render_backend, const BufferDesc* desc) { 137Buffer* gfx_make_buffer(GfxCore* gfxcore, const BufferDesc* desc) {
144 assert(render_backend); 138 assert(gfxcore);
145 assert(desc); 139 assert(desc);
146 140
147 Buffer* buffer = mempool_alloc(&render_backend->buffers); 141 Buffer* buffer = mempool_alloc(&gfxcore->buffers);
148 if (!gfx_init_buffer(buffer, desc)) { 142 if (!gfx_init_buffer(buffer, desc)) {
149 mempool_free(&render_backend->buffers, &buffer); 143 mempool_free(&gfxcore->buffers, &buffer);
150 return 0; 144 return 0;
151 } 145 }
152 return buffer; 146 return buffer;
153} 147}
154 148
155void gfx_destroy_buffer(RenderBackend* render_backend, Buffer** buffer) { 149void gfx_destroy_buffer(GfxCore* gfxcore, Buffer** buffer) {
156 assert(render_backend); 150 assert(gfxcore);
157 assert(buffer); 151 assert(buffer);
158 if (*buffer) { 152 if (*buffer) {
159 gfx_del_buffer(*buffer); 153 gfx_del_buffer(*buffer);
160 mempool_free(&render_backend->buffers, buffer); 154 mempool_free(&gfxcore->buffers, buffer);
161 } 155 }
162} 156}
163 157
@@ -165,26 +159,25 @@ void gfx_destroy_buffer(RenderBackend* render_backend, Buffer** buffer) {
165// Geometry. 159// Geometry.
166// ----------------------------------------------------------------------------- 160// -----------------------------------------------------------------------------
167 161
168Geometry* gfx_make_geometry( 162Geometry* gfx_make_geometry(GfxCore* gfxcore, const GeometryDesc* desc) {
169 RenderBackend* render_backend, const GeometryDesc* desc) { 163 assert(gfxcore);
170 assert(render_backend);
171 assert(desc); 164 assert(desc);
172 165
173 Geometry* geometry = mempool_alloc(&render_backend->geometries); 166 Geometry* geometry = mempool_alloc(&gfxcore->geometries);
174 if (!gfx_init_geometry(geometry, render_backend, desc)) { 167 if (!gfx_init_geometry(geometry, gfxcore, desc)) {
175 mempool_free(&render_backend->geometries, &geometry); 168 mempool_free(&gfxcore->geometries, &geometry);
176 return 0; 169 return 0;
177 } 170 }
178 return geometry; 171 return geometry;
179} 172}
180 173
181void gfx_destroy_geometry(RenderBackend* render_backend, Geometry** geometry) { 174void gfx_destroy_geometry(GfxCore* gfxcore, Geometry** geometry) {
182 assert(render_backend); 175 assert(gfxcore);
183 assert(geometry); 176 assert(geometry);
184 177
185 if (*geometry) { 178 if (*geometry) {
186 gfx_del_geometry(*geometry); 179 gfx_del_geometry(*geometry);
187 mempool_free(&render_backend->geometries, geometry); 180 mempool_free(&gfxcore->geometries, geometry);
188 } 181 }
189} 182}
190 183
@@ -192,27 +185,26 @@ void gfx_destroy_geometry(RenderBackend* render_backend, Geometry** geometry) {
192// Textures. 185// Textures.
193// ----------------------------------------------------------------------------- 186// -----------------------------------------------------------------------------
194 187
195Texture* gfx_make_texture( 188Texture* gfx_make_texture(GfxCore* gfxcore, const TextureDesc* desc) {
196 RenderBackend* render_backend, const TextureDesc* desc) { 189 assert(gfxcore);
197 assert(render_backend);
198 assert(desc); 190 assert(desc);
199 191
200 Texture* texture = mempool_alloc(&render_backend->textures); 192 Texture* texture = mempool_alloc(&gfxcore->textures);
201 if (!gfx_init_texture(texture, desc)) { 193 if (!gfx_init_texture(texture, desc)) {
202 mempool_free(&render_backend->textures, &texture); 194 mempool_free(&gfxcore->textures, &texture);
203 return 0; 195 return 0;
204 } 196 }
205 return texture; 197 return texture;
206} 198}
207 199
208void gfx_destroy_texture(RenderBackend* render_backend, Texture** texture) { 200void gfx_destroy_texture(GfxCore* gfxcore, Texture** texture) {
209 assert(render_backend); 201 assert(gfxcore);
210 assert(texture); 202 assert(texture);
211 assert(*texture); 203 assert(*texture);
212 204
213 if (*texture) { 205 if (*texture) {
214 gfx_del_texture(*texture); 206 gfx_del_texture(*texture);
215 mempool_free(&render_backend->textures, texture); 207 mempool_free(&gfxcore->textures, texture);
216 } 208 }
217} 209}
218 210
@@ -221,26 +213,25 @@ void gfx_destroy_texture(RenderBackend* render_backend, Texture** texture) {
221// ----------------------------------------------------------------------------- 213// -----------------------------------------------------------------------------
222 214
223RenderBuffer* gfx_make_renderbuffer( 215RenderBuffer* gfx_make_renderbuffer(
224 RenderBackend* render_backend, const RenderBufferDesc* desc) { 216 GfxCore* gfxcore, const RenderBufferDesc* desc) {
225 assert(render_backend); 217 assert(gfxcore);
226 assert(desc); 218 assert(desc);
227 219
228 RenderBuffer* renderbuffer = mempool_alloc(&render_backend->renderbuffers); 220 RenderBuffer* renderbuffer = mempool_alloc(&gfxcore->renderbuffers);
229 if (!gfx_init_renderbuffer(renderbuffer, desc)) { 221 if (!gfx_init_renderbuffer(renderbuffer, desc)) {
230 mempool_free(&render_backend->renderbuffers, &renderbuffer); 222 mempool_free(&gfxcore->renderbuffers, &renderbuffer);
231 } 223 }
232 return renderbuffer; 224 return renderbuffer;
233} 225}
234 226
235void gfx_destroy_renderbuffer( 227void gfx_destroy_renderbuffer(GfxCore* gfxcore, RenderBuffer** renderbuffer) {
236 RenderBackend* render_backend, RenderBuffer** renderbuffer) { 228 assert(gfxcore);
237 assert(render_backend);
238 assert(renderbuffer); 229 assert(renderbuffer);
239 assert(*renderbuffer); 230 assert(*renderbuffer);
240 231
241 if (*renderbuffer) { 232 if (*renderbuffer) {
242 gfx_del_renderbuffer(*renderbuffer); 233 gfx_del_renderbuffer(*renderbuffer);
243 mempool_free(&render_backend->renderbuffers, renderbuffer); 234 mempool_free(&gfxcore->renderbuffers, renderbuffer);
244 } 235 }
245} 236}
246 237
@@ -249,27 +240,26 @@ void gfx_destroy_renderbuffer(
249// ----------------------------------------------------------------------------- 240// -----------------------------------------------------------------------------
250 241
251FrameBuffer* gfx_make_framebuffer( 242FrameBuffer* gfx_make_framebuffer(
252 RenderBackend* render_backend, const FrameBufferDesc* desc) { 243 GfxCore* gfxcore, const FrameBufferDesc* desc) {
253 assert(render_backend); 244 assert(gfxcore);
254 assert(desc); 245 assert(desc);
255 246
256 FrameBuffer* framebuffer = mempool_alloc(&render_backend->framebuffers); 247 FrameBuffer* framebuffer = mempool_alloc(&gfxcore->framebuffers);
257 if (!gfx_init_framebuffer(framebuffer, desc)) { 248 if (!gfx_init_framebuffer(framebuffer, desc)) {
258 mempool_free(&render_backend->framebuffers, &framebuffer); 249 mempool_free(&gfxcore->framebuffers, &framebuffer);
259 return 0; 250 return 0;
260 } 251 }
261 return framebuffer; 252 return framebuffer;
262} 253}
263 254
264void gfx_destroy_framebuffer( 255void gfx_destroy_framebuffer(GfxCore* gfxcore, FrameBuffer** framebuffer) {
265 RenderBackend* render_backend, FrameBuffer** framebuffer) { 256 assert(gfxcore);
266 assert(render_backend);
267 assert(framebuffer); 257 assert(framebuffer);
268 assert(*framebuffer); 258 assert(*framebuffer);
269 259
270 if (*framebuffer) { 260 if (*framebuffer) {
271 gfx_del_framebuffer(*framebuffer); 261 gfx_del_framebuffer(*framebuffer);
272 mempool_free(&render_backend->framebuffers, framebuffer); 262 mempool_free(&gfxcore->framebuffers, framebuffer);
273 } 263 }
274} 264}
275 265
@@ -340,12 +330,12 @@ static ShaderProgramCacheEntry* find_program_cache_entry(
340 return 0; 330 return 0;
341} 331}
342 332
343Shader* gfx_make_shader(RenderBackend* render_backend, const ShaderDesc* desc) { 333Shader* gfx_make_shader(GfxCore* gfxcore, const ShaderDesc* desc) {
344 assert(render_backend); 334 assert(gfxcore);
345 assert(desc); 335 assert(desc);
346 336
347 // Check the shader cache first. 337 // Check the shader cache first.
348 ShaderCache* cache = &render_backend->shader_cache; 338 ShaderCache* cache = &gfxcore->shader_cache;
349 const uint64_t hash = hash_shader_desc(desc); 339 const uint64_t hash = hash_shader_desc(desc);
350 Shader* shader = find_cached_shader(cache, hash); 340 Shader* shader = find_cached_shader(cache, hash);
351 if (shader) { 341 if (shader) {
@@ -353,12 +343,12 @@ Shader* gfx_make_shader(RenderBackend* render_backend, const ShaderDesc* desc) {
353 return shader; 343 return shader;
354 } 344 }
355 345
356 shader = mempool_alloc(&render_backend->shaders); 346 shader = mempool_alloc(&gfxcore->shaders);
357 if (!shader) { 347 if (!shader) {
358 return 0; 348 return 0;
359 } 349 }
360 if (!gfx_compile_shader(shader, desc)) { 350 if (!gfx_compile_shader(shader, desc)) {
361 mempool_free(&render_backend->shaders, &shader); 351 mempool_free(&gfxcore->shaders, &shader);
362 return 0; 352 return 0;
363 } 353 }
364 ShaderCacheEntry* entry = mempool_alloc(cache); 354 ShaderCacheEntry* entry = mempool_alloc(cache);
@@ -367,29 +357,29 @@ Shader* gfx_make_shader(RenderBackend* render_backend, const ShaderDesc* desc) {
367 return shader; 357 return shader;
368} 358}
369 359
370void gfx_destroy_shader(RenderBackend* render_backend, Shader** shader) { 360void gfx_destroy_shader(GfxCore* gfxcore, Shader** shader) {
371 assert(render_backend); 361 assert(gfxcore);
372 assert(shader); 362 assert(shader);
373 363
374 if (*shader) { 364 if (*shader) {
375 // Remove the shader from the cache. 365 // Remove the shader from the cache.
376 ShaderCache* cache = &render_backend->shader_cache; 366 ShaderCache* cache = &gfxcore->shader_cache;
377 ShaderCacheEntry* entry = find_shader_cache_entry(cache, *shader); 367 ShaderCacheEntry* entry = find_shader_cache_entry(cache, *shader);
378 assert(entry); // Must be there, shaders can't go untracked. 368 assert(entry); // Must be there, shaders can't go untracked.
379 mempool_free(cache, &entry); 369 mempool_free(cache, &entry);
380 370
381 gfx_del_shader(*shader); 371 gfx_del_shader(*shader);
382 mempool_free(&render_backend->shaders, shader); 372 mempool_free(&gfxcore->shaders, shader);
383 } 373 }
384} 374}
385 375
386ShaderProgram* gfx_make_shader_program( 376ShaderProgram* gfx_make_shader_program(
387 RenderBackend* render_backend, const ShaderProgramDesc* desc) { 377 GfxCore* gfxcore, const ShaderProgramDesc* desc) {
388 assert(render_backend); 378 assert(gfxcore);
389 assert(desc); 379 assert(desc);
390 380
391 // Check the shader program cache first. 381 // Check the shader program cache first.
392 ProgramCache* cache = &render_backend->program_cache; 382 ProgramCache* cache = &gfxcore->program_cache;
393 const uint64_t hash = hash_program_desc(desc); 383 const uint64_t hash = hash_program_desc(desc);
394 ShaderProgram* prog = find_cached_program(cache, hash); 384 ShaderProgram* prog = find_cached_program(cache, hash);
395 if (prog) { 385 if (prog) {
@@ -397,9 +387,9 @@ ShaderProgram* gfx_make_shader_program(
397 return prog; 387 return prog;
398 } 388 }
399 389
400 prog = mempool_alloc(&render_backend->shader_programs); 390 prog = mempool_alloc(&gfxcore->shader_programs);
401 if (!gfx_build_shader_program(prog, desc)) { 391 if (!gfx_build_shader_program(prog, desc)) {
402 mempool_free(&render_backend->shader_programs, &prog); 392 mempool_free(&gfxcore->shader_programs, &prog);
403 return 0; 393 return 0;
404 } 394 }
405 ShaderProgramCacheEntry* entry = mempool_alloc(cache); 395 ShaderProgramCacheEntry* entry = mempool_alloc(cache);
@@ -408,18 +398,17 @@ ShaderProgram* gfx_make_shader_program(
408 return prog; 398 return prog;
409} 399}
410 400
411void gfx_destroy_shader_program( 401void gfx_destroy_shader_program(GfxCore* gfxcore, ShaderProgram** prog) {
412 RenderBackend* render_backend, ShaderProgram** prog) { 402 assert(gfxcore);
413 assert(render_backend);
414 assert(prog); 403 assert(prog);
415 if (*prog) { 404 if (*prog) {
416 // Remove the shader program from the cache. 405 // Remove the shader program from the cache.
417 ProgramCache* cache = &render_backend->program_cache; 406 ProgramCache* cache = &gfxcore->program_cache;
418 ShaderProgramCacheEntry* entry = find_program_cache_entry(cache, *prog); 407 ShaderProgramCacheEntry* entry = find_program_cache_entry(cache, *prog);
419 assert(entry); // Must be there, shaders can't go untracked. 408 assert(entry); // Must be there, shaders can't go untracked.
420 mempool_free(cache, &entry); 409 mempool_free(cache, &entry);
421 410
422 gfx_del_shader_program(*prog); 411 gfx_del_shader_program(*prog);
423 mempool_free(&render_backend->shader_programs, prog); 412 mempool_free(&gfxcore->shader_programs, prog);
424 } 413 }
425} 414}
diff --git a/gfx/src/render/render_backend_impl.h b/gfx/src/render/core_impl.h
index e149e98..e27c0f2 100644
--- a/gfx/src/render/render_backend_impl.h
+++ b/gfx/src/render/core_impl.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <gfx/sizes.h> 4#include <gfx/sizes.h>
5 5
6#include "buffer.h" 6#include "buffer.h"
@@ -44,7 +44,7 @@ typedef struct {
44 int height; 44 int height;
45} Viewport; 45} Viewport;
46 46
47typedef struct RenderBackend { 47typedef struct GfxCore {
48 Viewport viewport; 48 Viewport viewport;
49 // mempools for render-specific objects: textures, geometry, etc. 49 // mempools for render-specific objects: textures, geometry, etc.
50 buffer_pool buffers; 50 buffer_pool buffers;
@@ -57,10 +57,10 @@ typedef struct RenderBackend {
57 // Caches. 57 // Caches.
58 ShaderCache shader_cache; 58 ShaderCache shader_cache;
59 ProgramCache program_cache; 59 ProgramCache program_cache;
60} RenderBackend; 60} GfxCore;
61 61
62/// Create a new render backend. 62/// Create a new render backend.
63void gfx_init_render_backend(RenderBackend*); 63void gfx_init_gfxcore(GfxCore*);
64 64
65/// Destroy the render backend. 65/// Destroy the render backend.
66void gfx_del_render_backend(RenderBackend*); 66void gfx_del_gfxcore(GfxCore*);
diff --git a/gfx/src/render/framebuffer.h b/gfx/src/render/framebuffer.h
index 7153b30..1a3439c 100644
--- a/gfx/src/render/framebuffer.h
+++ b/gfx/src/render/framebuffer.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "gl_util.h" 5#include "gl_util.h"
6 6
diff --git a/gfx/src/render/geometry.c b/gfx/src/render/geometry.c
index 8974387..cfc749f 100644
--- a/gfx/src/render/geometry.c
+++ b/gfx/src/render/geometry.c
@@ -30,11 +30,11 @@ static GLenum primitive_type_to_gl(PrimitiveType type) {
30/// Create a typed buffer for the buffer view if the view does not already point 30/// Create a typed buffer for the buffer view if the view does not already point
31/// to a buffer. 31/// to a buffer.
32void init_view_buffer( 32void init_view_buffer(
33 RenderBackend* render_backend, BufferView* view, BufferType buffer_type, 33 GfxCore* gfxcore, BufferView* view, BufferType buffer_type,
34 BufferUsage buffer_usage) { 34 BufferUsage buffer_usage) {
35 if (!view->buffer) { 35 if (!view->buffer) {
36 view->buffer = gfx_make_buffer( 36 view->buffer = gfx_make_buffer(
37 render_backend, 37 gfxcore,
38 &(BufferDesc){ 38 &(BufferDesc){
39 .usage = buffer_usage, 39 .usage = buffer_usage,
40 .type = buffer_type, 40 .type = buffer_type,
@@ -47,10 +47,10 @@ void init_view_buffer(
47 47
48/// Configure the buffer in teh VAO. 48/// Configure the buffer in teh VAO.
49static void configure_buffer( 49static void configure_buffer(
50 RenderBackend* render_backend, const GeometryDesc* desc, BufferView* view, 50 GfxCore* gfxcore, const GeometryDesc* desc, BufferView* view,
51 size_t num_components, size_t component_size_bytes, GLenum component_type, 51 size_t num_components, size_t component_size_bytes, GLenum component_type,
52 GLboolean normalized, GLuint channel) { 52 GLboolean normalized, GLuint channel) {
53 assert(render_backend); 53 assert(gfxcore);
54 assert(desc); 54 assert(desc);
55 assert(view); 55 assert(view);
56 assert(view->buffer); 56 assert(view->buffer);
@@ -78,127 +78,117 @@ static void configure_buffer(
78 glBindBuffer(GL_ARRAY_BUFFER, 0); 78 glBindBuffer(GL_ARRAY_BUFFER, 0);
79} 79}
80 80
81static bool configure_vertex_attributes( 81static bool configure_vertex_attributes(GfxCore* gfxcore, GeometryDesc* desc) {
82 RenderBackend* render_backend, GeometryDesc* desc) { 82 assert(gfxcore);
83 assert(render_backend);
84 assert(desc); 83 assert(desc);
85 84
86 if (view_is_populated(desc->positions3d)) { 85 if (view_is_populated(desc->positions3d)) {
87 init_view_buffer( 86 init_view_buffer(
88 render_backend, (BufferView*)&desc->positions3d, Buffer3d, 87 gfxcore, (BufferView*)&desc->positions3d, Buffer3d, desc->buffer_usage);
89 desc->buffer_usage);
90 if (!desc->positions3d.buffer) { 88 if (!desc->positions3d.buffer) {
91 return false; 89 return false;
92 } 90 }
93 configure_buffer( 91 configure_buffer(
94 render_backend, desc, (BufferView*)&desc->positions3d, 3, sizeof(float), 92 gfxcore, desc, (BufferView*)&desc->positions3d, 3, sizeof(float),
95 GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL); 93 GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL);
96 } else if (view_is_populated(desc->positions2d)) { 94 } else if (view_is_populated(desc->positions2d)) {
97 init_view_buffer( 95 init_view_buffer(
98 render_backend, (BufferView*)&desc->positions2d, Buffer2d, 96 gfxcore, (BufferView*)&desc->positions2d, Buffer2d, desc->buffer_usage);
99 desc->buffer_usage);
100 if (!desc->positions2d.buffer) { 97 if (!desc->positions2d.buffer) {
101 return false; 98 return false;
102 } 99 }
103 configure_buffer( 100 configure_buffer(
104 render_backend, desc, (BufferView*)&desc->positions2d, 2, sizeof(float), 101 gfxcore, desc, (BufferView*)&desc->positions2d, 2, sizeof(float),
105 GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL); 102 GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL);
106 } 103 }
107 if (view_is_populated(desc->normals)) { 104 if (view_is_populated(desc->normals)) {
108 init_view_buffer( 105 init_view_buffer(
109 render_backend, (BufferView*)&desc->normals, Buffer3d, 106 gfxcore, (BufferView*)&desc->normals, Buffer3d, desc->buffer_usage);
110 desc->buffer_usage);
111 if (!desc->normals.buffer) { 107 if (!desc->normals.buffer) {
112 return false; 108 return false;
113 } 109 }
114 configure_buffer( 110 configure_buffer(
115 render_backend, desc, (BufferView*)&desc->normals, 3, sizeof(float), 111 gfxcore, desc, (BufferView*)&desc->normals, 3, sizeof(float), GL_FLOAT,
116 GL_FLOAT, GL_FALSE, GFX_NORMAL_CHANNEL); 112 GL_FALSE, GFX_NORMAL_CHANNEL);
117 } 113 }
118 if (view_is_populated(desc->tangents)) { 114 if (view_is_populated(desc->tangents)) {
119 init_view_buffer( 115 init_view_buffer(
120 render_backend, (BufferView*)&desc->tangents, Buffer4d, 116 gfxcore, (BufferView*)&desc->tangents, Buffer4d, desc->buffer_usage);
121 desc->buffer_usage);
122 if (!desc->tangents.buffer) { 117 if (!desc->tangents.buffer) {
123 return false; 118 return false;
124 } 119 }
125 configure_buffer( 120 configure_buffer(
126 render_backend, desc, (BufferView*)&desc->tangents, 4, sizeof(float), 121 gfxcore, desc, (BufferView*)&desc->tangents, 4, sizeof(float), GL_FLOAT,
127 GL_FLOAT, GL_FALSE, GFX_TANGENT_CHANNEL); 122 GL_FALSE, GFX_TANGENT_CHANNEL);
128 } 123 }
129 if (view_is_populated(desc->texcoords)) { 124 if (view_is_populated(desc->texcoords)) {
130 init_view_buffer( 125 init_view_buffer(
131 render_backend, (BufferView*)&desc->texcoords, Buffer2d, 126 gfxcore, (BufferView*)&desc->texcoords, Buffer2d, desc->buffer_usage);
132 desc->buffer_usage);
133 if (!desc->texcoords.buffer) { 127 if (!desc->texcoords.buffer) {
134 return false; 128 return false;
135 } 129 }
136 configure_buffer( 130 configure_buffer(
137 render_backend, desc, (BufferView*)&desc->texcoords, 2, sizeof(float), 131 gfxcore, desc, (BufferView*)&desc->texcoords, 2, sizeof(float),
138 GL_FLOAT, GL_FALSE, GFX_TEXCOORDS_CHANNEL); 132 GL_FLOAT, GL_FALSE, GFX_TEXCOORDS_CHANNEL);
139 } 133 }
140 if (view_is_populated(desc->joints.u8)) { 134 if (view_is_populated(desc->joints.u8)) {
141 init_view_buffer( 135 init_view_buffer(
142 render_backend, (BufferView*)&desc->joints.u8, BufferU8, 136 gfxcore, (BufferView*)&desc->joints.u8, BufferU8, desc->buffer_usage);
143 desc->buffer_usage);
144 if (!desc->joints.u8.buffer) { 137 if (!desc->joints.u8.buffer) {
145 return false; 138 return false;
146 } 139 }
147 configure_buffer( 140 configure_buffer(
148 render_backend, desc, (BufferView*)&desc->joints.u8, 4, sizeof(uint8_t), 141 gfxcore, desc, (BufferView*)&desc->joints.u8, 4, sizeof(uint8_t),
149 GL_UNSIGNED_BYTE, GL_FALSE, GFX_JOINTS_CHANNEL); 142 GL_UNSIGNED_BYTE, GL_FALSE, GFX_JOINTS_CHANNEL);
150 } else if (view_is_populated(desc->joints.u16)) { 143 } else if (view_is_populated(desc->joints.u16)) {
151 init_view_buffer( 144 init_view_buffer(
152 render_backend, (BufferView*)&desc->joints.u16, BufferU16, 145 gfxcore, (BufferView*)&desc->joints.u16, BufferU16, desc->buffer_usage);
153 desc->buffer_usage);
154 if (!desc->joints.u16.buffer) { 146 if (!desc->joints.u16.buffer) {
155 return false; 147 return false;
156 } 148 }
157 configure_buffer( 149 configure_buffer(
158 render_backend, desc, (BufferView*)&desc->joints.u16, 4, 150 gfxcore, desc, (BufferView*)&desc->joints.u16, 4, sizeof(uint16_t),
159 sizeof(uint16_t), GL_UNSIGNED_SHORT, GL_FALSE, GFX_JOINTS_CHANNEL); 151 GL_UNSIGNED_SHORT, GL_FALSE, GFX_JOINTS_CHANNEL);
160 } 152 }
161 153
162 // If weights are given as unsigned integers, then they are normalized 154 // If weights are given as unsigned integers, then they are normalized
163 // when read by the shader. 155 // when read by the shader.
164 if (view_is_populated(desc->weights.u8)) { 156 if (view_is_populated(desc->weights.u8)) {
165 init_view_buffer( 157 init_view_buffer(
166 render_backend, (BufferView*)&desc->weights.u8, BufferU8, 158 gfxcore, (BufferView*)&desc->weights.u8, BufferU8, desc->buffer_usage);
167 desc->buffer_usage);
168 if (!desc->weights.u8.buffer) { 159 if (!desc->weights.u8.buffer) {
169 return false; 160 return false;
170 } 161 }
171 configure_buffer( 162 configure_buffer(
172 render_backend, desc, (BufferView*)&desc->weights.u8, 4, 163 gfxcore, desc, (BufferView*)&desc->weights.u8, 4, sizeof(uint8_t),
173 sizeof(uint8_t), GL_UNSIGNED_BYTE, GL_TRUE, GFX_WEIGHTS_CHANNEL); 164 GL_UNSIGNED_BYTE, GL_TRUE, GFX_WEIGHTS_CHANNEL);
174 } else if (view_is_populated(desc->weights.u16)) { 165 } else if (view_is_populated(desc->weights.u16)) {
175 init_view_buffer( 166 init_view_buffer(
176 render_backend, (BufferView*)&desc->weights.u16, BufferU16, 167 gfxcore, (BufferView*)&desc->weights.u16, BufferU16,
177 desc->buffer_usage); 168 desc->buffer_usage);
178 if (!desc->weights.u16.buffer) { 169 if (!desc->weights.u16.buffer) {
179 return false; 170 return false;
180 } 171 }
181 configure_buffer( 172 configure_buffer(
182 render_backend, desc, (BufferView*)&desc->weights.u16, 4, 173 gfxcore, desc, (BufferView*)&desc->weights.u16, 4, sizeof(uint16_t),
183 sizeof(uint16_t), GL_UNSIGNED_SHORT, GL_TRUE, GFX_WEIGHTS_CHANNEL); 174 GL_UNSIGNED_SHORT, GL_TRUE, GFX_WEIGHTS_CHANNEL);
184 } else if (view_is_populated(desc->weights.floats)) { 175 } else if (view_is_populated(desc->weights.floats)) {
185 init_view_buffer( 176 init_view_buffer(
186 render_backend, (BufferView*)&desc->weights.floats, BufferFloat, 177 gfxcore, (BufferView*)&desc->weights.floats, BufferFloat,
187 desc->buffer_usage); 178 desc->buffer_usage);
188 if (!desc->weights.floats.buffer) { 179 if (!desc->weights.floats.buffer) {
189 return false; 180 return false;
190 } 181 }
191 configure_buffer( 182 configure_buffer(
192 render_backend, desc, (BufferView*)&desc->weights.floats, 4, 183 gfxcore, desc, (BufferView*)&desc->weights.floats, 4, sizeof(float),
193 sizeof(float), GL_FLOAT, GL_FALSE, GFX_WEIGHTS_CHANNEL); 184 GL_FLOAT, GL_FALSE, GFX_WEIGHTS_CHANNEL);
194 } 185 }
195 186
196 return true; 187 return true;
197} 188}
198 189
199static bool configure_indices( 190static bool configure_indices(GfxCore* gfxcore, GeometryDesc* desc) {
200 RenderBackend* render_backend, GeometryDesc* desc) { 191 assert(gfxcore);
201 assert(render_backend);
202 assert(desc); 192 assert(desc);
203 193
204 if (view_is_populated(desc->indices8)) { 194 if (view_is_populated(desc->indices8)) {
@@ -206,8 +196,7 @@ static bool configure_indices(
206 assert( 196 assert(
207 desc->num_indices <= desc->indices8.size_bytes / sizeof(VertexIndex8)); 197 desc->num_indices <= desc->indices8.size_bytes / sizeof(VertexIndex8));
208 init_view_buffer( 198 init_view_buffer(
209 render_backend, (BufferView*)&desc->indices8, BufferU8, 199 gfxcore, (BufferView*)&desc->indices8, BufferU8, desc->buffer_usage);
210 desc->buffer_usage);
211 if (!desc->indices8.buffer) { 200 if (!desc->indices8.buffer) {
212 return false; 201 return false;
213 } 202 }
@@ -217,8 +206,7 @@ static bool configure_indices(
217 desc->num_indices <= 206 desc->num_indices <=
218 desc->indices16.size_bytes / sizeof(VertexIndex16)); 207 desc->indices16.size_bytes / sizeof(VertexIndex16));
219 init_view_buffer( 208 init_view_buffer(
220 render_backend, (BufferView*)&desc->indices16, BufferU16, 209 gfxcore, (BufferView*)&desc->indices16, BufferU16, desc->buffer_usage);
221 desc->buffer_usage);
222 if (!desc->indices16.buffer) { 210 if (!desc->indices16.buffer) {
223 return false; 211 return false;
224 } 212 }
@@ -228,20 +216,19 @@ static bool configure_indices(
228} 216}
229 217
230bool gfx_init_geometry( 218bool gfx_init_geometry(
231 Geometry* geometry, RenderBackend* render_backend, 219 Geometry* geometry, GfxCore* gfxcore, const GeometryDesc* input_desc) {
232 const GeometryDesc* input_desc) {
233 assert(geometry); 220 assert(geometry);
234 assert(render_backend); 221 assert(gfxcore);
235 assert(input_desc); 222 assert(input_desc);
236 assert( 223 assert(
237 view_is_populated(input_desc->positions3d) || 224 view_is_populated(input_desc->positions3d) ||
238 view_is_populated(input_desc->positions2d)); 225 view_is_populated(input_desc->positions2d));
239 assert(input_desc->num_verts > 0); 226 assert(input_desc->num_verts > 0);
240 227
241 geometry->mode = primitive_type_to_gl(input_desc->type); 228 geometry->mode = primitive_type_to_gl(input_desc->type);
242 geometry->desc = *input_desc; 229 geometry->desc = *input_desc;
243 geometry->num_verts = input_desc->num_verts; 230 geometry->num_verts = input_desc->num_verts;
244 geometry->render_backend = render_backend; 231 geometry->gfxcore = gfxcore;
245 232
246 // The geometry's copy of the descriptor is manipulated below. Create a 233 // The geometry's copy of the descriptor is manipulated below. Create a
247 // shorter name for it. 234 // shorter name for it.
@@ -249,10 +236,10 @@ bool gfx_init_geometry(
249 236
250 glGenVertexArrays(1, &geometry->vao); 237 glGenVertexArrays(1, &geometry->vao);
251 glBindVertexArray(geometry->vao); 238 glBindVertexArray(geometry->vao);
252 if (!configure_vertex_attributes(render_backend, desc)) { 239 if (!configure_vertex_attributes(gfxcore, desc)) {
253 goto cleanup; 240 goto cleanup;
254 } 241 }
255 if (!configure_indices(render_backend, desc)) { 242 if (!configure_indices(gfxcore, desc)) {
256 goto cleanup; 243 goto cleanup;
257 } 244 }
258 glBindVertexArray(0); 245 glBindVertexArray(0);
diff --git a/gfx/src/render/geometry.h b/gfx/src/render/geometry.h
index 484934d..c37a76f 100644
--- a/gfx/src/render/geometry.h
+++ b/gfx/src/render/geometry.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "gl_util.h" 5#include "gl_util.h"
6 6
@@ -18,11 +18,11 @@ typedef struct Geometry {
18 GeometryDesc desc; 18 GeometryDesc desc;
19 size_t num_verts; // May differ from the initial value in the descriptor if 19 size_t num_verts; // May differ from the initial value in the descriptor if
20 // the geometry is updated. 20 // the geometry is updated.
21 RenderBackend* render_backend; 21 GfxCore* gfxcore;
22} Geometry; 22} Geometry;
23 23
24/// Create new geometry. 24/// Create new geometry.
25bool gfx_init_geometry(Geometry*, RenderBackend*, const GeometryDesc*); 25bool gfx_init_geometry(Geometry*, GfxCore*, const GeometryDesc*);
26 26
27/// Destroy the geometry. 27/// Destroy the geometry.
28void gfx_del_geometry(Geometry*); 28void gfx_del_geometry(Geometry*);
diff --git a/gfx/src/render/renderbuffer.h b/gfx/src/render/renderbuffer.h
index 458dc83..ea11610 100644
--- a/gfx/src/render/renderbuffer.h
+++ b/gfx/src/render/renderbuffer.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "gl_util.h" 5#include "gl_util.h"
6 6
diff --git a/gfx/src/render/shader.h b/gfx/src/render/shader.h
index a1aaec2..b9f5679 100644
--- a/gfx/src/render/shader.h
+++ b/gfx/src/render/shader.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "gl_util.h" 5#include "gl_util.h"
6 6
diff --git a/gfx/src/render/shader_program.h b/gfx/src/render/shader_program.h
index c269190..1443663 100644
--- a/gfx/src/render/shader_program.h
+++ b/gfx/src/render/shader_program.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <gfx/sizes.h> 4#include <gfx/sizes.h>
5 5
6#include "gl_util.h" 6#include "gl_util.h"
@@ -12,9 +12,9 @@
12typedef struct Texture Texture; 12typedef struct Texture Texture;
13 13
14typedef struct ShaderProgram { 14typedef struct ShaderProgram {
15 GLuint id; 15 GLuint id;
16 ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_SHADER]; 16 ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_SHADER];
17 int num_uniforms; 17 int num_uniforms;
18} ShaderProgram; 18} ShaderProgram;
19 19
20/// Create a new shader program. 20/// Create a new shader program.
diff --git a/gfx/src/render/texture.h b/gfx/src/render/texture.h
index f667752..4af41e9 100644
--- a/gfx/src/render/texture.h
+++ b/gfx/src/render/texture.h
@@ -1,6 +1,6 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "gl_util.h" 5#include "gl_util.h"
6 6
diff --git a/gfx/src/renderer/imm_renderer.c b/gfx/src/renderer/imm_renderer.c
index dd5e2cb..8cf3a10 100644
--- a/gfx/src/renderer/imm_renderer.c
+++ b/gfx/src/renderer/imm_renderer.c
@@ -1,6 +1,6 @@
1#include "imm_renderer_impl.h" 1#include "imm_renderer_impl.h"
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <gfx/util/shader.h> 4#include <gfx/util/shader.h>
5 5
6#include <math/aabb3.h> 6#include <math/aabb3.h>
@@ -8,27 +8,26 @@
8#include <assert.h> 8#include <assert.h>
9#include <string.h> // memcpy 9#include <string.h> // memcpy
10 10
11bool imm_renderer_make(ImmRenderer* renderer, RenderBackend* render_backend) { 11bool imm_renderer_make(ImmRenderer* renderer, GfxCore* gfxcore) {
12 assert(renderer); 12 assert(renderer);
13 assert(render_backend); 13 assert(gfxcore);
14 14
15 const size_t num_triangle_verts = IMM_MAX_NUM_TRIANGLES * 3; 15 const size_t num_triangle_verts = IMM_MAX_NUM_TRIANGLES * 3;
16 16
17 renderer->render_backend = render_backend; 17 renderer->gfxcore = gfxcore;
18 18
19 renderer->triangles = gfx_make_geometry( 19 renderer->triangles = gfx_make_geometry(
20 render_backend, 20 gfxcore, &(GeometryDesc){
21 &(GeometryDesc){ 21 .type = Triangles,
22 .type = Triangles, 22 .buffer_usage = BufferDynamic,
23 .buffer_usage = BufferDynamic, 23 .num_verts = num_triangle_verts,
24 .num_verts = num_triangle_verts, 24 .positions3d = (BufferView3d){
25 .positions3d = 25 .size_bytes = num_triangle_verts * sizeof(vec3)}});
26 (BufferView3d){.size_bytes = num_triangle_verts * sizeof(vec3)}});
27 if (!renderer->triangles) { 26 if (!renderer->triangles) {
28 goto cleanup; 27 goto cleanup;
29 } 28 }
30 29
31 renderer->shader = gfx_make_immediate_mode_shader(render_backend); 30 renderer->shader = gfx_make_immediate_mode_shader(gfxcore);
32 if (!renderer->shader) { 31 if (!renderer->shader) {
33 goto cleanup; 32 goto cleanup;
34 } 33 }
@@ -47,15 +46,15 @@ cleanup:
47 46
48void imm_renderer_destroy(ImmRenderer* renderer) { 47void imm_renderer_destroy(ImmRenderer* renderer) {
49 assert(renderer); 48 assert(renderer);
50 assert(renderer->render_backend); 49 assert(renderer->gfxcore);
51 50
52 if (renderer->triangles) { 51 if (renderer->triangles) {
53 gfx_destroy_geometry(renderer->render_backend, &renderer->triangles); 52 gfx_destroy_geometry(renderer->gfxcore, &renderer->triangles);
54 // TODO: Could also destroy the geometry's buffers here. 53 // TODO: Could also destroy the geometry's buffers here.
55 } 54 }
56 55
57 if (renderer->shader) { 56 if (renderer->shader) {
58 gfx_destroy_shader_program(renderer->render_backend, &renderer->shader); 57 gfx_destroy_shader_program(renderer->gfxcore, &renderer->shader);
59 } 58 }
60} 59}
61 60
diff --git a/gfx/src/renderer/imm_renderer_impl.h b/gfx/src/renderer/imm_renderer_impl.h
index 7769855..5ece354 100644
--- a/gfx/src/renderer/imm_renderer_impl.h
+++ b/gfx/src/renderer/imm_renderer_impl.h
@@ -18,7 +18,7 @@ typedef struct ShaderProgram ShaderProgram;
18/// of primitives per frame. It does not adjust this number dynamically. Keeps 18/// of primitives per frame. It does not adjust this number dynamically. Keeps
19/// things simple while the extra complexity is not needed. 19/// things simple while the extra complexity is not needed.
20typedef struct ImmRenderer { 20typedef struct ImmRenderer {
21 RenderBackend* render_backend; 21 GfxCore* gfxcore;
22 ShaderProgram* shader; 22 ShaderProgram* shader;
23 Geometry* triangles; 23 Geometry* triangles;
24 size_t num_triangle_verts; // Number of triangle verts this frame. 24 size_t num_triangle_verts; // Number of triangle verts this frame.
@@ -35,7 +35,7 @@ typedef struct ImmRenderer {
35} ImmRenderer; 35} ImmRenderer;
36 36
37/// Create a new immediate mode renderer. 37/// Create a new immediate mode renderer.
38bool imm_renderer_make(ImmRenderer*, RenderBackend*); 38bool imm_renderer_make(ImmRenderer*, GfxCore*);
39 39
40/// Destroy the immediate mode renderer. 40/// Destroy the immediate mode renderer.
41void imm_renderer_destroy(ImmRenderer*); 41void imm_renderer_destroy(ImmRenderer*);
diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c
index 2244733..d615918 100644
--- a/gfx/src/renderer/renderer.c
+++ b/gfx/src/renderer/renderer.c
@@ -11,7 +11,7 @@
11#include "scene/scene_impl.h" 11#include "scene/scene_impl.h"
12#include "scene/scene_memory.h" 12#include "scene/scene_memory.h"
13 13
14#include <gfx/render_backend.h> 14#include <gfx/core.h>
15#include <gfx/util/ibl.h> 15#include <gfx/util/ibl.h>
16#include <gfx/util/shader.h> 16#include <gfx/util/shader.h>
17 17
@@ -29,11 +29,11 @@ static const int PREFILTERED_ENVIRONMENT_MAP_HEIGHT = 128;
29static const int BRDF_INTEGRATION_MAP_WIDTH = 512; 29static const int BRDF_INTEGRATION_MAP_WIDTH = 512;
30static const int BRDF_INTEGRATION_MAP_HEIGHT = 512; 30static const int BRDF_INTEGRATION_MAP_HEIGHT = 512;
31 31
32bool renderer_make(Renderer* renderer, RenderBackend* render_backend) { 32bool renderer_make(Renderer* renderer, GfxCore* gfxcore) {
33 assert(renderer); 33 assert(renderer);
34 assert(render_backend); 34 assert(gfxcore);
35 35
36 renderer->render_backend = render_backend; 36 renderer->gfxcore = gfxcore;
37 37
38 return true; 38 return true;
39} 39}
@@ -42,23 +42,23 @@ void renderer_destroy(Renderer* renderer) {
42 if (!renderer) { 42 if (!renderer) {
43 return; 43 return;
44 } 44 }
45 assert(renderer->render_backend); 45 assert(renderer->gfxcore);
46 RenderBackend* render_backend = renderer->render_backend; 46 GfxCore* gfxcore = renderer->gfxcore;
47 if (renderer->ibl) { 47 if (renderer->ibl) {
48 gfx_destroy_ibl(render_backend, &renderer->ibl); 48 gfx_destroy_ibl(gfxcore, &renderer->ibl);
49 } 49 }
50 if (renderer->shaders.debug) { 50 if (renderer->shaders.debug) {
51 gfx_destroy_shader_program(render_backend, &renderer->shaders.debug); 51 gfx_destroy_shader_program(gfxcore, &renderer->shaders.debug);
52 } 52 }
53 if (renderer->shaders.normals) { 53 if (renderer->shaders.normals) {
54 gfx_destroy_shader_program(render_backend, &renderer->shaders.normals); 54 gfx_destroy_shader_program(gfxcore, &renderer->shaders.normals);
55 } 55 }
56 if (renderer->shaders.normal_mapped_normals) { 56 if (renderer->shaders.normal_mapped_normals) {
57 gfx_destroy_shader_program( 57 gfx_destroy_shader_program(
58 render_backend, &renderer->shaders.normal_mapped_normals); 58 gfxcore, &renderer->shaders.normal_mapped_normals);
59 } 59 }
60 if (renderer->shaders.tangents) { 60 if (renderer->shaders.tangents) {
61 gfx_destroy_shader_program(render_backend, &renderer->shaders.tangents); 61 gfx_destroy_shader_program(gfxcore, &renderer->shaders.tangents);
62 } 62 }
63} 63}
64 64
@@ -66,14 +66,13 @@ void renderer_destroy(Renderer* renderer) {
66static bool init_ibl(Renderer* renderer) { 66static bool init_ibl(Renderer* renderer) {
67 assert(renderer); 67 assert(renderer);
68 68
69 if (!renderer->ibl && 69 if (!renderer->ibl && !(renderer->ibl = gfx_make_ibl(renderer->gfxcore))) {
70 !(renderer->ibl = gfx_make_ibl(renderer->render_backend))) {
71 return false; 70 return false;
72 } 71 }
73 72
74 if (!renderer->brdf_integration_map && 73 if (!renderer->brdf_integration_map &&
75 !(renderer->brdf_integration_map = gfx_make_brdf_integration_map( 74 !(renderer->brdf_integration_map = gfx_make_brdf_integration_map(
76 renderer->ibl, renderer->render_backend, BRDF_INTEGRATION_MAP_WIDTH, 75 renderer->ibl, renderer->gfxcore, BRDF_INTEGRATION_MAP_WIDTH,
77 BRDF_INTEGRATION_MAP_HEIGHT))) { 76 BRDF_INTEGRATION_MAP_HEIGHT))) {
78 return false; 77 return false;
79 } 78 }
@@ -84,13 +83,13 @@ static bool init_ibl(Renderer* renderer) {
84static ShaderProgram* load_shader(Renderer* renderer, RenderSceneMode mode) { 83static ShaderProgram* load_shader(Renderer* renderer, RenderSceneMode mode) {
85 assert(renderer); 84 assert(renderer);
86 85
87#define LOAD_AND_RETURN(pShader, constructor) \ 86#define LOAD_AND_RETURN(pShader, constructor) \
88 { \ 87 { \
89 if (!pShader) { \ 88 if (!pShader) { \
90 pShader = constructor(renderer->render_backend); \ 89 pShader = constructor(renderer->gfxcore); \
91 } \ 90 } \
92 assert(pShader); \ 91 assert(pShader); \
93 return pShader; \ 92 return pShader; \
94 } 93 }
95 94
96 switch (mode) { 95 switch (mode) {
@@ -121,8 +120,7 @@ static ShaderProgram* load_shader(Renderer* renderer, RenderSceneMode mode) {
121/// Computes irradiance and prefiltered environment maps for the light if they 120/// Computes irradiance and prefiltered environment maps for the light if they
122/// have not been already computed. 121/// have not been already computed.
123static bool setup_environment_light( 122static bool setup_environment_light(
124 Renderer* renderer, RenderBackend* render_backend, 123 Renderer* renderer, GfxCore* gfxcore, EnvironmentLight* light) {
125 EnvironmentLight* light) {
126 assert(renderer); 124 assert(renderer);
127 assert(light); 125 assert(light);
128 126
@@ -139,14 +137,14 @@ static bool setup_environment_light(
139 Texture* prefiltered_environment_map = 0; 137 Texture* prefiltered_environment_map = 0;
140 138
141 if (!(irradiance_map = gfx_make_irradiance_map( 139 if (!(irradiance_map = gfx_make_irradiance_map(
142 renderer->ibl, render_backend, light->environment_map, 140 renderer->ibl, gfxcore, light->environment_map,
143 IRRADIANCE_MAP_WIDTH, IRRADIANCE_MAP_HEIGHT))) { 141 IRRADIANCE_MAP_WIDTH, IRRADIANCE_MAP_HEIGHT))) {
144 goto cleanup; 142 goto cleanup;
145 } 143 }
146 144
147 int max_mip_level = 0; 145 int max_mip_level = 0;
148 if (!(prefiltered_environment_map = gfx_make_prefiltered_environment_map( 146 if (!(prefiltered_environment_map = gfx_make_prefiltered_environment_map(
149 renderer->ibl, render_backend, light->environment_map, 147 renderer->ibl, gfxcore, light->environment_map,
150 PREFILTERED_ENVIRONMENT_MAP_WIDTH, 148 PREFILTERED_ENVIRONMENT_MAP_WIDTH,
151 PREFILTERED_ENVIRONMENT_MAP_HEIGHT, &max_mip_level))) { 149 PREFILTERED_ENVIRONMENT_MAP_HEIGHT, &max_mip_level))) {
152 goto cleanup; 150 goto cleanup;
@@ -160,16 +158,16 @@ static bool setup_environment_light(
160 158
161cleanup: 159cleanup:
162 if (irradiance_map) { 160 if (irradiance_map) {
163 gfx_destroy_texture(render_backend, &irradiance_map); 161 gfx_destroy_texture(gfxcore, &irradiance_map);
164 } 162 }
165 if (prefiltered_environment_map) { 163 if (prefiltered_environment_map) {
166 gfx_destroy_texture(render_backend, &prefiltered_environment_map); 164 gfx_destroy_texture(gfxcore, &prefiltered_environment_map);
167 } 165 }
168 return false; 166 return false;
169} 167}
170 168
171typedef struct RenderState { 169typedef struct RenderState {
172 RenderBackend* render_backend; 170 GfxCore* gfxcore;
173 Renderer* renderer; 171 Renderer* renderer;
174 ShaderProgram* shader; // Null to use scene shaders. 172 ShaderProgram* shader; // Null to use scene shaders.
175 const Scene* scene; 173 const Scene* scene;
@@ -220,7 +218,7 @@ static void draw_recursively(
220 218
221 if (light->type == EnvironmentLightType) { 219 if (light->type == EnvironmentLightType) {
222 bool result = setup_environment_light( 220 bool result = setup_environment_light(
223 state->renderer, state->render_backend, &light->environment); 221 state->renderer, state->gfxcore, &light->environment);
224 // TODO: Handle the result in a better way. 222 // TODO: Handle the result in a better way.
225 assert(result); 223 assert(result);
226 state->environment_light = light; 224 state->environment_light = light;
@@ -329,7 +327,7 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) {
329 const Scene* scene = params->scene; 327 const Scene* scene = params->scene;
330 const SceneCamera* camera = params->camera; 328 const SceneCamera* camera = params->camera;
331 329
332 RenderBackend* render_backend = renderer->render_backend; 330 GfxCore* gfxcore = renderer->gfxcore;
333 331
334 mat4 projection, camera_rotation, view_matrix; 332 mat4 projection, camera_rotation, view_matrix;
335 if (camera) { 333 if (camera) {
@@ -344,11 +342,11 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) {
344 } 342 }
345 343
346 int width, height; 344 int width, height;
347 gfx_get_viewport(render_backend, &width, &height); 345 gfx_get_viewport(gfxcore, &width, &height);
348 const float aspect = (float)width / (float)height; 346 const float aspect = (float)width / (float)height;
349 347
350 RenderState state = { 348 RenderState state = {
351 .render_backend = render_backend, 349 .gfxcore = gfxcore,
352 .renderer = renderer, 350 .renderer = renderer,
353 .shader = shader, 351 .shader = shader,
354 .scene = scene, 352 .scene = scene,
diff --git a/gfx/src/renderer/renderer_impl.h b/gfx/src/renderer/renderer_impl.h
index 1e28eb5..fc14dcb 100644
--- a/gfx/src/renderer/renderer_impl.h
+++ b/gfx/src/renderer/renderer_impl.h
@@ -9,9 +9,9 @@ typedef struct ShaderProgram ShaderProgram;
9typedef struct Texture Texture; 9typedef struct Texture Texture;
10 10
11typedef struct Renderer { 11typedef struct Renderer {
12 RenderBackend* render_backend; 12 GfxCore* gfxcore;
13 IBL* ibl; 13 IBL* ibl;
14 Texture* brdf_integration_map; 14 Texture* brdf_integration_map;
15 struct { 15 struct {
16 ShaderProgram* debug; 16 ShaderProgram* debug;
17 ShaderProgram* normals; 17 ShaderProgram* normals;
@@ -21,7 +21,7 @@ typedef struct Renderer {
21} Renderer; 21} Renderer;
22 22
23/// Create a new renderer. 23/// Create a new renderer.
24bool renderer_make(Renderer*, RenderBackend*); 24bool renderer_make(Renderer*, GfxCore*);
25 25
26/// Destroy the renderer. 26/// Destroy the renderer.
27void renderer_destroy(Renderer*); 27void renderer_destroy(Renderer*);
diff --git a/gfx/src/scene/material.c b/gfx/src/scene/material.c
index b32d791..3248243 100644
--- a/gfx/src/scene/material.c
+++ b/gfx/src/scene/material.c
@@ -2,7 +2,7 @@
2 2
3#include "scene_memory.h" 3#include "scene_memory.h"
4 4
5#include <gfx/render_backend.h> 5#include <gfx/core.h>
6 6
7static void material_make(Material* material, const MaterialDesc* desc) { 7static void material_make(Material* material, const MaterialDesc* desc) {
8 assert(material); 8 assert(material);
diff --git a/gfx/src/scene/object.c b/gfx/src/scene/object.c
index 406c81f..e8e3ee6 100644
--- a/gfx/src/scene/object.c
+++ b/gfx/src/scene/object.c
@@ -1,6 +1,6 @@
1#include "object_impl.h" 1#include "object_impl.h"
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4 4
5#include "mesh_impl.h" 5#include "mesh_impl.h"
6#include "node_impl.h" 6#include "node_impl.h"
diff --git a/gfx/src/util/geometry.c b/gfx/src/util/geometry.c
index 84435ce..afe0109 100644
--- a/gfx/src/util/geometry.c
+++ b/gfx/src/util/geometry.c
@@ -25,20 +25,20 @@ static GeometryDesc make_quad_desc(vec2 positions[4]) {
25 return desc; 25 return desc;
26} 26}
27 27
28Geometry* gfx_make_quad_11(RenderBackend* render_backend) { 28Geometry* gfx_make_quad_11(GfxCore* gfxcore) {
29 assert(render_backend); 29 assert(gfxcore);
30 30
31 vec2 positions[4]; 31 vec2 positions[4];
32 make_quad_11_positions(positions); 32 make_quad_11_positions(positions);
33 const GeometryDesc geometry_desc = make_quad_desc(positions); 33 const GeometryDesc geometry_desc = make_quad_desc(positions);
34 return gfx_make_geometry(render_backend, &geometry_desc); 34 return gfx_make_geometry(gfxcore, &geometry_desc);
35} 35}
36 36
37Geometry* gfx_make_quad_01(RenderBackend* render_backend) { 37Geometry* gfx_make_quad_01(GfxCore* gfxcore) {
38 assert(render_backend); 38 assert(gfxcore);
39 39
40 vec2 positions[4]; 40 vec2 positions[4];
41 make_quad_01_positions(positions); 41 make_quad_01_positions(positions);
42 const GeometryDesc geometry_desc = make_quad_desc(positions); 42 const GeometryDesc geometry_desc = make_quad_desc(positions);
43 return gfx_make_geometry(render_backend, &geometry_desc); 43 return gfx_make_geometry(gfxcore, &geometry_desc);
44} 44}
diff --git a/gfx/src/util/ibl.c b/gfx/src/util/ibl.c
index 6b7465c..5a79990 100644
--- a/gfx/src/util/ibl.c
+++ b/gfx/src/util/ibl.c
@@ -1,6 +1,6 @@
1#include <gfx/util/ibl.h> 1#include <gfx/util/ibl.h>
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <gfx/util/geometry.h> 4#include <gfx/util/geometry.h>
5#include <gfx/util/shader.h> 5#include <gfx/util/shader.h>
6#include <math/mat4.h> 6#include <math/mat4.h>
@@ -36,15 +36,15 @@ static const float flips[6] = {
36 -1.0f, // Front. 36 -1.0f, // Front.
37}; 37};
38 38
39IBL* gfx_make_ibl(RenderBackend* render_backend) { 39IBL* gfx_make_ibl(GfxCore* gfxcore) {
40 assert(render_backend); 40 assert(gfxcore);
41 41
42 IBL* ibl = calloc(1, sizeof(IBL)); 42 IBL* ibl = calloc(1, sizeof(IBL));
43 if (!ibl) { 43 if (!ibl) {
44 return 0; 44 return 0;
45 } 45 }
46 46
47 if (!(ibl->quad = gfx_make_quad_11(render_backend))) { 47 if (!(ibl->quad = gfx_make_quad_11(gfxcore))) {
48 goto cleanup; 48 goto cleanup;
49 } 49 }
50 50
@@ -53,24 +53,23 @@ IBL* gfx_make_ibl(RenderBackend* render_backend) {
53 // shader is fully compiled up front anyway, since the driver will typically 53 // shader is fully compiled up front anyway, since the driver will typically
54 // defer full compilation to the first draw call. 54 // defer full compilation to the first draw call.
55 if (!(ibl->brdf_integration_map_shader = 55 if (!(ibl->brdf_integration_map_shader =
56 gfx_make_brdf_integration_map_shader(render_backend))) { 56 gfx_make_brdf_integration_map_shader(gfxcore))) {
57 goto cleanup; 57 goto cleanup;
58 } 58 }
59 59
60 if (!(ibl->irradiance_map_shader = 60 if (!(ibl->irradiance_map_shader = gfx_make_irradiance_map_shader(gfxcore))) {
61 gfx_make_irradiance_map_shader(render_backend))) {
62 goto cleanup; 61 goto cleanup;
63 } 62 }
64 63
65 if (!(ibl->prefiltered_environment_map_shader = 64 if (!(ibl->prefiltered_environment_map_shader =
66 gfx_make_prefiltered_environment_map_shader(render_backend))) { 65 gfx_make_prefiltered_environment_map_shader(gfxcore))) {
67 goto cleanup; 66 goto cleanup;
68 } 67 }
69 68
70 // Create an empty framebuffer for now. Will attach the colour buffer later 69 // Create an empty framebuffer for now. Will attach the colour buffer later
71 // as we render the faces of the cube. 70 // as we render the faces of the cube.
72 if (!(ibl->framebuffer = gfx_make_framebuffer( 71 if (!(ibl->framebuffer = gfx_make_framebuffer(
73 render_backend, 72 gfxcore,
74 &(FrameBufferDesc){ 73 &(FrameBufferDesc){
75 .colour = 74 .colour =
76 (FrameBufferAttachment){.type = FrameBufferNoAttachment}, 75 (FrameBufferAttachment){.type = FrameBufferNoAttachment},
@@ -116,42 +115,41 @@ IBL* gfx_make_ibl(RenderBackend* render_backend) {
116 return ibl; 115 return ibl;
117 116
118cleanup: 117cleanup:
119 gfx_destroy_ibl(render_backend, &ibl); 118 gfx_destroy_ibl(gfxcore, &ibl);
120 return 0; 119 return 0;
121} 120}
122 121
123void gfx_destroy_ibl(RenderBackend* render_backend, IBL** ibl) { 122void gfx_destroy_ibl(GfxCore* gfxcore, IBL** ibl) {
124 if (!ibl) { 123 if (!ibl) {
125 return; 124 return;
126 } 125 }
127 if ((*ibl)->quad) { 126 if ((*ibl)->quad) {
128 gfx_destroy_geometry(render_backend, &(*ibl)->quad); 127 gfx_destroy_geometry(gfxcore, &(*ibl)->quad);
129 } 128 }
130 if ((*ibl)->brdf_integration_map_shader) { 129 if ((*ibl)->brdf_integration_map_shader) {
131 gfx_destroy_shader_program( 130 gfx_destroy_shader_program(gfxcore, &(*ibl)->brdf_integration_map_shader);
132 render_backend, &(*ibl)->brdf_integration_map_shader);
133 } 131 }
134 if ((*ibl)->irradiance_map_shader) { 132 if ((*ibl)->irradiance_map_shader) {
135 gfx_destroy_shader_program(render_backend, &(*ibl)->irradiance_map_shader); 133 gfx_destroy_shader_program(gfxcore, &(*ibl)->irradiance_map_shader);
136 } 134 }
137 if ((*ibl)->prefiltered_environment_map_shader) { 135 if ((*ibl)->prefiltered_environment_map_shader) {
138 gfx_destroy_shader_program( 136 gfx_destroy_shader_program(
139 render_backend, &(*ibl)->prefiltered_environment_map_shader); 137 gfxcore, &(*ibl)->prefiltered_environment_map_shader);
140 } 138 }
141 if ((*ibl)->brdf_integration_map) { 139 if ((*ibl)->brdf_integration_map) {
142 gfx_destroy_texture(render_backend, &(*ibl)->brdf_integration_map); 140 gfx_destroy_texture(gfxcore, &(*ibl)->brdf_integration_map);
143 } 141 }
144 if ((*ibl)->framebuffer) { 142 if ((*ibl)->framebuffer) {
145 gfx_destroy_framebuffer(render_backend, &(*ibl)->framebuffer); 143 gfx_destroy_framebuffer(gfxcore, &(*ibl)->framebuffer);
146 } 144 }
147 free(*ibl); 145 free(*ibl);
148 *ibl = 0; 146 *ibl = 0;
149} 147}
150 148
151Texture* gfx_make_brdf_integration_map( 149Texture* gfx_make_brdf_integration_map(
152 IBL* ibl, RenderBackend* render_backend, int width, int height) { 150 IBL* ibl, GfxCore* gfxcore, int width, int height) {
153 assert(ibl); 151 assert(ibl);
154 assert(render_backend); 152 assert(gfxcore);
155 153
156 if (ibl->brdf_integration_map) { 154 if (ibl->brdf_integration_map) {
157 return ibl->brdf_integration_map; 155 return ibl->brdf_integration_map;
@@ -160,15 +158,15 @@ Texture* gfx_make_brdf_integration_map(
160 bool success = false; 158 bool success = false;
161 159
162 if (!(ibl->brdf_integration_map = gfx_make_texture( 160 if (!(ibl->brdf_integration_map = gfx_make_texture(
163 render_backend, &(TextureDesc){ 161 gfxcore, &(TextureDesc){
164 .width = width, 162 .width = width,
165 .height = height, 163 .height = height,
166 .depth = 1, 164 .depth = 1,
167 .dimension = Texture2D, 165 .dimension = Texture2D,
168 .format = TextureRG16F, 166 .format = TextureRG16F,
169 .filtering = LinearFiltering, 167 .filtering = LinearFiltering,
170 .wrap = ClampToEdge, 168 .wrap = ClampToEdge,
171 .mipmaps = false}))) { 169 .mipmaps = false}))) {
172 goto cleanup; 170 goto cleanup;
173 } 171 }
174 172
@@ -190,7 +188,7 @@ cleanup:
190 gfx_deactivate_shader_program(ibl->brdf_integration_map_shader); 188 gfx_deactivate_shader_program(ibl->brdf_integration_map_shader);
191 gfx_deactivate_framebuffer(ibl->framebuffer); 189 gfx_deactivate_framebuffer(ibl->framebuffer);
192 if (!success && ibl->brdf_integration_map) { 190 if (!success && ibl->brdf_integration_map) {
193 gfx_destroy_texture(render_backend, &ibl->brdf_integration_map); 191 gfx_destroy_texture(gfxcore, &ibl->brdf_integration_map);
194 return 0; 192 return 0;
195 } else { 193 } else {
196 return ibl->brdf_integration_map; 194 return ibl->brdf_integration_map;
@@ -198,10 +196,10 @@ cleanup:
198} 196}
199 197
200Texture* gfx_make_irradiance_map( 198Texture* gfx_make_irradiance_map(
201 IBL* ibl, RenderBackend* render_backend, const Texture* environment_map, 199 IBL* ibl, GfxCore* gfxcore, const Texture* environment_map, int width,
202 int width, int height) { 200 int height) {
203 assert(ibl); 201 assert(ibl);
204 assert(render_backend); 202 assert(gfxcore);
205 assert(environment_map); 203 assert(environment_map);
206 204
207 bool success = false; 205 bool success = false;
@@ -215,14 +213,14 @@ Texture* gfx_make_irradiance_map(
215 // Make sure to use a float colour format to avoid [0,1] clamping when the 213 // Make sure to use a float colour format to avoid [0,1] clamping when the
216 // irradiance values are computed! 214 // irradiance values are computed!
217 if (!(irradiance_map = gfx_make_texture( 215 if (!(irradiance_map = gfx_make_texture(
218 render_backend, &(TextureDesc){ 216 gfxcore, &(TextureDesc){
219 .width = width, 217 .width = width,
220 .height = height, 218 .height = height,
221 .depth = 1, 219 .depth = 1,
222 .dimension = TextureCubeMap, 220 .dimension = TextureCubeMap,
223 .format = TextureR11G11B10F, 221 .format = TextureR11G11B10F,
224 .filtering = LinearFiltering, 222 .filtering = LinearFiltering,
225 .mipmaps = false}))) { 223 .mipmaps = false}))) {
226 goto cleanup; 224 goto cleanup;
227 } 225 }
228 226
@@ -251,7 +249,7 @@ cleanup:
251 gfx_deactivate_shader_program(ibl->irradiance_map_shader); 249 gfx_deactivate_shader_program(ibl->irradiance_map_shader);
252 gfx_deactivate_framebuffer(ibl->framebuffer); 250 gfx_deactivate_framebuffer(ibl->framebuffer);
253 if (!success && irradiance_map) { 251 if (!success && irradiance_map) {
254 gfx_destroy_texture(render_backend, &irradiance_map); 252 gfx_destroy_texture(gfxcore, &irradiance_map);
255 return 0; 253 return 0;
256 } else { 254 } else {
257 return irradiance_map; 255 return irradiance_map;
@@ -259,10 +257,10 @@ cleanup:
259} 257}
260 258
261Texture* gfx_make_prefiltered_environment_map( 259Texture* gfx_make_prefiltered_environment_map(
262 IBL* ibl, RenderBackend* render_backend, const Texture* environment_map, 260 IBL* ibl, GfxCore* gfxcore, const Texture* environment_map, int width,
263 int width, int height, int* max_mip_level) { 261 int height, int* max_mip_level) {
264 assert(ibl); 262 assert(ibl);
265 assert(render_backend); 263 assert(gfxcore);
266 assert(environment_map); 264 assert(environment_map);
267 assert(max_mip_level); 265 assert(max_mip_level);
268 266
@@ -271,14 +269,14 @@ Texture* gfx_make_prefiltered_environment_map(
271 Texture* prefiltered_env_map = 0; 269 Texture* prefiltered_env_map = 0;
272 270
273 if (!(prefiltered_env_map = gfx_make_texture( 271 if (!(prefiltered_env_map = gfx_make_texture(
274 render_backend, &(TextureDesc){ 272 gfxcore, &(TextureDesc){
275 .width = width, 273 .width = width,
276 .height = height, 274 .height = height,
277 .depth = 1, 275 .depth = 1,
278 .dimension = TextureCubeMap, 276 .dimension = TextureCubeMap,
279 .format = TextureR11G11B10F, 277 .format = TextureR11G11B10F,
280 .filtering = LinearFiltering, 278 .filtering = LinearFiltering,
281 .mipmaps = true}))) { 279 .mipmaps = true}))) {
282 goto cleanup; 280 goto cleanup;
283 } 281 }
284 282
@@ -322,7 +320,7 @@ cleanup:
322 gfx_deactivate_shader_program(ibl->prefiltered_environment_map_shader); 320 gfx_deactivate_shader_program(ibl->prefiltered_environment_map_shader);
323 gfx_deactivate_framebuffer(ibl->framebuffer); 321 gfx_deactivate_framebuffer(ibl->framebuffer);
324 if (!success && prefiltered_env_map) { 322 if (!success && prefiltered_env_map) {
325 gfx_destroy_texture(render_backend, &prefiltered_env_map); 323 gfx_destroy_texture(gfxcore, &prefiltered_env_map);
326 return 0; 324 return 0;
327 } else { 325 } else {
328 return prefiltered_env_map; 326 return prefiltered_env_map;
diff --git a/gfx/src/util/shader.c b/gfx/src/util/shader.c
index ed81f79..f5c22cc 100644
--- a/gfx/src/util/shader.c
+++ b/gfx/src/util/shader.c
@@ -1,6 +1,6 @@
1#include <gfx/util/shader.h> 1#include <gfx/util/shader.h>
2 2
3#include <gfx/render_backend.h> 3#include <gfx/core.h>
4#include <shaders/brdf_integration_map.frag.h> 4#include <shaders/brdf_integration_map.frag.h>
5#include <shaders/cook_torrance.frag.h> 5#include <shaders/cook_torrance.frag.h>
6#include <shaders/cook_torrance.vert.h> 6#include <shaders/cook_torrance.vert.h>
@@ -27,10 +27,9 @@
27#include <string.h> 27#include <string.h>
28 28
29static ShaderProgram* make_shader_program( 29static ShaderProgram* make_shader_program(
30 RenderBackend* render_backend, const char* vert_source, 30 GfxCore* gfxcore, const char* vert_source, const char* frag_source,
31 const char* frag_source, const ShaderCompilerDefine* defines, 31 const ShaderCompilerDefine* defines, size_t num_defines) {
32 size_t num_defines) { 32 assert(gfxcore);
33 assert(render_backend);
34 assert(vert_source); 33 assert(vert_source);
35 assert(frag_source); 34 assert(frag_source);
36 35
@@ -49,19 +48,18 @@ static ShaderProgram* make_shader_program(
49 fragment_shader_desc.defines, defines, 48 fragment_shader_desc.defines, defines,
50 num_defines * sizeof(ShaderCompilerDefine)); 49 num_defines * sizeof(ShaderCompilerDefine));
51 } 50 }
52 vert = gfx_make_shader(render_backend, &vertex_shader_desc); 51 vert = gfx_make_shader(gfxcore, &vertex_shader_desc);
53 if (!vert) { 52 if (!vert) {
54 goto cleanup; 53 goto cleanup;
55 } 54 }
56 frag = gfx_make_shader(render_backend, &fragment_shader_desc); 55 frag = gfx_make_shader(gfxcore, &fragment_shader_desc);
57 if (!frag) { 56 if (!frag) {
58 goto cleanup; 57 goto cleanup;
59 } 58 }
60 59
61 ShaderProgramDesc shader_program_desc = { 60 ShaderProgramDesc shader_program_desc = {
62 .vertex_shader = vert, .fragment_shader = frag}; 61 .vertex_shader = vert, .fragment_shader = frag};
63 ShaderProgram* prog = 62 ShaderProgram* prog = gfx_make_shader_program(gfxcore, &shader_program_desc);
64 gfx_make_shader_program(render_backend, &shader_program_desc);
65 if (!prog) { 63 if (!prog) {
66 goto cleanup; 64 goto cleanup;
67 } 65 }
@@ -69,76 +67,70 @@ static ShaderProgram* make_shader_program(
69 67
70cleanup: 68cleanup:
71 if (vert) { 69 if (vert) {
72 gfx_destroy_shader(render_backend, &vert); 70 gfx_destroy_shader(gfxcore, &vert);
73 } 71 }
74 if (frag) { 72 if (frag) {
75 gfx_destroy_shader(render_backend, &frag); 73 gfx_destroy_shader(gfxcore, &frag);
76 } 74 }
77 return 0; 75 return 0;
78} 76}
79 77
80ShaderProgram* gfx_make_brdf_integration_map_shader( 78ShaderProgram* gfx_make_brdf_integration_map_shader(GfxCore* gfxcore) {
81 RenderBackend* render_backend) {
82 return make_shader_program( 79 return make_shader_program(
83 render_backend, quad_vert, brdf_integration_map_frag, 0, 0); 80 gfxcore, quad_vert, brdf_integration_map_frag, 0, 0);
84} 81}
85 82
86ShaderProgram* gfx_make_cook_torrance_shader(RenderBackend* render_backend) { 83ShaderProgram* gfx_make_cook_torrance_shader(GfxCore* gfxcore) {
87 return make_shader_program( 84 return make_shader_program(
88 render_backend, cook_torrance_vert, cook_torrance_frag, 0, 0); 85 gfxcore, cook_torrance_vert, cook_torrance_frag, 0, 0);
89} 86}
90 87
91ShaderProgram* gfx_make_cook_torrance_shader_perm( 88ShaderProgram* gfx_make_cook_torrance_shader_perm(
92 RenderBackend* render_backend, const ShaderCompilerDefine* defines, 89 GfxCore* gfxcore, const ShaderCompilerDefine* defines, size_t num_defines) {
93 size_t num_defines) {
94 return make_shader_program( 90 return make_shader_program(
95 render_backend, cook_torrance_vert, cook_torrance_frag, defines, 91 gfxcore, cook_torrance_vert, cook_torrance_frag, defines, num_defines);
96 num_defines);
97} 92}
98 93
99ShaderProgram* gfx_make_immediate_mode_shader(RenderBackend* render_backend) { 94ShaderProgram* gfx_make_immediate_mode_shader(GfxCore* gfxcore) {
100 return make_shader_program( 95 return make_shader_program(
101 render_backend, immediate_mode_vert, immediate_mode_frag, 0, 0); 96 gfxcore, immediate_mode_vert, immediate_mode_frag, 0, 0);
102} 97}
103 98
104ShaderProgram* gfx_make_irradiance_map_shader(RenderBackend* render_backend) { 99ShaderProgram* gfx_make_irradiance_map_shader(GfxCore* gfxcore) {
105 return make_shader_program( 100 return make_shader_program(
106 render_backend, cubemap_filtering_vert, irradiance_map_frag, 0, 0); 101 gfxcore, cubemap_filtering_vert, irradiance_map_frag, 0, 0);
107} 102}
108 103
109ShaderProgram* gfx_make_prefiltered_environment_map_shader( 104ShaderProgram* gfx_make_prefiltered_environment_map_shader(GfxCore* gfxcore) {
110 RenderBackend* render_backend) {
111 return make_shader_program( 105 return make_shader_program(
112 render_backend, cubemap_filtering_vert, prefiltered_environment_map_frag, 106 gfxcore, cubemap_filtering_vert, prefiltered_environment_map_frag, 0, 0);
113 0, 0);
114} 107}
115 108
116ShaderProgram* gfx_make_debug3d_shader(RenderBackend* render_backend) { 109ShaderProgram* gfx_make_debug3d_shader(GfxCore* gfxcore) {
117 return make_shader_program(render_backend, debug3d_vert, debug3d_frag, 0, 0); 110 return make_shader_program(gfxcore, debug3d_vert, debug3d_frag, 0, 0);
118} 111}
119 112
120ShaderProgram* gfx_make_skyquad_shader(RenderBackend* render_backend) { 113ShaderProgram* gfx_make_skyquad_shader(GfxCore* gfxcore) {
121 return make_shader_program(render_backend, skyquad_vert, skyquad_frag, 0, 0); 114 return make_shader_program(gfxcore, skyquad_vert, skyquad_frag, 0, 0);
122} 115}
123 116
124ShaderProgram* gfx_make_view_normal_mapped_normals_shader( 117ShaderProgram* gfx_make_view_normal_mapped_normals_shader(GfxCore* gfxcore) {
125 RenderBackend* render_backend) {
126 return make_shader_program( 118 return make_shader_program(
127 render_backend, view_normal_mapped_normals_vert, 119 gfxcore, view_normal_mapped_normals_vert, view_normal_mapped_normals_frag,
128 view_normal_mapped_normals_frag, 0, 0); 120 0, 0);
129} 121}
130 122
131ShaderProgram* gfx_make_view_normals_shader(RenderBackend* render_backend) { 123ShaderProgram* gfx_make_view_normals_shader(GfxCore* gfxcore) {
132 return make_shader_program( 124 return make_shader_program(
133 render_backend, view_normals_vert, view_normals_frag, 0, 0); 125 gfxcore, view_normals_vert, view_normals_frag, 0, 0);
134} 126}
135 127
136ShaderProgram* gfx_make_view_tangents_shader(RenderBackend* render_backend) { 128ShaderProgram* gfx_make_view_tangents_shader(GfxCore* gfxcore) {
137 return make_shader_program( 129 return make_shader_program(
138 render_backend, view_tangents_vert, view_tangents_frag, 0, 0); 130 gfxcore, view_tangents_vert, view_tangents_frag, 0, 0);
139} 131}
140 132
141ShaderProgram* gfx_make_view_texture_shader(RenderBackend* render_backend) { 133ShaderProgram* gfx_make_view_texture_shader(GfxCore* gfxcore) {
142 return make_shader_program( 134 return make_shader_program(
143 render_backend, view_texture_vert, view_texture_frag, 0, 0); 135 gfxcore, view_texture_vert, view_texture_frag, 0, 0);
144} 136}
diff --git a/gfx/src/util/skyquad.c b/gfx/src/util/skyquad.c
index 5027705..ff8f73f 100644
--- a/gfx/src/util/skyquad.c
+++ b/gfx/src/util/skyquad.c
@@ -1,7 +1,7 @@
1#include <gfx/util/skyquad.h> 1#include <gfx/util/skyquad.h>
2 2
3#include <gfx/core.h>
3#include <gfx/gfx.h> 4#include <gfx/gfx.h>
4#include <gfx/render_backend.h>
5#include <gfx/scene/light.h> 5#include <gfx/scene/light.h>
6#include <gfx/scene/material.h> 6#include <gfx/scene/material.h>
7#include <gfx/scene/mesh.h> 7#include <gfx/scene/mesh.h>
@@ -15,9 +15,8 @@
15 15
16#include <assert.h> 16#include <assert.h>
17 17
18SceneObject* gfx_make_skyquad( 18SceneObject* gfx_make_skyquad(GfxCore* gfxcore, const Texture* texture) {
19 RenderBackend* render_backend, const Texture* texture) { 19 assert(gfxcore);
20 assert(render_backend);
21 assert(texture); 20 assert(texture);
22 21
23 ShaderProgram* shader = 0; 22 ShaderProgram* shader = 0;
@@ -26,12 +25,12 @@ SceneObject* gfx_make_skyquad(
26 Mesh* mesh = 0; 25 Mesh* mesh = 0;
27 SceneObject* object = 0; 26 SceneObject* object = 0;
28 27
29 shader = gfx_make_skyquad_shader(render_backend); 28 shader = gfx_make_skyquad_shader(gfxcore);
30 if (!shader) { 29 if (!shader) {
31 goto cleanup; 30 goto cleanup;
32 } 31 }
33 32
34 geometry = gfx_make_quad_11(render_backend); 33 geometry = gfx_make_quad_11(gfxcore);
35 if (!geometry) { 34 if (!geometry) {
36 goto cleanup; 35 goto cleanup;
37 } 36 }
@@ -65,10 +64,10 @@ SceneObject* gfx_make_skyquad(
65 64
66cleanup: 65cleanup:
67 if (shader) { 66 if (shader) {
68 gfx_destroy_shader_program(render_backend, &shader); 67 gfx_destroy_shader_program(gfxcore, &shader);
69 } 68 }
70 if (geometry) { 69 if (geometry) {
71 gfx_destroy_geometry(render_backend, &geometry); 70 gfx_destroy_geometry(gfxcore, &geometry);
72 } 71 }
73 if (material) { 72 if (material) {
74 gfx_destroy_material(&material); 73 gfx_destroy_material(&material);
@@ -116,9 +115,8 @@ cleanup:
116} 115}
117 116
118SceneNode* gfx_setup_skyquad( 117SceneNode* gfx_setup_skyquad(
119 RenderBackend* render_backend, SceneNode* root, 118 GfxCore* gfxcore, SceneNode* root, const Texture* environment_map) {
120 const Texture* environment_map) { 119 assert(gfxcore);
121 assert(render_backend);
122 assert(root); 120 assert(root);
123 assert(environment_map); 121 assert(environment_map);
124 122
@@ -127,7 +125,7 @@ SceneNode* gfx_setup_skyquad(
127 SceneNode* light_node = 0; 125 SceneNode* light_node = 0;
128 126
129 // Create the skyquad object. 127 // Create the skyquad object.
130 skyquad_object = gfx_make_skyquad(render_backend, environment_map); 128 skyquad_object = gfx_make_skyquad(gfxcore, environment_map);
131 if (!skyquad_object) { 129 if (!skyquad_object) {
132 goto cleanup; 130 goto cleanup;
133 } 131 }