diff options
-rw-r--r-- | gfx/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gfx/src/asset/asset_cache.c | 47 | ||||
-rw-r--r-- | gfx/src/gfx_assert.h | 5 | ||||
-rw-r--r-- | gfx/src/render/buffer.c | 8 | ||||
-rw-r--r-- | gfx/src/render/framebuffer.c | 4 | ||||
-rw-r--r-- | gfx/src/render/geometry.c | 9 | ||||
-rw-r--r-- | gfx/src/render/render_backend.c | 107 | ||||
-rw-r--r-- | gfx/src/render/renderbuffer.c | 1 | ||||
-rw-r--r-- | gfx/src/render/shader.c | 8 | ||||
-rw-r--r-- | gfx/src/render/shader_program.c | 21 | ||||
-rw-r--r-- | gfx/src/render/texture.c | 19 | ||||
-rw-r--r-- | gfx/src/scene/animation.c | 72 | ||||
-rw-r--r-- | gfx/src/scene/camera.c | 25 | ||||
-rw-r--r-- | gfx/src/scene/light.c | 13 | ||||
-rw-r--r-- | gfx/src/scene/material.c | 3 | ||||
-rw-r--r-- | gfx/src/scene/mesh.c | 3 | ||||
-rw-r--r-- | gfx/src/scene/node.c | 73 | ||||
-rw-r--r-- | gfx/src/scene/object.c | 16 | ||||
-rw-r--r-- | gfx/src/scene/scene.c | 13 |
19 files changed, 204 insertions, 244 deletions
diff --git a/gfx/CMakeLists.txt b/gfx/CMakeLists.txt index e5c965e..2b295d5 100644 --- a/gfx/CMakeLists.txt +++ b/gfx/CMakeLists.txt | |||
@@ -74,6 +74,7 @@ target_link_libraries(gfx PUBLIC | |||
74 | math) | 74 | math) |
75 | 75 | ||
76 | target_link_libraries(gfx PRIVATE | 76 | target_link_libraries(gfx PRIVATE |
77 | cassert | ||
77 | cgltf | 78 | cgltf |
78 | cgltf-tangents | 79 | cgltf-tangents |
79 | error | 80 | error |
diff --git a/gfx/src/asset/asset_cache.c b/gfx/src/asset/asset_cache.c index 0c6a8dc..2fa57ad 100644 --- a/gfx/src/asset/asset_cache.c +++ b/gfx/src/asset/asset_cache.c | |||
@@ -4,13 +4,11 @@ | |||
4 | #include <gfx/gfx.h> | 4 | #include <gfx/gfx.h> |
5 | #include <gfx/util/scene.h> | 5 | #include <gfx/util/scene.h> |
6 | #include <gfx/util/texture.h> | 6 | #include <gfx/util/texture.h> |
7 | #include <gfx_assert.h> | ||
7 | 8 | ||
8 | #include <cstring.h> | 9 | #include <cstring.h> |
9 | #include <log/log.h> | 10 | #include <log/log.h> |
10 | 11 | ||
11 | #include <assert.h> | ||
12 | #include <stddef.h> | ||
13 | |||
14 | static Hash calc_scene_hash(const LoadSceneCmd* cmd) { | 12 | static Hash calc_scene_hash(const LoadSceneCmd* cmd) { |
15 | assert(cmd); | 13 | assert(cmd); |
16 | switch (cmd->origin) { | 14 | switch (cmd->origin) { |
@@ -19,7 +17,7 @@ static Hash calc_scene_hash(const LoadSceneCmd* cmd) { | |||
19 | case AssetFromMemory: | 17 | case AssetFromMemory: |
20 | return (Hash)cmd->data; | 18 | return (Hash)cmd->data; |
21 | } | 19 | } |
22 | assert(false); | 20 | FAIL("Unhandled scene asset origin"); |
23 | return 0; | 21 | return 0; |
24 | } | 22 | } |
25 | 23 | ||
@@ -59,7 +57,7 @@ static Hash calc_texture_hash(const LoadTextureCmd* cmd) { | |||
59 | } | 57 | } |
60 | break; | 58 | break; |
61 | } | 59 | } |
62 | assert(false); | 60 | FAIL("Unhandled texture asset origin"); |
63 | return 0; | 61 | return 0; |
64 | } | 62 | } |
65 | 63 | ||
@@ -73,25 +71,16 @@ static Asset* lookup_cache(AssetCache* cache, Hash hash) { | |||
73 | return 0; | 71 | return 0; |
74 | } | 72 | } |
75 | 73 | ||
76 | // TODO: questionable function. Make mempool_alloc() fail when out of memory. | ||
77 | static void insert_into_cache(AssetCache* cache, const Asset* asset) { | ||
78 | assert(cache); | ||
79 | assert(asset); | ||
80 | Asset* poolAsset = mempool_alloc(&cache->assets); | ||
81 | assert(asset); | ||
82 | *poolAsset = *asset; | ||
83 | } | ||
84 | |||
85 | static void log_scene_cache_hit(const LoadSceneCmd* cmd, Hash hash) { | 74 | static void log_scene_cache_hit(const LoadSceneCmd* cmd, Hash hash) { |
86 | assert(cmd); | 75 | assert(cmd); |
87 | switch (cmd->origin) { | 76 | switch (cmd->origin) { |
88 | case AssetFromFile: | 77 | case AssetFromFile: |
89 | LOGI( | 78 | LOGD( |
90 | "Found asset [%s] in cache with hash [%lu]", | 79 | "Found asset [%s] in cache with hash [%lu]", |
91 | mstring_cstr(&cmd->filepath), hash); | 80 | mstring_cstr(&cmd->filepath), hash); |
92 | break; | 81 | break; |
93 | case AssetFromMemory: | 82 | case AssetFromMemory: |
94 | LOGI("Found asset [%p] in cache with hash [%lu]", cmd->data, hash); | 83 | LOGD("Found asset [%p] in cache with hash [%lu]", cmd->data, hash); |
95 | break; | 84 | break; |
96 | } | 85 | } |
97 | } | 86 | } |
@@ -100,10 +89,10 @@ static void log_scene_loaded(const LoadSceneCmd* cmd) { | |||
100 | assert(cmd); | 89 | assert(cmd); |
101 | switch (cmd->origin) { | 90 | switch (cmd->origin) { |
102 | case AssetFromFile: | 91 | case AssetFromFile: |
103 | LOGI("Loaded asset from file: [%s]", mstring_cstr(&cmd->filepath)); | 92 | LOGD("Loaded asset from file: [%s]", mstring_cstr(&cmd->filepath)); |
104 | break; | 93 | break; |
105 | case AssetFromMemory: | 94 | case AssetFromMemory: |
106 | LOGI("Loaded asset from memory: [%p]", cmd->data); | 95 | LOGD("Loaded asset from memory: [%p]", cmd->data); |
107 | break; | 96 | break; |
108 | } | 97 | } |
109 | } | 98 | } |
@@ -143,12 +132,11 @@ SceneNode* gfx_load_scene( | |||
143 | // Load it, insert it into the cache, and return it. | 132 | // Load it, insert it into the cache, and return it. |
144 | SceneNode* node = gfx_scene_load(gfx, root_node, cmd); | 133 | SceneNode* node = gfx_scene_load(gfx, root_node, cmd); |
145 | if (node) { | 134 | if (node) { |
146 | insert_into_cache( | 135 | *(Asset*)mempool_alloc(&cache->assets) = (Asset){ |
147 | cache, &(Asset){ | 136 | .type = SceneAsset, |
148 | .type = SceneAsset, | 137 | .hash = hash, |
149 | .hash = hash, | 138 | .data = node, |
150 | .data = node, | 139 | }; |
151 | }); | ||
152 | log_scene_loaded(cmd); | 140 | log_scene_loaded(cmd); |
153 | } | 141 | } |
154 | return node; | 142 | return node; |
@@ -172,12 +160,11 @@ Texture* gfx_load_texture(Gfx* gfx, const LoadTextureCmd* cmd) { | |||
172 | RenderBackend* render_backend = gfx_get_render_backend(gfx); | 160 | RenderBackend* render_backend = gfx_get_render_backend(gfx); |
173 | Texture* texture = gfx_texture_load(render_backend, cmd); | 161 | Texture* texture = gfx_texture_load(render_backend, cmd); |
174 | if (texture) { | 162 | if (texture) { |
175 | insert_into_cache( | 163 | *(Asset*)mempool_alloc(&cache->assets) = (Asset){ |
176 | cache, &(Asset){ | 164 | .type = TextureAsset, |
177 | .type = TextureAsset, | 165 | .hash = hash, |
178 | .hash = hash, | 166 | .data = texture, |
179 | .data = texture, | 167 | }; |
180 | }); | ||
181 | } | 168 | } |
182 | return texture; | 169 | return texture; |
183 | } | 170 | } |
diff --git a/gfx/src/gfx_assert.h b/gfx/src/gfx_assert.h new file mode 100644 index 0000000..f4b3aa5 --- /dev/null +++ b/gfx/src/gfx_assert.h | |||
@@ -0,0 +1,5 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <log/log.h> | ||
4 | |||
5 | #include <cassert.h> // Include after log to use log's LOGE(). | ||
diff --git a/gfx/src/render/buffer.c b/gfx/src/render/buffer.c index 55c68cc..28877bb 100644 --- a/gfx/src/render/buffer.c +++ b/gfx/src/render/buffer.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "buffer.h" | 1 | #include "buffer.h" |
2 | 2 | ||
3 | #include <gfx/render_backend.h> | 3 | #include <gfx/render_backend.h> |
4 | #include <gfx_assert.h> | ||
4 | 5 | ||
5 | #include <math/vec2.h> | 6 | #include <math/vec2.h> |
6 | #include <math/vec3.h> | 7 | #include <math/vec3.h> |
@@ -18,7 +19,7 @@ static GLenum get_buffer_usage(BufferUsage usage) { | |||
18 | case BufferDynamic: | 19 | case BufferDynamic: |
19 | return GL_DYNAMIC_DRAW; | 20 | return GL_DYNAMIC_DRAW; |
20 | } | 21 | } |
21 | assert(false); | 22 | FAIL("Unhandled buffer usage"); |
22 | return GL_STATIC_DRAW; | 23 | return GL_STATIC_DRAW; |
23 | } | 24 | } |
24 | 25 | ||
@@ -39,21 +40,24 @@ size_t gfx_get_buffer_type_size_bytes(BufferType type) { | |||
39 | case BufferU16: | 40 | case BufferU16: |
40 | return sizeof(uint16_t); | 41 | return sizeof(uint16_t); |
41 | } | 42 | } |
42 | assert(false); | 43 | FAIL("Unhandled buffer type"); |
43 | return 0; | 44 | return 0; |
44 | } | 45 | } |
45 | 46 | ||
46 | bool gfx_init_buffer(Buffer* buffer, const BufferDesc* desc) { | 47 | bool gfx_init_buffer(Buffer* buffer, const BufferDesc* desc) { |
47 | assert(buffer); | 48 | assert(buffer); |
49 | |||
48 | buffer->type = desc->type; | 50 | buffer->type = desc->type; |
49 | buffer->usage = desc->usage; | 51 | buffer->usage = desc->usage; |
50 | buffer->size_bytes = get_buffer_size_bytes(desc->type, &desc->data); | 52 | buffer->size_bytes = get_buffer_size_bytes(desc->type, &desc->data); |
51 | const GLenum usage = get_buffer_usage(desc->usage); | 53 | const GLenum usage = get_buffer_usage(desc->usage); |
54 | |||
52 | glGenBuffers(1, &buffer->vbo); | 55 | glGenBuffers(1, &buffer->vbo); |
53 | glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo); | 56 | glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo); |
54 | glBufferData(GL_ARRAY_BUFFER, buffer->size_bytes, desc->data.data, usage); | 57 | glBufferData(GL_ARRAY_BUFFER, buffer->size_bytes, desc->data.data, usage); |
55 | glBindBuffer(GL_ARRAY_BUFFER, 0); | 58 | glBindBuffer(GL_ARRAY_BUFFER, 0); |
56 | ASSERT_GL; | 59 | ASSERT_GL; |
60 | |||
57 | return true; | 61 | return true; |
58 | } | 62 | } |
59 | 63 | ||
diff --git a/gfx/src/render/framebuffer.c b/gfx/src/render/framebuffer.c index 84ade4a..2ea2165 100644 --- a/gfx/src/render/framebuffer.c +++ b/gfx/src/render/framebuffer.c | |||
@@ -3,9 +3,9 @@ | |||
3 | #include "renderbuffer.h" | 3 | #include "renderbuffer.h" |
4 | #include "texture.h" | 4 | #include "texture.h" |
5 | 5 | ||
6 | #include <error.h> | 6 | #include <gfx_assert.h> |
7 | 7 | ||
8 | #include <assert.h> | 8 | #include <error.h> |
9 | 9 | ||
10 | static void framebuffer_attach_colour( | 10 | static void framebuffer_attach_colour( |
11 | FrameBuffer* framebuffer, const FrameBufferAttachment* attachment) { | 11 | FrameBuffer* framebuffer, const FrameBufferAttachment* attachment) { |
diff --git a/gfx/src/render/geometry.c b/gfx/src/render/geometry.c index 44bfd04..8974387 100644 --- a/gfx/src/render/geometry.c +++ b/gfx/src/render/geometry.c | |||
@@ -3,6 +3,8 @@ | |||
3 | #include "buffer.h" | 3 | #include "buffer.h" |
4 | #include "constants.h" | 4 | #include "constants.h" |
5 | 5 | ||
6 | #include <gfx_assert.h> | ||
7 | |||
6 | #include <math/vec2.h> | 8 | #include <math/vec2.h> |
7 | #include <math/vec3.h> | 9 | #include <math/vec3.h> |
8 | 10 | ||
@@ -20,10 +22,9 @@ static GLenum primitive_type_to_gl(PrimitiveType type) { | |||
20 | return GL_TRIANGLE_FAN; | 22 | return GL_TRIANGLE_FAN; |
21 | case TriangleStrip: | 23 | case TriangleStrip: |
22 | return GL_TRIANGLE_STRIP; | 24 | return GL_TRIANGLE_STRIP; |
23 | default: | ||
24 | LOGE("primitive_type_to_gl(): missing case"); | ||
25 | return GL_INVALID_ENUM; | ||
26 | } | 25 | } |
26 | FAIL("primitive_type_to_gl(): missing case"); | ||
27 | return GL_INVALID_ENUM; | ||
27 | } | 28 | } |
28 | 29 | ||
29 | /// 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 |
@@ -300,7 +301,7 @@ void gfx_update_geometry(Geometry* geometry, const GeometryDesc* desc) { | |||
300 | } | 301 | } |
301 | // TODO: more | 302 | // TODO: more |
302 | else { | 303 | else { |
303 | assert(false && "TODO: gfx_update_geometry() - handle other buffer types"); | 304 | FAIL("TODO: gfx_update_geometry() - handle other buffer types"); |
304 | } | 305 | } |
305 | 306 | ||
306 | if (desc->num_verts != 0) { | 307 | if (desc->num_verts != 0) { |
diff --git a/gfx/src/render/render_backend.c b/gfx/src/render/render_backend.c index defc164..4e783f8 100644 --- a/gfx/src/render/render_backend.c +++ b/gfx/src/render/render_backend.c | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | #include "gl_util.h" | 3 | #include "gl_util.h" |
4 | 4 | ||
5 | #include <GL/gl.h> | ||
6 | // #include <log/log.h> | 5 | // #include <log/log.h> |
7 | 6 | ||
8 | #include <assert.h> | 7 | #include <assert.h> |
@@ -138,10 +137,8 @@ void gfx_set_polygon_offset( | |||
138 | Buffer* gfx_make_buffer(RenderBackend* render_backend, const BufferDesc* desc) { | 137 | Buffer* gfx_make_buffer(RenderBackend* render_backend, const BufferDesc* desc) { |
139 | assert(render_backend); | 138 | assert(render_backend); |
140 | assert(desc); | 139 | assert(desc); |
140 | |||
141 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 141 | Buffer* buffer = mempool_alloc(&render_backend->buffers); |
142 | if (!buffer) { | ||
143 | return 0; | ||
144 | } | ||
145 | if (!gfx_init_buffer(buffer, desc)) { | 142 | if (!gfx_init_buffer(buffer, desc)) { |
146 | mempool_free(&render_backend->buffers, &buffer); | 143 | mempool_free(&render_backend->buffers, &buffer); |
147 | return 0; | 144 | return 0; |
@@ -152,8 +149,10 @@ Buffer* gfx_make_buffer(RenderBackend* render_backend, const BufferDesc* desc) { | |||
152 | void gfx_destroy_buffer(RenderBackend* render_backend, Buffer** buffer) { | 149 | void gfx_destroy_buffer(RenderBackend* render_backend, Buffer** buffer) { |
153 | assert(render_backend); | 150 | assert(render_backend); |
154 | assert(buffer); | 151 | assert(buffer); |
155 | gfx_del_buffer(*buffer); | 152 | if (*buffer) { |
156 | mempool_free(&render_backend->buffers, buffer); | 153 | gfx_del_buffer(*buffer); |
154 | mempool_free(&render_backend->buffers, buffer); | ||
155 | } | ||
157 | } | 156 | } |
158 | 157 | ||
159 | // ----------------------------------------------------------------------------- | 158 | // ----------------------------------------------------------------------------- |
@@ -164,10 +163,8 @@ Geometry* gfx_make_geometry( | |||
164 | RenderBackend* render_backend, const GeometryDesc* desc) { | 163 | RenderBackend* render_backend, const GeometryDesc* desc) { |
165 | assert(render_backend); | 164 | assert(render_backend); |
166 | assert(desc); | 165 | assert(desc); |
166 | |||
167 | Geometry* geometry = mempool_alloc(&render_backend->geometries); | 167 | Geometry* geometry = mempool_alloc(&render_backend->geometries); |
168 | if (!geometry) { | ||
169 | return 0; | ||
170 | } | ||
171 | if (!gfx_init_geometry(geometry, render_backend, desc)) { | 168 | if (!gfx_init_geometry(geometry, render_backend, desc)) { |
172 | mempool_free(&render_backend->geometries, &geometry); | 169 | mempool_free(&render_backend->geometries, &geometry); |
173 | return 0; | 170 | return 0; |
@@ -178,8 +175,11 @@ Geometry* gfx_make_geometry( | |||
178 | void gfx_destroy_geometry(RenderBackend* render_backend, Geometry** geometry) { | 175 | void gfx_destroy_geometry(RenderBackend* render_backend, Geometry** geometry) { |
179 | assert(render_backend); | 176 | assert(render_backend); |
180 | assert(geometry); | 177 | assert(geometry); |
181 | gfx_del_geometry(*geometry); | 178 | |
182 | mempool_free(&render_backend->geometries, geometry); | 179 | if (*geometry) { |
180 | gfx_del_geometry(*geometry); | ||
181 | mempool_free(&render_backend->geometries, geometry); | ||
182 | } | ||
183 | } | 183 | } |
184 | 184 | ||
185 | // ----------------------------------------------------------------------------- | 185 | // ----------------------------------------------------------------------------- |
@@ -190,10 +190,8 @@ Texture* gfx_make_texture( | |||
190 | RenderBackend* render_backend, const TextureDesc* desc) { | 190 | RenderBackend* render_backend, const TextureDesc* desc) { |
191 | assert(render_backend); | 191 | assert(render_backend); |
192 | assert(desc); | 192 | assert(desc); |
193 | |||
193 | Texture* texture = mempool_alloc(&render_backend->textures); | 194 | Texture* texture = mempool_alloc(&render_backend->textures); |
194 | if (!texture) { | ||
195 | return 0; | ||
196 | } | ||
197 | if (!gfx_init_texture(texture, desc)) { | 195 | if (!gfx_init_texture(texture, desc)) { |
198 | mempool_free(&render_backend->textures, &texture); | 196 | mempool_free(&render_backend->textures, &texture); |
199 | return 0; | 197 | return 0; |
@@ -205,8 +203,11 @@ void gfx_destroy_texture(RenderBackend* render_backend, Texture** texture) { | |||
205 | assert(render_backend); | 203 | assert(render_backend); |
206 | assert(texture); | 204 | assert(texture); |
207 | assert(*texture); | 205 | assert(*texture); |
208 | gfx_del_texture(*texture); | 206 | |
209 | mempool_free(&render_backend->textures, texture); | 207 | if (*texture) { |
208 | gfx_del_texture(*texture); | ||
209 | mempool_free(&render_backend->textures, texture); | ||
210 | } | ||
210 | } | 211 | } |
211 | 212 | ||
212 | // ----------------------------------------------------------------------------- | 213 | // ----------------------------------------------------------------------------- |
@@ -217,10 +218,8 @@ RenderBuffer* gfx_make_renderbuffer( | |||
217 | RenderBackend* render_backend, const RenderBufferDesc* desc) { | 218 | RenderBackend* render_backend, const RenderBufferDesc* desc) { |
218 | assert(render_backend); | 219 | assert(render_backend); |
219 | assert(desc); | 220 | assert(desc); |
221 | |||
220 | RenderBuffer* renderbuffer = mempool_alloc(&render_backend->renderbuffers); | 222 | RenderBuffer* renderbuffer = mempool_alloc(&render_backend->renderbuffers); |
221 | if (!renderbuffer) { | ||
222 | return 0; | ||
223 | } | ||
224 | if (!gfx_init_renderbuffer(renderbuffer, desc)) { | 223 | if (!gfx_init_renderbuffer(renderbuffer, desc)) { |
225 | mempool_free(&render_backend->renderbuffers, &renderbuffer); | 224 | mempool_free(&render_backend->renderbuffers, &renderbuffer); |
226 | } | 225 | } |
@@ -232,8 +231,11 @@ void gfx_destroy_renderbuffer( | |||
232 | assert(render_backend); | 231 | assert(render_backend); |
233 | assert(renderbuffer); | 232 | assert(renderbuffer); |
234 | assert(*renderbuffer); | 233 | assert(*renderbuffer); |
235 | gfx_del_renderbuffer(*renderbuffer); | 234 | |
236 | mempool_free(&render_backend->renderbuffers, renderbuffer); | 235 | if (*renderbuffer) { |
236 | gfx_del_renderbuffer(*renderbuffer); | ||
237 | mempool_free(&render_backend->renderbuffers, renderbuffer); | ||
238 | } | ||
237 | } | 239 | } |
238 | 240 | ||
239 | // ----------------------------------------------------------------------------- | 241 | // ----------------------------------------------------------------------------- |
@@ -244,10 +246,8 @@ FrameBuffer* gfx_make_framebuffer( | |||
244 | RenderBackend* render_backend, const FrameBufferDesc* desc) { | 246 | RenderBackend* render_backend, const FrameBufferDesc* desc) { |
245 | assert(render_backend); | 247 | assert(render_backend); |
246 | assert(desc); | 248 | assert(desc); |
249 | |||
247 | FrameBuffer* framebuffer = mempool_alloc(&render_backend->framebuffers); | 250 | FrameBuffer* framebuffer = mempool_alloc(&render_backend->framebuffers); |
248 | if (!framebuffer) { | ||
249 | return 0; | ||
250 | } | ||
251 | if (!gfx_init_framebuffer(framebuffer, desc)) { | 251 | if (!gfx_init_framebuffer(framebuffer, desc)) { |
252 | mempool_free(&render_backend->framebuffers, &framebuffer); | 252 | mempool_free(&render_backend->framebuffers, &framebuffer); |
253 | return 0; | 253 | return 0; |
@@ -260,8 +260,11 @@ void gfx_destroy_framebuffer( | |||
260 | assert(render_backend); | 260 | assert(render_backend); |
261 | assert(framebuffer); | 261 | assert(framebuffer); |
262 | assert(*framebuffer); | 262 | assert(*framebuffer); |
263 | gfx_del_framebuffer(*framebuffer); | 263 | |
264 | mempool_free(&render_backend->framebuffers, framebuffer); | 264 | if (*framebuffer) { |
265 | gfx_del_framebuffer(*framebuffer); | ||
266 | mempool_free(&render_backend->framebuffers, framebuffer); | ||
267 | } | ||
265 | } | 268 | } |
266 | 269 | ||
267 | // ----------------------------------------------------------------------------- | 270 | // ----------------------------------------------------------------------------- |
@@ -340,7 +343,7 @@ Shader* gfx_make_shader(RenderBackend* render_backend, const ShaderDesc* desc) { | |||
340 | const uint64_t hash = hash_shader_desc(desc); | 343 | const uint64_t hash = hash_shader_desc(desc); |
341 | Shader* shader = find_cached_shader(cache, hash); | 344 | Shader* shader = find_cached_shader(cache, hash); |
342 | if (shader) { | 345 | if (shader) { |
343 | // LOGD("Found cached shader with hash %lx", hash); | 346 | // LOGD("Found cached shader with hash [%lx]", hash); |
344 | return shader; | 347 | return shader; |
345 | } | 348 | } |
346 | 349 | ||
@@ -353,25 +356,25 @@ Shader* gfx_make_shader(RenderBackend* render_backend, const ShaderDesc* desc) { | |||
353 | return 0; | 356 | return 0; |
354 | } | 357 | } |
355 | ShaderCacheEntry* entry = mempool_alloc(cache); | 358 | ShaderCacheEntry* entry = mempool_alloc(cache); |
356 | assert(entry); | 359 | *entry = (ShaderCacheEntry){.hash = hash, .shader = shader}; |
357 | *entry = (ShaderCacheEntry){.hash = hash, .shader = shader}; | 360 | // LOGD("Added shader with hash [%lx] to cache", hash); |
358 | // LOGD("Added shader with hash %lx to cache", hash); | ||
359 | return shader; | 361 | return shader; |
360 | } | 362 | } |
361 | 363 | ||
362 | void gfx_destroy_shader(RenderBackend* render_backend, Shader** shader) { | 364 | void gfx_destroy_shader(RenderBackend* render_backend, Shader** shader) { |
363 | assert(render_backend); | 365 | assert(render_backend); |
364 | assert(shader); | 366 | assert(shader); |
365 | assert(*shader); | ||
366 | 367 | ||
367 | // Remove the shader from the cache. | 368 | if (*shader) { |
368 | ShaderCache* cache = &render_backend->shader_cache; | 369 | // Remove the shader from the cache. |
369 | ShaderCacheEntry* entry = find_shader_cache_entry(cache, *shader); | 370 | ShaderCache* cache = &render_backend->shader_cache; |
370 | assert(entry); // Must be there, shaders can't go untracked. | 371 | ShaderCacheEntry* entry = find_shader_cache_entry(cache, *shader); |
371 | mempool_free(cache, &entry); | 372 | assert(entry); // Must be there, shaders can't go untracked. |
373 | mempool_free(cache, &entry); | ||
372 | 374 | ||
373 | gfx_del_shader(*shader); | 375 | gfx_del_shader(*shader); |
374 | mempool_free(&render_backend->shaders, shader); | 376 | mempool_free(&render_backend->shaders, shader); |
377 | } | ||
375 | } | 378 | } |
376 | 379 | ||
377 | ShaderProgram* gfx_make_shader_program( | 380 | ShaderProgram* gfx_make_shader_program( |
@@ -384,22 +387,18 @@ ShaderProgram* gfx_make_shader_program( | |||
384 | const uint64_t hash = hash_program_desc(desc); | 387 | const uint64_t hash = hash_program_desc(desc); |
385 | ShaderProgram* prog = find_cached_program(cache, hash); | 388 | ShaderProgram* prog = find_cached_program(cache, hash); |
386 | if (prog) { | 389 | if (prog) { |
387 | // LOGD("Found cached shader program with hash %lx", hash); | 390 | // LOGD("Found cached shader program with hash [%lx]", hash); |
388 | return prog; | 391 | return prog; |
389 | } | 392 | } |
390 | 393 | ||
391 | prog = mempool_alloc(&render_backend->shader_programs); | 394 | prog = mempool_alloc(&render_backend->shader_programs); |
392 | if (!prog) { | ||
393 | return 0; | ||
394 | } | ||
395 | if (!gfx_build_shader_program(prog, desc)) { | 395 | if (!gfx_build_shader_program(prog, desc)) { |
396 | mempool_free(&render_backend->shader_programs, &prog); | 396 | mempool_free(&render_backend->shader_programs, &prog); |
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | ShaderProgramCacheEntry* entry = mempool_alloc(cache); | 399 | ShaderProgramCacheEntry* entry = mempool_alloc(cache); |
400 | assert(entry); | ||
401 | *entry = (ShaderProgramCacheEntry){.hash = hash, .program = prog}; | 400 | *entry = (ShaderProgramCacheEntry){.hash = hash, .program = prog}; |
402 | // LOGD("Added shader program with hash %lx to cache", hash); | 401 | // LOGD("Added shader program with hash [%lx] to cache", hash); |
403 | return prog; | 402 | return prog; |
404 | } | 403 | } |
405 | 404 | ||
@@ -407,14 +406,14 @@ void gfx_destroy_shader_program( | |||
407 | RenderBackend* render_backend, ShaderProgram** prog) { | 406 | RenderBackend* render_backend, ShaderProgram** prog) { |
408 | assert(render_backend); | 407 | assert(render_backend); |
409 | assert(prog); | 408 | assert(prog); |
410 | assert(*prog); | 409 | if (*prog) { |
411 | 410 | // Remove the shader program from the cache. | |
412 | // Remove the shader program from the cache. | 411 | ProgramCache* cache = &render_backend->program_cache; |
413 | ProgramCache* cache = &render_backend->program_cache; | 412 | ShaderProgramCacheEntry* entry = find_program_cache_entry(cache, *prog); |
414 | ShaderProgramCacheEntry* entry = find_program_cache_entry(cache, *prog); | 413 | assert(entry); // Must be there, shaders can't go untracked. |
415 | assert(entry); // Must be there, shaders can't go untracked. | 414 | mempool_free(cache, &entry); |
416 | mempool_free(cache, &entry); | 415 | |
417 | 416 | gfx_del_shader_program(*prog); | |
418 | gfx_del_shader_program(*prog); | 417 | mempool_free(&render_backend->shader_programs, prog); |
419 | mempool_free(&render_backend->shader_programs, prog); | 418 | } |
420 | } | 419 | } |
diff --git a/gfx/src/render/renderbuffer.c b/gfx/src/render/renderbuffer.c index a2eae52..23f9524 100644 --- a/gfx/src/render/renderbuffer.c +++ b/gfx/src/render/renderbuffer.c | |||
@@ -27,6 +27,7 @@ bool gfx_init_renderbuffer( | |||
27 | 27 | ||
28 | void gfx_del_renderbuffer(RenderBuffer* renderbuffer) { | 28 | void gfx_del_renderbuffer(RenderBuffer* renderbuffer) { |
29 | assert(renderbuffer); | 29 | assert(renderbuffer); |
30 | |||
30 | if (renderbuffer->id) { | 31 | if (renderbuffer->id) { |
31 | glDeleteRenderbuffers(1, &renderbuffer->id); | 32 | glDeleteRenderbuffers(1, &renderbuffer->id); |
32 | renderbuffer->id = 0; | 33 | renderbuffer->id = 0; |
diff --git a/gfx/src/render/shader.c b/gfx/src/render/shader.c index d4778a2..af2f89f 100644 --- a/gfx/src/render/shader.c +++ b/gfx/src/render/shader.c | |||
@@ -1,11 +1,11 @@ | |||
1 | #include "shader.h" | 1 | #include "shader.h" |
2 | 2 | ||
3 | #include "gl_util.h" | 3 | #include "gl_util.h" |
4 | #include <gfx_assert.h> | ||
4 | 5 | ||
5 | #include <cstring.h> | 6 | #include <cstring.h> |
6 | #include <log/log.h> | 7 | #include <log/log.h> |
7 | 8 | ||
8 | #include <assert.h> | ||
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <string.h> | 10 | #include <string.h> |
11 | 11 | ||
@@ -15,10 +15,9 @@ static GLenum shader_type_to_gl(ShaderType type) { | |||
15 | return GL_VERTEX_SHADER; | 15 | return GL_VERTEX_SHADER; |
16 | case FragmentShader: | 16 | case FragmentShader: |
17 | return GL_FRAGMENT_SHADER; | 17 | return GL_FRAGMENT_SHADER; |
18 | default: | ||
19 | LOGE("shader_type_to_gl(): missing case"); | ||
20 | return GL_INVALID_ENUM; | ||
21 | } | 18 | } |
19 | FAIL("shader_type_to_gl(): missing case"); | ||
20 | return GL_INVALID_ENUM; | ||
22 | } | 21 | } |
23 | 22 | ||
24 | static lstring make_defines_string(const ShaderDesc* desc) { | 23 | static lstring make_defines_string(const ShaderDesc* desc) { |
@@ -84,6 +83,7 @@ bool gfx_compile_shader(Shader* shader, const ShaderDesc* desc) { | |||
84 | 83 | ||
85 | void gfx_del_shader(Shader* shader) { | 84 | void gfx_del_shader(Shader* shader) { |
86 | assert(shader); | 85 | assert(shader); |
86 | |||
87 | if (shader->id) { | 87 | if (shader->id) { |
88 | glDeleteShader(shader->id); | 88 | glDeleteShader(shader->id); |
89 | shader->id = 0; | 89 | shader->id = 0; |
diff --git a/gfx/src/render/shader_program.c b/gfx/src/render/shader_program.c index d80ee4f..3cbe48d 100644 --- a/gfx/src/render/shader_program.c +++ b/gfx/src/render/shader_program.c | |||
@@ -3,10 +3,10 @@ | |||
3 | #include "gl_util.h" | 3 | #include "gl_util.h" |
4 | #include "shader.h" | 4 | #include "shader.h" |
5 | #include "texture.h" | 5 | #include "texture.h" |
6 | #include <gfx_assert.h> | ||
6 | 7 | ||
7 | #include <log/log.h> | 8 | #include <log/log.h> |
8 | 9 | ||
9 | #include <assert.h> | ||
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <string.h> | 11 | #include <string.h> |
12 | 12 | ||
@@ -45,12 +45,14 @@ bool gfx_build_shader_program( | |||
45 | ShaderProgram* prog, const ShaderProgramDesc* desc) { | 45 | ShaderProgram* prog, const ShaderProgramDesc* desc) { |
46 | assert(prog); | 46 | assert(prog); |
47 | assert(desc); | 47 | assert(desc); |
48 | |||
48 | prog->id = create_program(desc->vertex_shader->id, desc->fragment_shader->id); | 49 | prog->id = create_program(desc->vertex_shader->id, desc->fragment_shader->id); |
49 | return prog->id != 0; | 50 | return prog->id != 0; |
50 | } | 51 | } |
51 | 52 | ||
52 | void gfx_del_shader_program(ShaderProgram* prog) { | 53 | void gfx_del_shader_program(ShaderProgram* prog) { |
53 | assert(prog); | 54 | assert(prog); |
55 | |||
54 | if (prog->id) { | 56 | if (prog->id) { |
55 | glDeleteProgram(prog->id); | 57 | glDeleteProgram(prog->id); |
56 | prog->id = 0; | 58 | prog->id = 0; |
@@ -75,6 +77,7 @@ static void set_texture_uniform( | |||
75 | assert(prog != 0); | 77 | assert(prog != 0); |
76 | assert(name); | 78 | assert(name); |
77 | assert(texture); | 79 | assert(texture); |
80 | |||
78 | const GLint location = glGetUniformLocation(prog, name); | 81 | const GLint location = glGetUniformLocation(prog, name); |
79 | if (location >= 0) { | 82 | if (location >= 0) { |
80 | glActiveTexture(GL_TEXTURE0 + texture_unit); | 83 | glActiveTexture(GL_TEXTURE0 + texture_unit); |
@@ -88,6 +91,7 @@ static void set_mat4_uniform( | |||
88 | assert(prog != 0); | 91 | assert(prog != 0); |
89 | assert(name); | 92 | assert(name); |
90 | assert(mats); | 93 | assert(mats); |
94 | |||
91 | const GLint location = glGetUniformLocation(prog, name); | 95 | const GLint location = glGetUniformLocation(prog, name); |
92 | if (location >= 0) { | 96 | if (location >= 0) { |
93 | glUniformMatrix4fv(location, count, GL_FALSE, (const float*)mats); | 97 | glUniformMatrix4fv(location, count, GL_FALSE, (const float*)mats); |
@@ -97,6 +101,7 @@ static void set_mat4_uniform( | |||
97 | static void set_vec3_uniform(GLuint prog, const char* name, vec3 value) { | 101 | static void set_vec3_uniform(GLuint prog, const char* name, vec3 value) { |
98 | assert(prog != 0); | 102 | assert(prog != 0); |
99 | assert(name); | 103 | assert(name); |
104 | |||
100 | const GLint location = glGetUniformLocation(prog, name); | 105 | const GLint location = glGetUniformLocation(prog, name); |
101 | if (location >= 0) { | 106 | if (location >= 0) { |
102 | glUniform3f(location, value.x, value.y, value.z); | 107 | glUniform3f(location, value.x, value.y, value.z); |
@@ -106,6 +111,7 @@ static void set_vec3_uniform(GLuint prog, const char* name, vec3 value) { | |||
106 | static void set_vec4_uniform(GLuint prog, const char* name, vec4 value) { | 111 | static void set_vec4_uniform(GLuint prog, const char* name, vec4 value) { |
107 | assert(prog != 0); | 112 | assert(prog != 0); |
108 | assert(name); | 113 | assert(name); |
114 | |||
109 | const GLint location = glGetUniformLocation(prog, name); | 115 | const GLint location = glGetUniformLocation(prog, name); |
110 | if (location >= 0) { | 116 | if (location >= 0) { |
111 | glUniform4f(location, value.x, value.y, value.z, value.w); | 117 | glUniform4f(location, value.x, value.y, value.z, value.w); |
@@ -115,6 +121,7 @@ static void set_vec4_uniform(GLuint prog, const char* name, vec4 value) { | |||
115 | static void set_float_uniform(GLuint prog, const char* name, float value) { | 121 | static void set_float_uniform(GLuint prog, const char* name, float value) { |
116 | assert(prog != 0); | 122 | assert(prog != 0); |
117 | assert(name); | 123 | assert(name); |
124 | |||
118 | const GLint location = glGetUniformLocation(prog, name); | 125 | const GLint location = glGetUniformLocation(prog, name); |
119 | if (location >= 0) { | 126 | if (location >= 0) { |
120 | glUniform1f(location, value); | 127 | glUniform1f(location, value); |
@@ -123,6 +130,7 @@ static void set_float_uniform(GLuint prog, const char* name, float value) { | |||
123 | 130 | ||
124 | void gfx_apply_uniforms(const ShaderProgram* prog) { | 131 | void gfx_apply_uniforms(const ShaderProgram* prog) { |
125 | assert(prog); | 132 | assert(prog); |
133 | |||
126 | int next_texture_unit = 0; | 134 | int next_texture_unit = 0; |
127 | for (int i = 0; i < prog->num_uniforms; ++i) { | 135 | for (int i = 0; i < prog->num_uniforms; ++i) { |
128 | const ShaderUniform* uniform = &prog->uniforms[i]; | 136 | const ShaderUniform* uniform = &prog->uniforms[i]; |
@@ -160,6 +168,7 @@ static ShaderUniform* get_or_allocate_uniform( | |||
160 | ShaderProgram* prog, const char* name) { | 168 | ShaderProgram* prog, const char* name) { |
161 | assert(prog); | 169 | assert(prog); |
162 | assert(name); | 170 | assert(name); |
171 | |||
163 | // First search for the uniform in the list. | 172 | // First search for the uniform in the list. |
164 | for (int i = 0; i < prog->num_uniforms; ++i) { | 173 | for (int i = 0; i < prog->num_uniforms; ++i) { |
165 | ShaderUniform* uniform = &prog->uniforms[i]; | 174 | ShaderUniform* uniform = &prog->uniforms[i]; |
@@ -167,11 +176,11 @@ static ShaderUniform* get_or_allocate_uniform( | |||
167 | return uniform; | 176 | return uniform; |
168 | } | 177 | } |
169 | } | 178 | } |
179 | |||
170 | // Create the uniform if it does not exist. | 180 | // Create the uniform if it does not exist. |
171 | if (prog->num_uniforms == GFX_MAX_UNIFORMS_PER_SHADER) { | 181 | if (prog->num_uniforms == GFX_MAX_UNIFORMS_PER_SHADER) { |
172 | LOGE("Exceeded the maximum number of uniforms per shader. Please increase " | 182 | FAIL("Exceeded the maximum number of uniforms per shader. Please increase " |
173 | "this value."); | 183 | "this value."); |
174 | assert(false); | ||
175 | return 0; | 184 | return 0; |
176 | } | 185 | } |
177 | ShaderUniform* uniform = &prog->uniforms[prog->num_uniforms]; | 186 | ShaderUniform* uniform = &prog->uniforms[prog->num_uniforms]; |
@@ -187,6 +196,7 @@ void gfx_set_texture_uniform( | |||
187 | assert(prog); | 196 | assert(prog); |
188 | assert(name); | 197 | assert(name); |
189 | assert(texture); | 198 | assert(texture); |
199 | |||
190 | const GLint location = glGetUniformLocation(prog->id, name); | 200 | const GLint location = glGetUniformLocation(prog->id, name); |
191 | if (location < 0) { | 201 | if (location < 0) { |
192 | return; | 202 | return; |
@@ -203,6 +213,7 @@ void gfx_set_mat4_uniform( | |||
203 | assert(prog); | 213 | assert(prog); |
204 | assert(name); | 214 | assert(name); |
205 | assert(mat); | 215 | assert(mat); |
216 | |||
206 | const GLint location = glGetUniformLocation(prog->id, name); | 217 | const GLint location = glGetUniformLocation(prog->id, name); |
207 | if (location < 0) { | 218 | if (location < 0) { |
208 | return; | 219 | return; |
@@ -217,6 +228,7 @@ void gfx_set_mat4_uniform( | |||
217 | void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) { | 228 | void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) { |
218 | assert(prog); | 229 | assert(prog); |
219 | assert(name); | 230 | assert(name); |
231 | |||
220 | const GLint location = glGetUniformLocation(prog->id, name); | 232 | const GLint location = glGetUniformLocation(prog->id, name); |
221 | if (location < 0) { | 233 | if (location < 0) { |
222 | return; | 234 | return; |
@@ -231,6 +243,7 @@ void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) { | |||
231 | void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) { | 243 | void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) { |
232 | assert(prog); | 244 | assert(prog); |
233 | assert(name); | 245 | assert(name); |
246 | |||
234 | const GLint location = glGetUniformLocation(prog->id, name); | 247 | const GLint location = glGetUniformLocation(prog->id, name); |
235 | if (location < 0) { | 248 | if (location < 0) { |
236 | return; | 249 | return; |
@@ -245,6 +258,7 @@ void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) { | |||
245 | void gfx_set_float_uniform(ShaderProgram* prog, const char* name, float value) { | 258 | void gfx_set_float_uniform(ShaderProgram* prog, const char* name, float value) { |
246 | assert(prog); | 259 | assert(prog); |
247 | assert(name); | 260 | assert(name); |
261 | |||
248 | // No need to store the uniform on our side if it does not exist in the | 262 | // No need to store the uniform on our side if it does not exist in the |
249 | // program. | 263 | // program. |
250 | const GLint location = glGetUniformLocation(prog->id, name); | 264 | const GLint location = glGetUniformLocation(prog->id, name); |
@@ -263,6 +277,7 @@ void gfx_set_mat4_array_uniform( | |||
263 | assert(prog); | 277 | assert(prog); |
264 | assert(name); | 278 | assert(name); |
265 | assert(mats); | 279 | assert(mats); |
280 | |||
266 | const GLint location = glGetUniformLocation(prog->id, name); | 281 | const GLint location = glGetUniformLocation(prog->id, name); |
267 | if (location < 0) { | 282 | if (location < 0) { |
268 | return; | 283 | return; |
diff --git a/gfx/src/render/texture.c b/gfx/src/render/texture.c index 489f7a2..fd1d4dd 100644 --- a/gfx/src/render/texture.c +++ b/gfx/src/render/texture.c | |||
@@ -1,9 +1,10 @@ | |||
1 | #include "texture.h" | 1 | #include "texture.h" |
2 | 2 | ||
3 | #include <gfx_assert.h> | ||
4 | |||
3 | #include <error.h> | 5 | #include <error.h> |
4 | #include <math/defs.h> | 6 | #include <math/defs.h> |
5 | 7 | ||
6 | #include <assert.h> | ||
7 | #include <stdbool.h> | 8 | #include <stdbool.h> |
8 | 9 | ||
9 | bool gfx_init_texture(Texture* texture, const TextureDesc* desc) { | 10 | bool gfx_init_texture(Texture* texture, const TextureDesc* desc) { |
@@ -32,7 +33,7 @@ bool gfx_init_texture(Texture* texture, const TextureDesc* desc) { | |||
32 | texture->target, levels, internal_format, desc->width, desc->height); | 33 | texture->target, levels, internal_format, desc->width, desc->height); |
33 | break; | 34 | break; |
34 | default: | 35 | default: |
35 | assert(false && "Unhandled texture dimension"); | 36 | FAIL("Unhandled texture dimension"); |
36 | gfx_del_texture(texture); | 37 | gfx_del_texture(texture); |
37 | return false; | 38 | return false; |
38 | } | 39 | } |
@@ -79,6 +80,8 @@ bool gfx_init_texture(Texture* texture, const TextureDesc* desc) { | |||
79 | } | 80 | } |
80 | 81 | ||
81 | void gfx_del_texture(Texture* texture) { | 82 | void gfx_del_texture(Texture* texture) { |
83 | assert(texture); | ||
84 | |||
82 | if (texture->id) { | 85 | if (texture->id) { |
83 | glDeleteTextures(1, &texture->id); | 86 | glDeleteTextures(1, &texture->id); |
84 | texture->id = 0; | 87 | texture->id = 0; |
@@ -113,7 +116,7 @@ void gfx_update_texture(Texture* texture, const TextureDataDesc* desc) { | |||
113 | } | 116 | } |
114 | break; | 117 | break; |
115 | default: | 118 | default: |
116 | assert(false && "Unhandled texture dimension"); | 119 | FAIL("Unhandled texture dimension"); |
117 | break; | 120 | break; |
118 | } | 121 | } |
119 | 122 | ||
@@ -127,7 +130,7 @@ GLenum to_GL_dimension(TextureDimension dim) { | |||
127 | case TextureCubeMap: | 130 | case TextureCubeMap: |
128 | return GL_TEXTURE_CUBE_MAP; | 131 | return GL_TEXTURE_CUBE_MAP; |
129 | default: | 132 | default: |
130 | assert(false && "Unhandled TextureDimension"); | 133 | FAIL("Unhandled TextureDimension"); |
131 | return GL_INVALID_ENUM; | 134 | return GL_INVALID_ENUM; |
132 | } | 135 | } |
133 | } | 136 | } |
@@ -151,7 +154,7 @@ GLenum to_GL_internal_format(TextureFormat format) { | |||
151 | case TextureSRGBA8: | 154 | case TextureSRGBA8: |
152 | return GL_SRGB8_ALPHA8; | 155 | return GL_SRGB8_ALPHA8; |
153 | default: | 156 | default: |
154 | assert(false && "Unhandled TextureFormat"); | 157 | FAIL("Unhandled TextureFormat"); |
155 | return GL_INVALID_ENUM; | 158 | return GL_INVALID_ENUM; |
156 | } | 159 | } |
157 | } | 160 | } |
@@ -171,7 +174,7 @@ GLenum to_GL_format(TextureFormat format) { | |||
171 | case TextureSRGBA8: | 174 | case TextureSRGBA8: |
172 | return GL_RGBA; | 175 | return GL_RGBA; |
173 | default: | 176 | default: |
174 | assert(false && "Unhandled TextureFormat"); | 177 | FAIL("Unhandled TextureFormat"); |
175 | return GL_INVALID_ENUM; | 178 | return GL_INVALID_ENUM; |
176 | } | 179 | } |
177 | } | 180 | } |
@@ -189,7 +192,7 @@ GLenum to_GL_type(TextureFormat format) { | |||
189 | case TextureSRGBA8: | 192 | case TextureSRGBA8: |
190 | return GL_UNSIGNED_BYTE; | 193 | return GL_UNSIGNED_BYTE; |
191 | default: | 194 | default: |
192 | assert(false && "Unhandled TextureFormat"); | 195 | FAIL("Unhandled TextureFormat"); |
193 | return GL_INVALID_ENUM; | 196 | return GL_INVALID_ENUM; |
194 | } | 197 | } |
195 | } | 198 | } |
@@ -209,7 +212,7 @@ GLenum to_GL_cubemap_face(CubemapFace face) { | |||
209 | case CubemapFaceNegZ: | 212 | case CubemapFaceNegZ: |
210 | return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; | 213 | return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; |
211 | default: | 214 | default: |
212 | assert(false && "Unhandled CubemapFace"); | 215 | FAIL("Unhandled CubemapFace"); |
213 | return GL_INVALID_ENUM; | 216 | return GL_INVALID_ENUM; |
214 | } | 217 | } |
215 | } | 218 | } |
diff --git a/gfx/src/scene/animation.c b/gfx/src/scene/animation.c index 8d8178e..459e864 100644 --- a/gfx/src/scene/animation.c +++ b/gfx/src/scene/animation.c | |||
@@ -13,8 +13,7 @@ Joint* gfx_make_joint(const JointDesc* desc) { | |||
13 | // The joint matrix needs to be initialized so that meshes look right even if | 13 | // The joint matrix needs to be initialized so that meshes look right even if |
14 | // no animation is played. Initializing joint matrices to the identity makes | 14 | // no animation is played. Initializing joint matrices to the identity makes |
15 | // meshes appear in their bind pose. | 15 | // meshes appear in their bind pose. |
16 | Joint* joint = mem_alloc_joint(); | 16 | Joint* joint = mem_alloc_joint(); |
17 | assert(joint); | ||
18 | joint->inv_bind_matrix = desc->inv_bind_matrix; | 17 | joint->inv_bind_matrix = desc->inv_bind_matrix; |
19 | joint->joint_matrix = mat4_id(); | 18 | joint->joint_matrix = mat4_id(); |
20 | return joint; | 19 | return joint; |
@@ -22,20 +21,20 @@ Joint* gfx_make_joint(const JointDesc* desc) { | |||
22 | 21 | ||
23 | void gfx_destroy_joint(Joint** joint) { | 22 | void gfx_destroy_joint(Joint** joint) { |
24 | assert(joint); | 23 | assert(joint); |
25 | assert(*joint); | ||
26 | 24 | ||
27 | if ((*joint)->parent.val) { | 25 | if (*joint) { |
28 | gfx_del_node((*joint)->parent); | 26 | if ((*joint)->parent.val) { |
27 | gfx_del_node((*joint)->parent); | ||
28 | } | ||
29 | mem_free_joint(joint); | ||
29 | } | 30 | } |
30 | mem_free_joint(joint); | ||
31 | } | 31 | } |
32 | 32 | ||
33 | static Skeleton* make_skeleton(const SkeletonDesc* desc) { | 33 | static Skeleton* make_skeleton(const SkeletonDesc* desc) { |
34 | assert(desc); | 34 | assert(desc); |
35 | assert(desc->num_joints < GFX_MAX_NUM_JOINTS); | 35 | assert(desc->num_joints < GFX_MAX_NUM_JOINTS); |
36 | 36 | ||
37 | Skeleton* skeleton = mem_alloc_skeleton(); | 37 | Skeleton* skeleton = mem_alloc_skeleton(); |
38 | assert(skeleton); | ||
39 | skeleton->num_joints = desc->num_joints; | 38 | skeleton->num_joints = desc->num_joints; |
40 | for (size_t i = 0; i < desc->num_joints; ++i) { | 39 | for (size_t i = 0; i < desc->num_joints; ++i) { |
41 | skeleton->joints[i] = mem_get_node_index(desc->joints[i]); | 40 | skeleton->joints[i] = mem_get_node_index(desc->joints[i]); |
@@ -47,8 +46,7 @@ static Animation* make_animation(const AnimationDesc* desc) { | |||
47 | assert(desc); | 46 | assert(desc); |
48 | assert(desc->num_channels < GFX_MAX_NUM_CHANNELS); | 47 | assert(desc->num_channels < GFX_MAX_NUM_CHANNELS); |
49 | 48 | ||
50 | Animation* animation = mem_alloc_animation(); | 49 | Animation* animation = mem_alloc_animation(); |
51 | assert(animation); | ||
52 | animation->name = desc->name; | 50 | animation->name = desc->name; |
53 | animation->duration = 0; | 51 | animation->duration = 0; |
54 | animation->num_channels = desc->num_channels; | 52 | animation->num_channels = desc->num_channels; |
@@ -86,9 +84,6 @@ Anima* gfx_make_anima(const AnimaDesc* desc) { | |||
86 | assert(desc); | 84 | assert(desc); |
87 | 85 | ||
88 | Anima* anima = mem_alloc_anima(); | 86 | Anima* anima = mem_alloc_anima(); |
89 | if (!anima) { | ||
90 | return 0; | ||
91 | } | ||
92 | 87 | ||
93 | // Wire the skeletons in the same order they are given in the descriptor. | 88 | // Wire the skeletons in the same order they are given in the descriptor. |
94 | Skeleton* last_skeleton = 0; | 89 | Skeleton* last_skeleton = 0; |
@@ -97,7 +92,6 @@ Anima* gfx_make_anima(const AnimaDesc* desc) { | |||
97 | // TODO: Here and everywhere else, I think it would simplify the code | 92 | // TODO: Here and everywhere else, I think it would simplify the code |
98 | // greatly to make mem_alloc_xyz() fail if the allocation fails. At that | 93 | // greatly to make mem_alloc_xyz() fail if the allocation fails. At that |
99 | // point the user should just bump their memory limits. | 94 | // point the user should just bump their memory limits. |
100 | assert(skeleton); | ||
101 | const skeleton_idx skeleton_index = mem_get_skeleton_index(skeleton); | 95 | const skeleton_idx skeleton_index = mem_get_skeleton_index(skeleton); |
102 | if (last_skeleton == 0) { | 96 | if (last_skeleton == 0) { |
103 | anima->skeleton = skeleton_index; | 97 | anima->skeleton = skeleton_index; |
@@ -110,8 +104,7 @@ Anima* gfx_make_anima(const AnimaDesc* desc) { | |||
110 | // Wire the animations in the same order they are given in the descriptor. | 104 | // Wire the animations in the same order they are given in the descriptor. |
111 | Animation* last_animation = 0; | 105 | Animation* last_animation = 0; |
112 | for (size_t i = 0; i < desc->num_animations; ++i) { | 106 | for (size_t i = 0; i < desc->num_animations; ++i) { |
113 | Animation* animation = make_animation(&desc->animations[i]); | 107 | Animation* animation = make_animation(&desc->animations[i]); |
114 | assert(animation); | ||
115 | const animation_idx animation_index = mem_get_animation_index(animation); | 108 | const animation_idx animation_index = mem_get_animation_index(animation); |
116 | if (last_animation == 0) { | 109 | if (last_animation == 0) { |
117 | anima->animation = animation_index; | 110 | anima->animation = animation_index; |
@@ -126,25 +119,26 @@ Anima* gfx_make_anima(const AnimaDesc* desc) { | |||
126 | 119 | ||
127 | void gfx_destroy_anima(Anima** anima) { | 120 | void gfx_destroy_anima(Anima** anima) { |
128 | assert(anima); | 121 | assert(anima); |
129 | assert(*anima); | ||
130 | 122 | ||
131 | for (skeleton_idx i = (*anima)->skeleton; i.val != 0;) { | 123 | if (*anima) { |
132 | Skeleton* skeleton = mem_get_skeleton(i); | 124 | for (skeleton_idx i = (*anima)->skeleton; i.val != 0;) { |
133 | i = skeleton->next; | 125 | Skeleton* skeleton = mem_get_skeleton(i); |
134 | mem_free_skeleton(&skeleton); | 126 | i = skeleton->next; |
135 | } | 127 | mem_free_skeleton(&skeleton); |
128 | } | ||
136 | 129 | ||
137 | for (animation_idx i = (*anima)->animation; i.val != 0;) { | 130 | for (animation_idx i = (*anima)->animation; i.val != 0;) { |
138 | Animation* animation = mem_get_animation(i); | 131 | Animation* animation = mem_get_animation(i); |
139 | i = animation->next; | 132 | i = animation->next; |
140 | mem_free_animation(&animation); | 133 | mem_free_animation(&animation); |
141 | } | 134 | } |
142 | 135 | ||
143 | if ((*anima)->parent.val) { | 136 | if ((*anima)->parent.val) { |
144 | gfx_del_node((*anima)->parent); | 137 | gfx_del_node((*anima)->parent); |
145 | } | 138 | } |
146 | 139 | ||
147 | mem_free_anima(anima); | 140 | mem_free_anima(anima); |
141 | } | ||
148 | } | 142 | } |
149 | 143 | ||
150 | static Animation* find_animation(animation_idx index, const char* name) { | 144 | static Animation* find_animation(animation_idx index, const char* name) { |
@@ -152,7 +146,6 @@ static Animation* find_animation(animation_idx index, const char* name) { | |||
152 | 146 | ||
153 | while (index.val != 0) { | 147 | while (index.val != 0) { |
154 | Animation* animation = mem_get_animation(index); | 148 | Animation* animation = mem_get_animation(index); |
155 | assert(animation); | ||
156 | if (sstring_eq_cstr(animation->name, name)) { | 149 | if (sstring_eq_cstr(animation->name, name)) { |
157 | // LOGD( | 150 | // LOGD( |
158 | // "Found animation at index %u, %s - %s", index.val, | 151 | // "Found animation at index %u, %s - %s", index.val, |
@@ -171,7 +164,7 @@ bool gfx_play_animation(Anima* anima, const AnimationPlaySettings* settings) { | |||
171 | assert(settings); | 164 | assert(settings); |
172 | 165 | ||
173 | // TODO: Should we animate at t=0 here to kickstart the animation? Otherwise | 166 | // TODO: Should we animate at t=0 here to kickstart the animation? Otherwise |
174 | // the client is forced to call gfx_update_animation() to do this. | 167 | // the client is forced to call gfx_update_animation() to do this. |
175 | Animation* animation = find_animation(anima->animation, settings->name); | 168 | Animation* animation = find_animation(anima->animation, settings->name); |
176 | if (!animation) { | 169 | if (!animation) { |
177 | return false; | 170 | return false; |
@@ -188,6 +181,7 @@ static void find_keyframes(const Channel* channel, R t, int* prev, int* next) { | |||
188 | assert(channel); | 181 | assert(channel); |
189 | assert(prev); | 182 | assert(prev); |
190 | assert(next); | 183 | assert(next); |
184 | |||
191 | *prev = -1; | 185 | *prev = -1; |
192 | *next = 0; | 186 | *next = 0; |
193 | while (((*next + 1) < (int)channel->num_keyframes) && | 187 | while (((*next + 1) < (int)channel->num_keyframes) && |
@@ -275,7 +269,6 @@ static void animate_channel(const Channel* channel, R t) { | |||
275 | t = t > channel->keyframes[next].time ? channel->keyframes[next].time : t; | 269 | t = t > channel->keyframes[next].time ? channel->keyframes[next].time : t; |
276 | 270 | ||
277 | SceneNode* target = mem_get_node(channel->target); | 271 | SceneNode* target = mem_get_node(channel->target); |
278 | assert(target); | ||
279 | 272 | ||
280 | switch (channel->type) { | 273 | switch (channel->type) { |
281 | case RotationChannel: { | 274 | case RotationChannel: { |
@@ -306,8 +299,7 @@ static void compute_joint_matrices_rec( | |||
306 | } | 299 | } |
307 | 300 | ||
308 | const SceneNode* node = mem_get_node(node_index); | 301 | const SceneNode* node = mem_get_node(node_index); |
309 | assert(node); | 302 | const mat4 global_joint_transform = |
310 | const mat4 global_joint_transform = | ||
311 | mat4_mul(parent_global_joint_transform, node->transform); | 303 | mat4_mul(parent_global_joint_transform, node->transform); |
312 | 304 | ||
313 | // For flexibility (glTF), we allow non-joint nodes between the root of the | 305 | // For flexibility (glTF), we allow non-joint nodes between the root of the |
@@ -316,7 +308,6 @@ static void compute_joint_matrices_rec( | |||
316 | if (node->type == JointNode) { | 308 | if (node->type == JointNode) { |
317 | // Compute this node's joint matrix. | 309 | // Compute this node's joint matrix. |
318 | Joint* joint = mem_get_joint(node->joint); | 310 | Joint* joint = mem_get_joint(node->joint); |
319 | assert(joint); | ||
320 | 311 | ||
321 | joint->joint_matrix = mat4_mul( | 312 | joint->joint_matrix = mat4_mul( |
322 | *root_inv_global_transform, | 313 | *root_inv_global_transform, |
@@ -328,8 +319,7 @@ static void compute_joint_matrices_rec( | |||
328 | while (child.val != 0) { | 319 | while (child.val != 0) { |
329 | compute_joint_matrices_rec( | 320 | compute_joint_matrices_rec( |
330 | child, global_joint_transform, root_inv_global_transform); | 321 | child, global_joint_transform, root_inv_global_transform); |
331 | node = mem_get_node(child); | 322 | node = mem_get_node(child); |
332 | assert(node); | ||
333 | child = node->next; // Next sibling. | 323 | child = node->next; // Next sibling. |
334 | } | 324 | } |
335 | } | 325 | } |
@@ -381,7 +371,6 @@ void gfx_update_animation(Anima* anima, R t) { | |||
381 | // once (and potentially other non-joint intermediate nodes). | 371 | // once (and potentially other non-joint intermediate nodes). |
382 | node_idx root_index = anima->parent; | 372 | node_idx root_index = anima->parent; |
383 | SceneNode* root = mem_get_node(root_index); | 373 | SceneNode* root = mem_get_node(root_index); |
384 | assert(root); | ||
385 | // LOGD("Root: %u, child: %u", root_index.val, root->child.val); | 374 | // LOGD("Root: %u, child: %u", root_index.val, root->child.val); |
386 | const mat4 root_global_transform = gfx_get_node_global_transform(root); | 375 | const mat4 root_global_transform = gfx_get_node_global_transform(root); |
387 | const mat4 root_inv_global_transform = mat4_inverse(root_global_transform); | 376 | const mat4 root_inv_global_transform = mat4_inverse(root_global_transform); |
@@ -391,8 +380,7 @@ void gfx_update_animation(Anima* anima, R t) { | |||
391 | compute_joint_matrices_rec( | 380 | compute_joint_matrices_rec( |
392 | child, root_global_transform, &root_inv_global_transform); | 381 | child, root_global_transform, &root_inv_global_transform); |
393 | SceneNode* node = mem_get_node(child); | 382 | SceneNode* node = mem_get_node(child); |
394 | assert(node); | 383 | child = node->next; // Next sibling. |
395 | child = node->next; // Next sibling. | ||
396 | } | 384 | } |
397 | } | 385 | } |
398 | 386 | ||
diff --git a/gfx/src/scene/camera.c b/gfx/src/scene/camera.c index df161c2..be7d806 100644 --- a/gfx/src/scene/camera.c +++ b/gfx/src/scene/camera.c | |||
@@ -5,29 +5,24 @@ | |||
5 | 5 | ||
6 | #include <assert.h> | 6 | #include <assert.h> |
7 | 7 | ||
8 | static void scene_camera_make(SceneCamera* camera) { | ||
9 | assert(camera); | ||
10 | camera->camera = | ||
11 | camera_perspective(/*fovy=*/90.0 * TO_RAD, /*aspect=*/16.0 / 9.0, | ||
12 | /*near=*/0.1, /*far=*/1000); | ||
13 | } | ||
14 | |||
15 | SceneCamera* gfx_make_camera() { | 8 | SceneCamera* gfx_make_camera() { |
16 | SceneCamera* camera = mem_alloc_camera(); | 9 | SceneCamera* camera = mem_alloc_camera(); |
17 | if (!camera) { | 10 | |
18 | return 0; | 11 | camera->camera = camera_perspective( |
19 | } | 12 | /*fovy=*/90.0 * TO_RAD, /*aspect=*/16.0 / 9.0, |
20 | scene_camera_make(camera); | 13 | /*near=*/0.1, /*far=*/1000); |
14 | |||
21 | return camera; | 15 | return camera; |
22 | } | 16 | } |
23 | 17 | ||
24 | void gfx_destroy_camera(SceneCamera** camera) { | 18 | void gfx_destroy_camera(SceneCamera** camera) { |
25 | assert(camera); | 19 | assert(camera); |
26 | assert(*camera); | 20 | if (*camera) { |
27 | if ((*camera)->parent.val) { | 21 | if ((*camera)->parent.val) { |
28 | gfx_del_node((*camera)->parent); | 22 | gfx_del_node((*camera)->parent); |
23 | } | ||
24 | mem_free_camera(camera); | ||
29 | } | 25 | } |
30 | mem_free_camera(camera); | ||
31 | } | 26 | } |
32 | 27 | ||
33 | void gfx_set_camera_camera(SceneCamera* scene_camera, Camera* camera) { | 28 | void gfx_set_camera_camera(SceneCamera* scene_camera, Camera* camera) { |
diff --git a/gfx/src/scene/light.c b/gfx/src/scene/light.c index 31dca77..1046c82 100644 --- a/gfx/src/scene/light.c +++ b/gfx/src/scene/light.c | |||
@@ -9,7 +9,6 @@ static void make_environment_light( | |||
9 | Light* light, const EnvironmentLightDesc* desc) { | 9 | Light* light, const EnvironmentLightDesc* desc) { |
10 | assert(light); | 10 | assert(light); |
11 | assert(desc); | 11 | assert(desc); |
12 | |||
13 | light->type = EnvironmentLightType; | 12 | light->type = EnvironmentLightType; |
14 | light->environment.environment_map = desc->environment_map; | 13 | light->environment.environment_map = desc->environment_map; |
15 | } | 14 | } |
@@ -18,9 +17,6 @@ Light* gfx_make_light(const LightDesc* desc) { | |||
18 | assert(desc); | 17 | assert(desc); |
19 | 18 | ||
20 | Light* light = mem_alloc_light(); | 19 | Light* light = mem_alloc_light(); |
21 | if (!light) { | ||
22 | return 0; | ||
23 | } | ||
24 | 20 | ||
25 | switch (desc->type) { | 21 | switch (desc->type) { |
26 | case EnvironmentLightType: | 22 | case EnvironmentLightType: |
@@ -37,9 +33,10 @@ Light* gfx_make_light(const LightDesc* desc) { | |||
37 | 33 | ||
38 | void gfx_destroy_light(Light** light) { | 34 | void gfx_destroy_light(Light** light) { |
39 | assert(light); | 35 | assert(light); |
40 | assert(*light); | 36 | if (*light) { |
41 | if ((*light)->parent.val) { | 37 | if ((*light)->parent.val) { |
42 | gfx_del_node((*light)->parent); | 38 | gfx_del_node((*light)->parent); |
39 | } | ||
40 | mem_free_light(light); | ||
43 | } | 41 | } |
44 | mem_free_light(light); | ||
45 | } | 42 | } |
diff --git a/gfx/src/scene/material.c b/gfx/src/scene/material.c index 6d6decb..b32d791 100644 --- a/gfx/src/scene/material.c +++ b/gfx/src/scene/material.c | |||
@@ -17,9 +17,6 @@ static void material_make(Material* material, const MaterialDesc* desc) { | |||
17 | Material* gfx_make_material(const MaterialDesc* desc) { | 17 | Material* gfx_make_material(const MaterialDesc* desc) { |
18 | assert(desc); | 18 | assert(desc); |
19 | Material* material = mem_alloc_material(); | 19 | Material* material = mem_alloc_material(); |
20 | if (!material) { | ||
21 | return 0; | ||
22 | } | ||
23 | material_make(material, desc); | 20 | material_make(material, desc); |
24 | return material; | 21 | return material; |
25 | } | 22 | } |
diff --git a/gfx/src/scene/mesh.c b/gfx/src/scene/mesh.c index 689105c..1a93bed 100644 --- a/gfx/src/scene/mesh.c +++ b/gfx/src/scene/mesh.c | |||
@@ -17,9 +17,6 @@ static void mesh_make(Mesh* mesh, const MeshDesc* desc) { | |||
17 | 17 | ||
18 | Mesh* gfx_make_mesh(const MeshDesc* desc) { | 18 | Mesh* gfx_make_mesh(const MeshDesc* desc) { |
19 | Mesh* mesh = mem_alloc_mesh(); | 19 | Mesh* mesh = mem_alloc_mesh(); |
20 | if (!mesh) { | ||
21 | return 0; | ||
22 | } | ||
23 | mesh_make(mesh, desc); | 20 | mesh_make(mesh, desc); |
24 | return mesh; | 21 | return mesh; |
25 | } | 22 | } |
diff --git a/gfx/src/scene/node.c b/gfx/src/scene/node.c index 2670680..2f761a2 100644 --- a/gfx/src/scene/node.c +++ b/gfx/src/scene/node.c | |||
@@ -19,9 +19,6 @@ static void scene_node_make(SceneNode* node) { | |||
19 | 19 | ||
20 | SceneNode* gfx_make_node() { | 20 | SceneNode* gfx_make_node() { |
21 | SceneNode* node = mem_alloc_node(); | 21 | SceneNode* node = mem_alloc_node(); |
22 | if (!node) { | ||
23 | return 0; | ||
24 | } | ||
25 | scene_node_make(node); | 22 | scene_node_make(node); |
26 | return node; | 23 | return node; |
27 | } | 24 | } |
@@ -29,60 +26,45 @@ SceneNode* gfx_make_node() { | |||
29 | SceneNode* gfx_make_anima_node(Anima* anima) { | 26 | SceneNode* gfx_make_anima_node(Anima* anima) { |
30 | assert(anima); | 27 | assert(anima); |
31 | SceneNode* node = gfx_make_node(); | 28 | SceneNode* node = gfx_make_node(); |
32 | if (!node) { | 29 | node->type = AnimaNode; |
33 | return 0; | 30 | node->anima = mem_get_anima_index(anima); |
34 | } | 31 | anima->parent = mem_get_node_index(node); |
35 | node->type = AnimaNode; | ||
36 | node->anima = mem_get_anima_index(anima); | ||
37 | anima->parent = mem_get_node_index(node); | ||
38 | return node; | 32 | return node; |
39 | } | 33 | } |
40 | 34 | ||
41 | SceneNode* gfx_make_camera_node(SceneCamera* camera) { | 35 | SceneNode* gfx_make_camera_node(SceneCamera* camera) { |
42 | assert(camera); | 36 | assert(camera); |
43 | SceneNode* node = gfx_make_node(); | 37 | SceneNode* node = gfx_make_node(); |
44 | if (!node) { | 38 | node->type = CameraNode; |
45 | return 0; | 39 | node->camera = mem_get_camera_index(camera); |
46 | } | 40 | camera->parent = mem_get_node_index(node); |
47 | node->type = CameraNode; | ||
48 | node->camera = mem_get_camera_index(camera); | ||
49 | camera->parent = mem_get_node_index(node); | ||
50 | return node; | 41 | return node; |
51 | } | 42 | } |
52 | 43 | ||
53 | SceneNode* gfx_make_joint_node(Joint* joint) { | 44 | SceneNode* gfx_make_joint_node(Joint* joint) { |
54 | assert(joint); | 45 | assert(joint); |
55 | SceneNode* node = gfx_make_node(); | 46 | SceneNode* node = gfx_make_node(); |
56 | if (!node) { | 47 | node->type = JointNode; |
57 | return 0; | 48 | node->joint = mem_get_joint_index(joint); |
58 | } | 49 | joint->parent = mem_get_node_index(node); |
59 | node->type = JointNode; | ||
60 | node->joint = mem_get_joint_index(joint); | ||
61 | joint->parent = mem_get_node_index(node); | ||
62 | return node; | 50 | return node; |
63 | } | 51 | } |
64 | 52 | ||
65 | SceneNode* gfx_make_light_node(Light* light) { | 53 | SceneNode* gfx_make_light_node(Light* light) { |
66 | assert(light); | 54 | assert(light); |
67 | SceneNode* node = gfx_make_node(); | 55 | SceneNode* node = gfx_make_node(); |
68 | if (!node) { | 56 | node->type = LightNode; |
69 | return 0; | 57 | node->light = mem_get_light_index(light); |
70 | } | 58 | light->parent = mem_get_node_index(node); |
71 | node->type = LightNode; | ||
72 | node->light = mem_get_light_index(light); | ||
73 | light->parent = mem_get_node_index(node); | ||
74 | return node; | 59 | return node; |
75 | } | 60 | } |
76 | 61 | ||
77 | SceneNode* gfx_make_object_node(SceneObject* object) { | 62 | SceneNode* gfx_make_object_node(SceneObject* object) { |
78 | assert(object); | 63 | assert(object); |
79 | SceneNode* node = gfx_make_node(); | 64 | SceneNode* node = gfx_make_node(); |
80 | if (!node) { | 65 | node->type = ObjectNode; |
81 | return 0; | 66 | node->object = mem_get_object_index(object); |
82 | } | 67 | object->parent = mem_get_node_index(node); |
83 | node->type = ObjectNode; | ||
84 | node->object = mem_get_object_index(object); | ||
85 | object->parent = mem_get_node_index(node); | ||
86 | return node; | 68 | return node; |
87 | } | 69 | } |
88 | 70 | ||
@@ -131,7 +113,6 @@ static void free_node_resource(SceneNode* node) { | |||
131 | void gfx_construct_anima_node(SceneNode* node, Anima* anima) { | 113 | void gfx_construct_anima_node(SceneNode* node, Anima* anima) { |
132 | assert(node); | 114 | assert(node); |
133 | assert(anima); | 115 | assert(anima); |
134 | |||
135 | free_node_resource(node); | 116 | free_node_resource(node); |
136 | node->type = AnimaNode; | 117 | node->type = AnimaNode; |
137 | node->anima = mem_get_anima_index(anima); | 118 | node->anima = mem_get_anima_index(anima); |
@@ -141,7 +122,6 @@ void gfx_construct_anima_node(SceneNode* node, Anima* anima) { | |||
141 | void gfx_construct_camera_node(SceneNode* node, SceneCamera* camera) { | 122 | void gfx_construct_camera_node(SceneNode* node, SceneCamera* camera) { |
142 | assert(node); | 123 | assert(node); |
143 | assert(camera); | 124 | assert(camera); |
144 | |||
145 | free_node_resource(node); | 125 | free_node_resource(node); |
146 | node->type = CameraNode; | 126 | node->type = CameraNode; |
147 | node->camera = mem_get_camera_index(camera); | 127 | node->camera = mem_get_camera_index(camera); |
@@ -153,7 +133,6 @@ void gfx_construct_camera_node(SceneNode* node, SceneCamera* camera) { | |||
153 | void gfx_construct_joint_node(SceneNode* node, Joint* joint) { | 133 | void gfx_construct_joint_node(SceneNode* node, Joint* joint) { |
154 | assert(node); | 134 | assert(node); |
155 | assert(joint); | 135 | assert(joint); |
156 | |||
157 | free_node_resource(node); | 136 | free_node_resource(node); |
158 | node->type = JointNode; | 137 | node->type = JointNode; |
159 | node->joint = mem_get_joint_index(joint); | 138 | node->joint = mem_get_joint_index(joint); |
@@ -163,7 +142,6 @@ void gfx_construct_joint_node(SceneNode* node, Joint* joint) { | |||
163 | void gfx_construct_light_node(SceneNode* node, Light* light) { | 142 | void gfx_construct_light_node(SceneNode* node, Light* light) { |
164 | assert(node); | 143 | assert(node); |
165 | assert(light); | 144 | assert(light); |
166 | |||
167 | free_node_resource(node); | 145 | free_node_resource(node); |
168 | node->type = LightNode; | 146 | node->type = LightNode; |
169 | node->light = mem_get_light_index(light); | 147 | node->light = mem_get_light_index(light); |
@@ -173,7 +151,6 @@ void gfx_construct_light_node(SceneNode* node, Light* light) { | |||
173 | void gfx_construct_object_node(SceneNode* node, SceneObject* object) { | 151 | void gfx_construct_object_node(SceneNode* node, SceneObject* object) { |
174 | assert(node); | 152 | assert(node); |
175 | assert(object); | 153 | assert(object); |
176 | |||
177 | free_node_resource(node); | 154 | free_node_resource(node); |
178 | node->type = ObjectNode; | 155 | node->type = ObjectNode; |
179 | node->object = mem_get_object_index(object); | 156 | node->object = mem_get_object_index(object); |
@@ -199,20 +176,18 @@ static void destroy_node_rec(SceneNode* node) { | |||
199 | 176 | ||
200 | void gfx_destroy_node(SceneNode** node) { | 177 | void gfx_destroy_node(SceneNode** node) { |
201 | assert(node); | 178 | assert(node); |
202 | assert(*node); | 179 | if (*node) { |
203 | 180 | // Since the node and the whole hierarchy under it gets destroyed, there is | |
204 | // Since the node and the whole hierarchy under it gets destroyed, there is | 181 | // no need to individually detach every node from its hierarchy. We can |
205 | // no need to individually detach every node from its hierarchy. We can simply | 182 | // simply detach the given node and then destroy it and its sub-hierarchy. |
206 | // detach the given node and then destroy it and its sub-hierarchy. | 183 | TREE_REMOVE(*node); |
207 | TREE_REMOVE(*node); | 184 | destroy_node_rec(*node); |
208 | 185 | *node = 0; | |
209 | destroy_node_rec(*node); | 186 | } |
210 | |||
211 | *node = 0; | ||
212 | } | 187 | } |
213 | 188 | ||
214 | // TODO: Think more about ownership of nodes and resources. Should this function | 189 | // TODO: Think more about ownership of nodes and resources. Should this function |
215 | // even exist? | 190 | // even exist? |
216 | void gfx_del_node(node_idx index) { | 191 | void gfx_del_node(node_idx index) { |
217 | assert(index.val); | 192 | assert(index.val); |
218 | SceneNode* node = mem_get_node(index); | 193 | SceneNode* node = mem_get_node(index); |
diff --git a/gfx/src/scene/object.c b/gfx/src/scene/object.c index 64bb5a6..68a1340 100644 --- a/gfx/src/scene/object.c +++ b/gfx/src/scene/object.c | |||
@@ -15,20 +15,18 @@ static void scene_object_make(SceneObject* object) { | |||
15 | 15 | ||
16 | SceneObject* gfx_make_object() { | 16 | SceneObject* gfx_make_object() { |
17 | SceneObject* object = mem_alloc_object(); | 17 | SceneObject* object = mem_alloc_object(); |
18 | if (!object) { | ||
19 | return 0; | ||
20 | } | ||
21 | scene_object_make(object); | 18 | scene_object_make(object); |
22 | return object; | 19 | return object; |
23 | } | 20 | } |
24 | 21 | ||
25 | void gfx_destroy_object(SceneObject** object) { | 22 | void gfx_destroy_object(SceneObject** object) { |
26 | assert(object); | 23 | assert(object); |
27 | assert(*object); | 24 | if (*object) { |
28 | if ((*object)->parent.val) { | 25 | if ((*object)->parent.val) { |
29 | gfx_del_node((*object)->parent); | 26 | gfx_del_node((*object)->parent); |
27 | } | ||
28 | mem_free_object(object); | ||
30 | } | 29 | } |
31 | mem_free_object(object); | ||
32 | } | 30 | } |
33 | 31 | ||
34 | void gfx_set_object_transform(SceneObject* object, const mat4* transform) { | 32 | void gfx_set_object_transform(SceneObject* object, const mat4* transform) { |
@@ -80,8 +78,8 @@ void gfx_set_object_skeleton(SceneObject* object, const Skeleton* skeleton) { | |||
80 | } | 78 | } |
81 | 79 | ||
82 | // TODO: Could compute just once if we changed the Object API to require an | 80 | // TODO: Could compute just once if we changed the Object API to require an |
83 | // object descriptor up front instead of allowing the client to add meshes | 81 | // object descriptor up front instead of allowing the client to add meshes |
84 | // and skeletons dynamically. | 82 | // and skeletons dynamically. |
85 | aabb3 gfx_calc_object_aabb(const SceneObject* object) { | 83 | aabb3 gfx_calc_object_aabb(const SceneObject* object) { |
86 | assert(object); | 84 | assert(object); |
87 | 85 | ||
diff --git a/gfx/src/scene/scene.c b/gfx/src/scene/scene.c index c3dae9c..a6801ba 100644 --- a/gfx/src/scene/scene.c +++ b/gfx/src/scene/scene.c | |||
@@ -7,19 +7,16 @@ | |||
7 | 7 | ||
8 | Scene* gfx_make_scene(void) { | 8 | Scene* gfx_make_scene(void) { |
9 | Scene* scene = mem_alloc_scene(); | 9 | Scene* scene = mem_alloc_scene(); |
10 | if (!scene) { | 10 | scene->root = gfx_make_node(); |
11 | return 0; | ||
12 | } | ||
13 | scene->root = gfx_make_node(); | ||
14 | assert(scene->root); | ||
15 | return scene; | 11 | return scene; |
16 | } | 12 | } |
17 | 13 | ||
18 | void gfx_destroy_scene(Scene** scene) { | 14 | void gfx_destroy_scene(Scene** scene) { |
19 | assert(scene); | 15 | assert(scene); |
20 | assert(*scene); | 16 | if (*scene) { |
21 | gfx_destroy_node(&(*scene)->root); | 17 | gfx_destroy_node(&(*scene)->root); |
22 | mem_free_scene(scene); | 18 | mem_free_scene(scene); |
19 | } | ||
23 | } | 20 | } |
24 | 21 | ||
25 | SceneNode* gfx_get_scene_root(Scene* scene) { | 22 | SceneNode* gfx_get_scene_root(Scene* scene) { |