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