diff options
| author | 3gg <3gg@shellblade.net> | 2023-01-05 09:10:42 -0800 | 
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2023-01-05 09:10:42 -0800 | 
| commit | 47d6a4d1c2973664dc79edd0043fe63dd1e369c6 (patch) | |
| tree | 9f583193edc876dbc44b5293bb6dd965a9e0230a | |
| parent | 134282937e724f33f9cc18731024346373e6c38c (diff) | |
Add ability to set shader compiler defines.
| -rw-r--r-- | gfx/include/gfx/error.h | 20 | ||||
| -rw-r--r-- | gfx/include/gfx/render_backend.h | 94 | ||||
| -rw-r--r-- | gfx/include/gfx/sizes.h | 5 | ||||
| -rw-r--r-- | gfx/src/render/render_backend.c | 89 | ||||
| -rw-r--r-- | gfx/src/render/shader.c | 28 | ||||
| -rw-r--r-- | gltfview/src/main.c | 32 | 
6 files changed, 151 insertions, 117 deletions
| diff --git a/gfx/include/gfx/error.h b/gfx/include/gfx/error.h index b7887bb..dcb6932 100644 --- a/gfx/include/gfx/error.h +++ b/gfx/include/gfx/error.h | |||
| @@ -9,16 +9,16 @@ const char* gfx_get_error(void); | |||
| 9 | extern xlstring gfx_error; | 9 | extern xlstring gfx_error; | 
| 10 | 10 | ||
| 11 | /// Set the last error. | 11 | /// Set the last error. | 
| 12 | #define gfx_set_error(FORMAT, ...) \ | 12 | #define gfx_set_error(FORMAT, ...) \ | 
| 13 | gfx_error.length = snprintf(gfx_error.str, xlstring_size, \ | 13 | gfx_error.length = snprintf( \ | 
| 14 | FORMAT __VA_OPT__(, ) __VA_ARGS__) | 14 | gfx_error.str, xlstring_size, FORMAT __VA_OPT__(, ) __VA_ARGS__) | 
| 15 | 15 | ||
| 16 | /// Prepend an error to the last error. | 16 | /// Prepend an error to the last error. | 
| 17 | #define gfx_prepend_error(FORMAT, ...) \ | 17 | #define gfx_prepend_error(FORMAT, ...) \ | 
| 18 | { \ | 18 | { \ | 
| 19 | xlstring head; \ | 19 | xlstring head; \ | 
| 20 | head.length = \ | 20 | head.length = \ | 
| 21 | snprintf(head.str, xlstring_size, FORMAT __VA_OPT__(, ) __VA_ARGS__); \ | 21 | snprintf(head.str, xlstring_size, FORMAT __VA_OPT__(, ) __VA_ARGS__); \ | 
| 22 | head = xlstring_concat(head, xlstring_make(": ")); \ | 22 | xlstring_append(&head, xlstring_make(": ")); \ | 
| 23 | gfx_error = xlstring_concat(head, gfx_error); \ | 23 | gfx_error = xlstring_concat(head, gfx_error); \ | 
| 24 | } | 24 | } | 
| diff --git a/gfx/include/gfx/render_backend.h b/gfx/include/gfx/render_backend.h index 46c2908..3f2dbd0 100644 --- a/gfx/include/gfx/render_backend.h +++ b/gfx/include/gfx/render_backend.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | /// rendering operations. | 4 | /// rendering operations. | 
| 5 | #pragma once | 5 | #pragma once | 
| 6 | 6 | ||
| 7 | #include "sizes.h" | ||
| 8 | |||
| 7 | #include <math/fwd.h> | 9 | #include <math/fwd.h> | 
| 8 | #include <math/mat4.h> | 10 | #include <math/mat4.h> | 
| 9 | #include <math/vec4.h> | 11 | #include <math/vec4.h> | 
| @@ -14,13 +16,13 @@ | |||
| 14 | #include <stdint.h> | 16 | #include <stdint.h> | 
| 15 | 17 | ||
| 16 | // Implementation objects. | 18 | // Implementation objects. | 
| 17 | typedef struct Buffer Buffer; | 19 | typedef struct Buffer Buffer; | 
| 18 | typedef struct FrameBuffer FrameBuffer; | 20 | typedef struct FrameBuffer FrameBuffer; | 
| 19 | typedef struct Geometry Geometry; | 21 | typedef struct Geometry Geometry; | 
| 20 | typedef struct RenderBuffer RenderBuffer; | 22 | typedef struct RenderBuffer RenderBuffer; | 
| 21 | typedef struct Shader Shader; | 23 | typedef struct Shader Shader; | 
| 22 | typedef struct ShaderProgram ShaderProgram; | 24 | typedef struct ShaderProgram ShaderProgram; | 
| 23 | typedef struct Texture Texture; | 25 | typedef struct Texture Texture; | 
| 24 | typedef struct RenderBackend RenderBackend; | 26 | typedef struct RenderBackend RenderBackend; | 
| 25 | 27 | ||
| 26 | /// Data type for vertex indices. | 28 | /// Data type for vertex indices. | 
| @@ -37,13 +39,13 @@ typedef enum PrimitiveType { | |||
| 37 | 39 | ||
| 38 | /// A buffer view for vertex data (attributes or indices). | 40 | /// A buffer view for vertex data (attributes or indices). | 
| 39 | /// Either 'data' or 'buffer' must be set. | 41 | /// Either 'data' or 'buffer' must be set. | 
| 40 | #define MAKE_BUFFER_VIEW(NAME, TYPE) \ | 42 | #define MAKE_BUFFER_VIEW(NAME, TYPE) \ | 
| 41 | typedef struct NAME { \ | 43 | typedef struct NAME { \ | 
| 42 | const TYPE* data; \ | 44 | const TYPE* data; \ | 
| 43 | const Buffer* buffer; \ | 45 | const Buffer* buffer; \ | 
| 44 | size_t offset_bytes; \ | 46 | size_t offset_bytes; \ | 
| 45 | size_t size_bytes; \ | 47 | size_t size_bytes; \ | 
| 46 | size_t stride_bytes; \ | 48 | size_t stride_bytes; \ | 
| 47 | } NAME; | 49 | } NAME; | 
| 48 | 50 | ||
| 49 | /// A buffer view for 2D vectors. | 51 | /// A buffer view for 2D vectors. | 
| @@ -60,24 +62,32 @@ MAKE_BUFFER_VIEW(BufferViewIdx, uint16_t) | |||
| 60 | 62 | ||
| 61 | /// Describes a piece of geometry. | 63 | /// Describes a piece of geometry. | 
| 62 | typedef struct GeometryDesc { | 64 | typedef struct GeometryDesc { | 
| 63 | BufferView2d positions2d; | 65 | BufferView2d positions2d; | 
| 64 | BufferView3d positions3d; | 66 | BufferView3d positions3d; | 
| 65 | BufferView3d normals; | 67 | BufferView3d normals; | 
| 66 | BufferView4d tangents; | 68 | BufferView4d tangents; | 
| 67 | BufferView2d texcoords; | 69 | BufferView2d texcoords; | 
| 68 | BufferViewIdx indices; | 70 | BufferViewIdx indices; | 
| 69 | VertexCount num_verts; | 71 | VertexCount num_verts; | 
| 70 | size_t num_indices; | 72 | size_t num_indices; | 
| 71 | PrimitiveType type; | 73 | PrimitiveType type; | 
| 72 | } GeometryDesc; | 74 | } GeometryDesc; | 
| 73 | 75 | ||
| 76 | /// Shader compiler define. | ||
| 77 | typedef struct ShaderCompilerDefine { | ||
| 78 | sstring name; | ||
| 79 | sstring value; | ||
| 80 | } ShaderCompilerDefine; | ||
| 81 | |||
| 74 | /// Shader types. | 82 | /// Shader types. | 
| 75 | typedef enum { VertexShader, FragmentShader } ShaderType; | 83 | typedef enum { VertexShader, FragmentShader } ShaderType; | 
| 76 | 84 | ||
| 77 | /// Describes a shader. | 85 | /// Describes a shader. | 
| 78 | typedef struct ShaderDesc { | 86 | typedef struct ShaderDesc { | 
| 79 | const char* code; | 87 | ShaderType type; | 
| 80 | ShaderType type; | 88 | const char* code; | 
| 89 | ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; | ||
| 90 | size_t num_defines; | ||
| 81 | } ShaderDesc; | 91 | } ShaderDesc; | 
| 82 | 92 | ||
| 83 | /// Describes a shader program. | 93 | /// Describes a shader program. | 
| @@ -97,14 +107,14 @@ typedef enum { | |||
| 97 | 107 | ||
| 98 | /// Shader uniform. | 108 | /// Shader uniform. | 
| 99 | typedef struct ShaderUniform { | 109 | typedef struct ShaderUniform { | 
| 100 | sstring name; | 110 | sstring name; | 
| 101 | UniformType type; | 111 | UniformType type; | 
| 102 | union { | 112 | union { | 
| 103 | const Texture* texture; | 113 | const Texture* texture; | 
| 104 | mat4 mat4; | 114 | mat4 mat4; | 
| 105 | vec3 vec3; | 115 | vec3 vec3; | 
| 106 | vec4 vec4; | 116 | vec4 vec4; | 
| 107 | float scalar; | 117 | float scalar; | 
| 108 | } value; | 118 | } value; | 
| 109 | } ShaderUniform; | 119 | } ShaderUniform; | 
| 110 | 120 | ||
| @@ -135,14 +145,14 @@ typedef enum { | |||
| 135 | 145 | ||
| 136 | /// Describes a texture. | 146 | /// Describes a texture. | 
| 137 | typedef struct TextureDesc { | 147 | typedef struct TextureDesc { | 
| 138 | int width; | 148 | int width; | 
| 139 | int height; | 149 | int height; | 
| 140 | int depth; // Not used until 3D textures are exposed. | 150 | int depth; // Not used until 3D textures are exposed. | 
| 141 | TextureDimension dimension; | 151 | TextureDimension dimension; | 
| 142 | TextureFormat format; | 152 | TextureFormat format; | 
| 143 | TextureFiltering filtering; | 153 | TextureFiltering filtering; | 
| 144 | TextureWrapping wrap; | 154 | TextureWrapping wrap; | 
| 145 | bool mipmaps; | 155 | bool mipmaps; | 
| 146 | union { | 156 | union { | 
| 147 | const void* pixels; | 157 | const void* pixels; | 
| 148 | struct { | 158 | struct { | 
| @@ -158,8 +168,8 @@ typedef struct TextureDesc { | |||
| 158 | 168 | ||
| 159 | /// Describes a renderbuffer. | 169 | /// Describes a renderbuffer. | 
| 160 | typedef struct RenderBufferDesc { | 170 | typedef struct RenderBufferDesc { | 
| 161 | int width; | 171 | int width; | 
| 162 | int height; | 172 | int height; | 
| 163 | TextureFormat texture_format; | 173 | TextureFormat texture_format; | 
| 164 | } RenderBufferDesc; | 174 | } RenderBufferDesc; | 
| 165 | 175 | ||
| @@ -177,11 +187,11 @@ typedef struct FrameBufferAttachment { | |||
| 177 | union { | 187 | union { | 
| 178 | struct { | 188 | struct { | 
| 179 | Texture* texture; | 189 | Texture* texture; | 
| 180 | int mip_level; | 190 | int mip_level; | 
| 181 | } texture; | 191 | } texture; | 
| 182 | struct { | 192 | struct { | 
| 183 | Texture* texture; | 193 | Texture* texture; | 
| 184 | int mip_level; | 194 | int mip_level; | 
| 185 | CubemapFace face; | 195 | CubemapFace face; | 
| 186 | } cubemap; | 196 | } cubemap; | 
| 187 | RenderBuffer* renderbuffer; | 197 | RenderBuffer* renderbuffer; | 
| @@ -288,8 +298,8 @@ void gfx_deactivate_framebuffer(const FrameBuffer*); | |||
| 288 | 298 | ||
| 289 | /// Set the framebuffer's viewport. | 299 | /// Set the framebuffer's viewport. | 
| 290 | /// This function should be called every time the framebuffer is activated. | 300 | /// This function should be called every time the framebuffer is activated. | 
| 291 | void gfx_framebuffer_set_viewport(FrameBuffer*, int x, int y, int width, | 301 | void gfx_framebuffer_set_viewport( | 
| 292 | int height); | 302 | FrameBuffer*, int x, int y, int width, int height); | 
| 293 | 303 | ||
| 294 | // ----------------------------------------------------------------------------- | 304 | // ----------------------------------------------------------------------------- | 
| 295 | // Shaders. | 305 | // Shaders. | 
| @@ -302,8 +312,8 @@ Shader* gfx_make_shader(RenderBackend*, const ShaderDesc*); | |||
| 302 | void gfx_destroy_shader(RenderBackend*, Shader**); | 312 | void gfx_destroy_shader(RenderBackend*, Shader**); | 
| 303 | 313 | ||
| 304 | /// Create a shader program. | 314 | /// Create a shader program. | 
| 305 | ShaderProgram* gfx_make_shader_program(RenderBackend*, | 315 | ShaderProgram* gfx_make_shader_program( | 
| 306 | const ShaderProgramDesc*); | 316 | RenderBackend*, const ShaderProgramDesc*); | 
| 307 | 317 | ||
| 308 | /// Destroy the shader program. | 318 | /// Destroy the shader program. | 
| 309 | void gfx_destroy_shader_program(RenderBackend*, ShaderProgram**); | 319 | void gfx_destroy_shader_program(RenderBackend*, ShaderProgram**); | 
| diff --git a/gfx/include/gfx/sizes.h b/gfx/include/gfx/sizes.h index 7681e1f..2ed25b4 100644 --- a/gfx/include/gfx/sizes.h +++ b/gfx/include/gfx/sizes.h | |||
| @@ -51,7 +51,10 @@ | |||
| 51 | #define GFX_MAX_NUM_TEXTURES 1024 | 51 | #define GFX_MAX_NUM_TEXTURES 1024 | 
| 52 | 52 | ||
| 53 | /// Maximum number of uniforms in a ShaderProgram. | 53 | /// Maximum number of uniforms in a ShaderProgram. | 
| 54 | #define GFX_MAX_UNIFORMS_PER_SHADER 16 | 54 | #define GFX_MAX_UNIFORMS_PER_SHADER (GFX_MAX_UNIFORMS_PER_MATERIAL + 8) | 
| 55 | |||
| 56 | /// Maximum number of compiler defines in a Shader. | ||
| 57 | #define GFX_MAX_SHADER_COMPILER_DEFINES 16 | ||
| 55 | 58 | ||
| 56 | // Gfx | 59 | // Gfx | 
| 57 | 60 | ||
| diff --git a/gfx/src/render/render_backend.c b/gfx/src/render/render_backend.c index c79de7d..b3dc805 100644 --- a/gfx/src/render/render_backend.c +++ b/gfx/src/render/render_backend.c | |||
| @@ -33,26 +33,29 @@ void gfx_init_render_backend(RenderBackend* render_backend) { | |||
| 33 | void gfx_del_render_backend(RenderBackend* render_backend) { | 33 | void gfx_del_render_backend(RenderBackend* render_backend) { | 
| 34 | assert(render_backend); | 34 | assert(render_backend); | 
| 35 | 35 | ||
| 36 | mempool_foreach(&render_backend->buffers, buffer, | 36 | mempool_foreach( | 
| 37 | { gfx_del_buffer(buffer); }); | 37 | &render_backend->buffers, buffer, { gfx_del_buffer(buffer); }); | 
| 38 | 38 | ||
| 39 | mempool_foreach(&render_backend->framebuffers, framebuffer, | 39 | mempool_foreach(&render_backend->framebuffers, framebuffer, { | 
| 40 | { gfx_del_framebuffer(framebuffer); }); | 40 | gfx_del_framebuffer(framebuffer); | 
| 41 | }); | ||
| 41 | 42 | ||
| 42 | mempool_foreach(&render_backend->geometries, geometry, | 43 | mempool_foreach( | 
| 43 | { gfx_del_geometry(geometry); }); | 44 | &render_backend->geometries, geometry, { gfx_del_geometry(geometry); }); | 
| 44 | 45 | ||
| 45 | mempool_foreach(&render_backend->renderbuffers, renderbuffer, | 46 | mempool_foreach(&render_backend->renderbuffers, renderbuffer, { | 
| 46 | { gfx_del_renderbuffer(renderbuffer); }); | 47 | gfx_del_renderbuffer(renderbuffer); | 
| 48 | }); | ||
| 47 | 49 | ||
| 48 | mempool_foreach(&render_backend->shader_programs, prog, | 50 | mempool_foreach(&render_backend->shader_programs, prog, { | 
| 49 | { gfx_del_shader_program(prog); }); | 51 | gfx_del_shader_program(prog); | 
| 52 | }); | ||
| 50 | 53 | ||
| 51 | mempool_foreach(&render_backend->shaders, shader, | 54 | mempool_foreach( | 
| 52 | { gfx_del_shader(shader); }); | 55 | &render_backend->shaders, shader, { gfx_del_shader(shader); }); | 
| 53 | 56 | ||
| 54 | mempool_foreach(&render_backend->textures, texture, | 57 | mempool_foreach( | 
| 55 | { gfx_del_texture(texture); }); | 58 | &render_backend->textures, texture, { gfx_del_texture(texture); }); | 
| 56 | } | 59 | } | 
| 57 | 60 | ||
| 58 | // ----------------------------------------------------------------------------- | 61 | // ----------------------------------------------------------------------------- | 
| @@ -62,8 +65,8 @@ void gfx_del_render_backend(RenderBackend* render_backend) { | |||
| 62 | void gfx_start_frame(RenderBackend* render_backend) { | 65 | void gfx_start_frame(RenderBackend* render_backend) { | 
| 63 | assert(render_backend); | 66 | assert(render_backend); | 
| 64 | 67 | ||
| 65 | glViewport(0, 0, render_backend->viewport.width, | 68 | glViewport( | 
| 66 | render_backend->viewport.height); | 69 | 0, 0, render_backend->viewport.width, render_backend->viewport.height); | 
| 67 | glClearColor(0, 0, 0, 0); | 70 | glClearColor(0, 0, 0, 0); | 
| 68 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 71 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 
| 69 | 72 | ||
| @@ -77,7 +80,7 @@ void gfx_end_frame(RenderBackend* render_backend) { | |||
| 77 | 80 | ||
| 78 | void gfx_set_viewport(RenderBackend* render_backend, int width, int height) { | 81 | void gfx_set_viewport(RenderBackend* render_backend, int width, int height) { | 
| 79 | assert(render_backend); | 82 | assert(render_backend); | 
| 80 | render_backend->viewport.width = width; | 83 | render_backend->viewport.width = width; | 
| 81 | render_backend->viewport.height = height; | 84 | render_backend->viewport.height = height; | 
| 82 | } | 85 | } | 
| 83 | 86 | ||
| @@ -85,7 +88,7 @@ void gfx_get_viewport(RenderBackend* render_backend, int* width, int* height) { | |||
| 85 | assert(render_backend); | 88 | assert(render_backend); | 
| 86 | assert(width); | 89 | assert(width); | 
| 87 | assert(height); | 90 | assert(height); | 
| 88 | *width = render_backend->viewport.width; | 91 | *width = render_backend->viewport.width; | 
| 89 | *height = render_backend->viewport.height; | 92 | *height = render_backend->viewport.height; | 
| 90 | } | 93 | } | 
| 91 | 94 | ||
| @@ -93,8 +96,8 @@ void gfx_get_viewport(RenderBackend* render_backend, int* width, int* height) { | |||
| 93 | // Buffers. | 96 | // Buffers. | 
| 94 | // ----------------------------------------------------------------------------- | 97 | // ----------------------------------------------------------------------------- | 
| 95 | 98 | ||
| 96 | Buffer* gfx_make_buffer(RenderBackend* render_backend, const void* data, | 99 | Buffer* gfx_make_buffer( | 
| 97 | size_t size_bytes) { | 100 | RenderBackend* render_backend, const void* data, size_t size_bytes) { | 
| 98 | assert(render_backend); | 101 | assert(render_backend); | 
| 99 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 102 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 
| 100 | if (!buffer) { | 103 | if (!buffer) { | 
| @@ -107,8 +110,8 @@ Buffer* gfx_make_buffer(RenderBackend* render_backend, const void* data, | |||
| 107 | return buffer; | 110 | return buffer; | 
| 108 | } | 111 | } | 
| 109 | 112 | ||
| 110 | Buffer* gfx_make_buffer2d(RenderBackend* render_backend, const vec2* verts, | 113 | Buffer* gfx_make_buffer2d( | 
| 111 | size_t count) { | 114 | RenderBackend* render_backend, const vec2* verts, size_t count) { | 
| 112 | assert(render_backend); | 115 | assert(render_backend); | 
| 113 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 116 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 
| 114 | if (!buffer) { | 117 | if (!buffer) { | 
| @@ -121,8 +124,8 @@ Buffer* gfx_make_buffer2d(RenderBackend* render_backend, const vec2* verts, | |||
| 121 | return buffer; | 124 | return buffer; | 
| 122 | } | 125 | } | 
| 123 | 126 | ||
| 124 | Buffer* gfx_make_buffer3d(RenderBackend* render_backend, const vec3* verts, | 127 | Buffer* gfx_make_buffer3d( | 
| 125 | size_t count) { | 128 | RenderBackend* render_backend, const vec3* verts, size_t count) { | 
| 126 | assert(render_backend); | 129 | assert(render_backend); | 
| 127 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 130 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 
| 128 | if (!buffer) { | 131 | if (!buffer) { | 
| @@ -135,8 +138,8 @@ Buffer* gfx_make_buffer3d(RenderBackend* render_backend, const vec3* verts, | |||
| 135 | return buffer; | 138 | return buffer; | 
| 136 | } | 139 | } | 
| 137 | 140 | ||
| 138 | Buffer* gfx_make_buffer4d(RenderBackend* render_backend, const vec4* verts, | 141 | Buffer* gfx_make_buffer4d( | 
| 139 | size_t count) { | 142 | RenderBackend* render_backend, const vec4* verts, size_t count) { | 
| 140 | assert(render_backend); | 143 | assert(render_backend); | 
| 141 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 144 | Buffer* buffer = mempool_alloc(&render_backend->buffers); | 
| 142 | if (!buffer) { | 145 | if (!buffer) { | 
| @@ -160,8 +163,8 @@ void gfx_destroy_buffer(RenderBackend* render_backend, Buffer** buffer) { | |||
| 160 | // Geometry. | 163 | // Geometry. | 
| 161 | // ----------------------------------------------------------------------------- | 164 | // ----------------------------------------------------------------------------- | 
| 162 | 165 | ||
| 163 | Geometry* gfx_make_geometry(RenderBackend* render_backend, | 166 | Geometry* gfx_make_geometry( | 
| 164 | const GeometryDesc* desc) { | 167 | RenderBackend* render_backend, const GeometryDesc* desc) { | 
| 165 | assert(render_backend); | 168 | assert(render_backend); | 
| 166 | assert(desc); | 169 | assert(desc); | 
| 167 | Geometry* geometry = mempool_alloc(&render_backend->geometries); | 170 | Geometry* geometry = mempool_alloc(&render_backend->geometries); | 
| @@ -186,8 +189,8 @@ void gfx_destroy_geometry(RenderBackend* render_backend, Geometry** geometry) { | |||
| 186 | // Textures. | 189 | // Textures. | 
| 187 | // ----------------------------------------------------------------------------- | 190 | // ----------------------------------------------------------------------------- | 
| 188 | 191 | ||
| 189 | Texture* gfx_make_texture(RenderBackend* render_backend, | 192 | Texture* gfx_make_texture( | 
| 190 | const TextureDesc* desc) { | 193 | RenderBackend* render_backend, const TextureDesc* desc) { | 
| 191 | assert(render_backend); | 194 | assert(render_backend); | 
| 192 | assert(desc); | 195 | assert(desc); | 
| 193 | Texture* texture = mempool_alloc(&render_backend->textures); | 196 | Texture* texture = mempool_alloc(&render_backend->textures); | 
| @@ -213,8 +216,8 @@ void gfx_destroy_texture(RenderBackend* render_backend, Texture** texture) { | |||
| 213 | // Renderbuffers. | 216 | // Renderbuffers. | 
| 214 | // ----------------------------------------------------------------------------- | 217 | // ----------------------------------------------------------------------------- | 
| 215 | 218 | ||
| 216 | RenderBuffer* gfx_make_renderbuffer(RenderBackend* render_backend, | 219 | RenderBuffer* gfx_make_renderbuffer( | 
| 217 | const RenderBufferDesc* desc) { | 220 | RenderBackend* render_backend, const RenderBufferDesc* desc) { | 
| 218 | assert(render_backend); | 221 | assert(render_backend); | 
| 219 | assert(desc); | 222 | assert(desc); | 
| 220 | RenderBuffer* renderbuffer = mempool_alloc(&render_backend->renderbuffers); | 223 | RenderBuffer* renderbuffer = mempool_alloc(&render_backend->renderbuffers); | 
| @@ -227,8 +230,8 @@ RenderBuffer* gfx_make_renderbuffer(RenderBackend* render_backend, | |||
| 227 | return renderbuffer; | 230 | return renderbuffer; | 
| 228 | } | 231 | } | 
| 229 | 232 | ||
| 230 | void gfx_destroy_renderbuffer(RenderBackend* render_backend, | 233 | void gfx_destroy_renderbuffer( | 
| 231 | RenderBuffer** renderbuffer) { | 234 | RenderBackend* render_backend, RenderBuffer** renderbuffer) { | 
| 232 | assert(render_backend); | 235 | assert(render_backend); | 
| 233 | assert(renderbuffer); | 236 | assert(renderbuffer); | 
| 234 | assert(*renderbuffer); | 237 | assert(*renderbuffer); | 
| @@ -240,8 +243,8 @@ void gfx_destroy_renderbuffer(RenderBackend* render_backend, | |||
| 240 | // Framebuffers. | 243 | // Framebuffers. | 
| 241 | // ----------------------------------------------------------------------------- | 244 | // ----------------------------------------------------------------------------- | 
| 242 | 245 | ||
| 243 | FrameBuffer* gfx_make_framebuffer(RenderBackend* render_backend, | 246 | FrameBuffer* gfx_make_framebuffer( | 
| 244 | const FrameBufferDesc* desc) { | 247 | RenderBackend* render_backend, const FrameBufferDesc* desc) { | 
| 245 | assert(render_backend); | 248 | assert(render_backend); | 
| 246 | assert(desc); | 249 | assert(desc); | 
| 247 | FrameBuffer* framebuffer = mempool_alloc(&render_backend->framebuffers); | 250 | FrameBuffer* framebuffer = mempool_alloc(&render_backend->framebuffers); | 
| @@ -255,8 +258,8 @@ FrameBuffer* gfx_make_framebuffer(RenderBackend* render_backend, | |||
| 255 | return framebuffer; | 258 | return framebuffer; | 
| 256 | } | 259 | } | 
| 257 | 260 | ||
| 258 | void gfx_destroy_framebuffer(RenderBackend* render_backend, | 261 | void gfx_destroy_framebuffer( | 
| 259 | FrameBuffer** framebuffer) { | 262 | RenderBackend* render_backend, FrameBuffer** framebuffer) { | 
| 260 | assert(render_backend); | 263 | assert(render_backend); | 
| 261 | assert(framebuffer); | 264 | assert(framebuffer); | 
| 262 | assert(*framebuffer); | 265 | assert(*framebuffer); | 
| @@ -264,8 +267,6 @@ void gfx_destroy_framebuffer(RenderBackend* render_backend, | |||
| 264 | mempool_free(&render_backend->framebuffers, framebuffer); | 267 | mempool_free(&render_backend->framebuffers, framebuffer); | 
| 265 | } | 268 | } | 
| 266 | 269 | ||
| 267 | void gfx_activate_framebuffer(const FrameBuffer* framebuffer); | ||
| 268 | |||
| 269 | // ----------------------------------------------------------------------------- | 270 | // ----------------------------------------------------------------------------- | 
| 270 | // Shaders. | 271 | // Shaders. | 
| 271 | // ----------------------------------------------------------------------------- | 272 | // ----------------------------------------------------------------------------- | 
| @@ -292,8 +293,8 @@ void gfx_destroy_shader(RenderBackend* render_backend, Shader** shader) { | |||
| 292 | mempool_free(&render_backend->shaders, shader); | 293 | mempool_free(&render_backend->shaders, shader); | 
| 293 | } | 294 | } | 
| 294 | 295 | ||
| 295 | ShaderProgram* gfx_make_shader_program(RenderBackend* render_backend, | 296 | ShaderProgram* gfx_make_shader_program( | 
| 296 | const ShaderProgramDesc* desc) { | 297 | RenderBackend* render_backend, const ShaderProgramDesc* desc) { | 
| 297 | assert(render_backend); | 298 | assert(render_backend); | 
| 298 | assert(desc); | 299 | assert(desc); | 
| 299 | ShaderProgram* prog = mempool_alloc(&render_backend->shader_programs); | 300 | ShaderProgram* prog = mempool_alloc(&render_backend->shader_programs); | 
| @@ -307,8 +308,8 @@ ShaderProgram* gfx_make_shader_program(RenderBackend* render_backend, | |||
| 307 | return prog; | 308 | return prog; | 
| 308 | } | 309 | } | 
| 309 | 310 | ||
| 310 | void gfx_destroy_shader_program(RenderBackend* render_backend, | 311 | void gfx_destroy_shader_program( | 
| 311 | ShaderProgram** prog) { | 312 | RenderBackend* render_backend, ShaderProgram** prog) { | 
| 312 | assert(render_backend); | 313 | assert(render_backend); | 
| 313 | assert(prog); | 314 | assert(prog); | 
| 314 | assert(*prog); | 315 | assert(*prog); | 
| diff --git a/gfx/src/render/shader.c b/gfx/src/render/shader.c index 73bc86c..c8e02fd 100644 --- a/gfx/src/render/shader.c +++ b/gfx/src/render/shader.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | #include "gl_util.h" | 3 | #include "gl_util.h" | 
| 4 | 4 | ||
| 5 | #include <cstring.h> | ||
| 5 | #include <log/log.h> | 6 | #include <log/log.h> | 
| 6 | 7 | ||
| 7 | #include <assert.h> | 8 | #include <assert.h> | 
| @@ -20,6 +21,19 @@ static GLenum shader_type_to_gl(ShaderType type) { | |||
| 20 | } | 21 | } | 
| 21 | } | 22 | } | 
| 22 | 23 | ||
| 24 | static lstring make_defines_string(const ShaderDesc* desc) { | ||
| 25 | lstring defines = {0}; | ||
| 26 | for (size_t i = 0; i < desc->num_defines; ++i) { | ||
| 27 | const ShaderCompilerDefine* define = &desc->defines[i]; | ||
| 28 | lstring_append_cstr(&defines, "#define "); | ||
| 29 | lstring_append_cstr(&defines, sstring_cstring(&define->name)); | ||
| 30 | lstring_append_cstr(&defines, " "); | ||
| 31 | lstring_append_cstr(&defines, sstring_cstring(&define->value)); | ||
| 32 | lstring_append_cstr(&defines, "\n"); | ||
| 33 | } | ||
| 34 | return defines; | ||
| 35 | } | ||
| 36 | |||
| 23 | /// Creates an OpenGL shader. | 37 | /// Creates an OpenGL shader. | 
| 24 | /// Returns non-zero on success, 0 on failure. | 38 | /// Returns non-zero on success, 0 on failure. | 
| 25 | static GLuint create_shader(const ShaderDesc* desc) { | 39 | static GLuint create_shader(const ShaderDesc* desc) { | 
| @@ -34,10 +48,13 @@ static GLuint create_shader(const ShaderDesc* desc) { | |||
| 34 | const char* header = "#version 400 core\n\n"; | 48 | const char* header = "#version 400 core\n\n"; | 
| 35 | #endif | 49 | #endif | 
| 36 | 50 | ||
| 37 | const char* source_bits[] = {header, desc->code}; | 51 | lstring defines = make_defines_string(desc); | 
| 38 | const GLint source_lengths[] = {strlen(header), strlen(desc->code)}; | 52 | |
| 53 | const char* source_bits[] = {header, lstring_cstring(&defines), desc->code}; | ||
| 54 | const GLint source_lengths[] = { | ||
| 55 | strlen(header), lstring_length(defines), strlen(desc->code)}; | ||
| 39 | 56 | ||
| 40 | glShaderSource(shader, 2, source_bits, source_lengths); | 57 | glShaderSource(shader, 3, source_bits, source_lengths); | 
| 41 | glCompileShader(shader); | 58 | glCompileShader(shader); | 
| 42 | GLint result; | 59 | GLint result; | 
| 43 | glGetShaderiv(shader, GL_COMPILE_STATUS, &result); | 60 | glGetShaderiv(shader, GL_COMPILE_STATUS, &result); | 
| @@ -47,10 +64,11 @@ static GLuint create_shader(const ShaderDesc* desc) { | |||
| 47 | if (log_len > 0) { | 64 | if (log_len > 0) { | 
| 48 | char* log = calloc(log_len, sizeof(char)); | 65 | char* log = calloc(log_len, sizeof(char)); | 
| 49 | glGetShaderInfoLog(shader, log_len, NULL, log); | 66 | glGetShaderInfoLog(shader, log_len, NULL, log); | 
| 50 | LOGE("Failed loading shader: %s\n\nShader code: %s", log, desc->code); | 67 | static const char* sep = "----------"; | 
| 68 | LOGE("Failed loading shader: %s\n%s\n%s\n%s", log, sep, desc->code, sep); | ||
| 51 | free(log); | 69 | free(log); | 
| 52 | } else { | 70 | } else { | 
| 53 | LOGE("Failed loading shader: %s", desc->code); | 71 | LOGE("Failed loading shader:\n%s", desc->code); | 
| 54 | } | 72 | } | 
| 55 | glDeleteShader(shader); | 73 | glDeleteShader(shader); | 
| 56 | return 0; | 74 | return 0; | 
| diff --git a/gltfview/src/main.c b/gltfview/src/main.c index f7c372c..f4863b4 100644 --- a/gltfview/src/main.c +++ b/gltfview/src/main.c | |||
| @@ -12,7 +12,7 @@ static bool init(const GfxAppDesc* desc, void** app_state) { | |||
| 12 | return false; | 12 | return false; | 
| 13 | } | 13 | } | 
| 14 | if (!game_new(game, desc->argc, desc->argv)) { | 14 | if (!game_new(game, desc->argc, desc->argv)) { | 
| 15 | LOGE("Failed to initialize game\n"); | 15 | LOGE("Failed to initialize game"); | 
| 16 | return false; | 16 | return false; | 
| 17 | } | 17 | } | 
| 18 | *app_state = game; | 18 | *app_state = game; | 
| @@ -44,22 +44,24 @@ static void resize(void* app_state, int width, int height) { | |||
| 44 | } | 44 | } | 
| 45 | 45 | ||
| 46 | int main(int argc, const char** argv) { | 46 | int main(int argc, const char** argv) { | 
| 47 | const int initial_width = 1350; | 47 | const int initial_width = 1350; | 
| 48 | const int initial_height = 900; | 48 | const int initial_height = 900; | 
| 49 | const int max_fps = 60; | 49 | const int max_fps = 60; | 
| 50 | 50 | ||
| 51 | gfx_app_run(&(GfxAppDesc){.argc = argc, | 51 | gfx_app_run( | 
| 52 | .argv = argv, | 52 | &(GfxAppDesc){ | 
| 53 | .width = initial_width, | 53 | .argc = argc, | 
| 54 | .height = initial_height, | 54 | .argv = argv, | 
| 55 | .max_fps = max_fps, | 55 | .width = initial_width, | 
| 56 | .update_delta_time = | 56 | .height = initial_height, | 
| 57 | max_fps > 0 ? 1.0 / (double)max_fps : 0.0}, | 57 | .max_fps = max_fps, | 
| 58 | &(GfxAppCallbacks){.init = init, | 58 | .update_delta_time = max_fps > 0 ? 1.0 / (double)max_fps : 0.0}, | 
| 59 | .update = update, | 59 | &(GfxAppCallbacks){ | 
| 60 | .render = render, | 60 | .init = init, | 
| 61 | .resize = resize, | 61 | .update = update, | 
| 62 | .shutdown = shutdown}); | 62 | .render = render, | 
| 63 | .resize = resize, | ||
| 64 | .shutdown = shutdown}); | ||
| 63 | 65 | ||
| 64 | return 0; | 66 | return 0; | 
| 65 | } | 67 | } | 
