From 47d6a4d1c2973664dc79edd0043fe63dd1e369c6 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Thu, 5 Jan 2023 09:10:42 -0800 Subject: Add ability to set shader compiler defines. --- gfx/include/gfx/error.h | 20 ++++----- gfx/include/gfx/render_backend.h | 94 ++++++++++++++++++++++------------------ gfx/include/gfx/sizes.h | 5 ++- gfx/src/render/render_backend.c | 89 ++++++++++++++++++------------------- gfx/src/render/shader.c | 28 +++++++++--- 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); extern xlstring gfx_error; /// Set the last error. -#define gfx_set_error(FORMAT, ...) \ - gfx_error.length = snprintf(gfx_error.str, xlstring_size, \ - FORMAT __VA_OPT__(, ) __VA_ARGS__) +#define gfx_set_error(FORMAT, ...) \ + gfx_error.length = snprintf( \ + gfx_error.str, xlstring_size, FORMAT __VA_OPT__(, ) __VA_ARGS__) /// Prepend an error to the last error. -#define gfx_prepend_error(FORMAT, ...) \ - { \ - xlstring head; \ - head.length = \ - snprintf(head.str, xlstring_size, FORMAT __VA_OPT__(, ) __VA_ARGS__); \ - head = xlstring_concat(head, xlstring_make(": ")); \ - gfx_error = xlstring_concat(head, gfx_error); \ +#define gfx_prepend_error(FORMAT, ...) \ + { \ + xlstring head; \ + head.length = \ + snprintf(head.str, xlstring_size, FORMAT __VA_OPT__(, ) __VA_ARGS__); \ + xlstring_append(&head, xlstring_make(": ")); \ + gfx_error = xlstring_concat(head, gfx_error); \ } 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 @@ /// rendering operations. #pragma once +#include "sizes.h" + #include #include #include @@ -14,13 +16,13 @@ #include // Implementation objects. -typedef struct Buffer Buffer; -typedef struct FrameBuffer FrameBuffer; -typedef struct Geometry Geometry; -typedef struct RenderBuffer RenderBuffer; -typedef struct Shader Shader; +typedef struct Buffer Buffer; +typedef struct FrameBuffer FrameBuffer; +typedef struct Geometry Geometry; +typedef struct RenderBuffer RenderBuffer; +typedef struct Shader Shader; typedef struct ShaderProgram ShaderProgram; -typedef struct Texture Texture; +typedef struct Texture Texture; typedef struct RenderBackend RenderBackend; /// Data type for vertex indices. @@ -37,13 +39,13 @@ typedef enum PrimitiveType { /// A buffer view for vertex data (attributes or indices). /// Either 'data' or 'buffer' must be set. -#define MAKE_BUFFER_VIEW(NAME, TYPE) \ - typedef struct NAME { \ - const TYPE* data; \ - const Buffer* buffer; \ - size_t offset_bytes; \ - size_t size_bytes; \ - size_t stride_bytes; \ +#define MAKE_BUFFER_VIEW(NAME, TYPE) \ + typedef struct NAME { \ + const TYPE* data; \ + const Buffer* buffer; \ + size_t offset_bytes; \ + size_t size_bytes; \ + size_t stride_bytes; \ } NAME; /// A buffer view for 2D vectors. @@ -60,24 +62,32 @@ MAKE_BUFFER_VIEW(BufferViewIdx, uint16_t) /// Describes a piece of geometry. typedef struct GeometryDesc { - BufferView2d positions2d; - BufferView3d positions3d; - BufferView3d normals; - BufferView4d tangents; - BufferView2d texcoords; + BufferView2d positions2d; + BufferView3d positions3d; + BufferView3d normals; + BufferView4d tangents; + BufferView2d texcoords; BufferViewIdx indices; - VertexCount num_verts; - size_t num_indices; + VertexCount num_verts; + size_t num_indices; PrimitiveType type; } GeometryDesc; +/// Shader compiler define. +typedef struct ShaderCompilerDefine { + sstring name; + sstring value; +} ShaderCompilerDefine; + /// Shader types. typedef enum { VertexShader, FragmentShader } ShaderType; /// Describes a shader. typedef struct ShaderDesc { - const char* code; - ShaderType type; + ShaderType type; + const char* code; + ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; + size_t num_defines; } ShaderDesc; /// Describes a shader program. @@ -97,14 +107,14 @@ typedef enum { /// Shader uniform. typedef struct ShaderUniform { - sstring name; + sstring name; UniformType type; union { const Texture* texture; - mat4 mat4; - vec3 vec3; - vec4 vec4; - float scalar; + mat4 mat4; + vec3 vec3; + vec4 vec4; + float scalar; } value; } ShaderUniform; @@ -135,14 +145,14 @@ typedef enum { /// Describes a texture. typedef struct TextureDesc { - int width; - int height; - int depth; // Not used until 3D textures are exposed. + int width; + int height; + int depth; // Not used until 3D textures are exposed. TextureDimension dimension; - TextureFormat format; + TextureFormat format; TextureFiltering filtering; - TextureWrapping wrap; - bool mipmaps; + TextureWrapping wrap; + bool mipmaps; union { const void* pixels; struct { @@ -158,8 +168,8 @@ typedef struct TextureDesc { /// Describes a renderbuffer. typedef struct RenderBufferDesc { - int width; - int height; + int width; + int height; TextureFormat texture_format; } RenderBufferDesc; @@ -177,11 +187,11 @@ typedef struct FrameBufferAttachment { union { struct { Texture* texture; - int mip_level; + int mip_level; } texture; struct { - Texture* texture; - int mip_level; + Texture* texture; + int mip_level; CubemapFace face; } cubemap; RenderBuffer* renderbuffer; @@ -288,8 +298,8 @@ void gfx_deactivate_framebuffer(const FrameBuffer*); /// Set the framebuffer's viewport. /// This function should be called every time the framebuffer is activated. -void gfx_framebuffer_set_viewport(FrameBuffer*, int x, int y, int width, - int height); +void gfx_framebuffer_set_viewport( + FrameBuffer*, int x, int y, int width, int height); // ----------------------------------------------------------------------------- // Shaders. @@ -302,8 +312,8 @@ Shader* gfx_make_shader(RenderBackend*, const ShaderDesc*); void gfx_destroy_shader(RenderBackend*, Shader**); /// Create a shader program. -ShaderProgram* gfx_make_shader_program(RenderBackend*, - const ShaderProgramDesc*); +ShaderProgram* gfx_make_shader_program( + RenderBackend*, const ShaderProgramDesc*); /// Destroy the shader program. 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 @@ #define GFX_MAX_NUM_TEXTURES 1024 /// Maximum number of uniforms in a ShaderProgram. -#define GFX_MAX_UNIFORMS_PER_SHADER 16 +#define GFX_MAX_UNIFORMS_PER_SHADER (GFX_MAX_UNIFORMS_PER_MATERIAL + 8) + +/// Maximum number of compiler defines in a Shader. +#define GFX_MAX_SHADER_COMPILER_DEFINES 16 // Gfx 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) { void gfx_del_render_backend(RenderBackend* render_backend) { assert(render_backend); - mempool_foreach(&render_backend->buffers, buffer, - { gfx_del_buffer(buffer); }); + mempool_foreach( + &render_backend->buffers, buffer, { gfx_del_buffer(buffer); }); - mempool_foreach(&render_backend->framebuffers, framebuffer, - { gfx_del_framebuffer(framebuffer); }); + mempool_foreach(&render_backend->framebuffers, framebuffer, { + gfx_del_framebuffer(framebuffer); + }); - mempool_foreach(&render_backend->geometries, geometry, - { gfx_del_geometry(geometry); }); + mempool_foreach( + &render_backend->geometries, geometry, { gfx_del_geometry(geometry); }); - mempool_foreach(&render_backend->renderbuffers, renderbuffer, - { gfx_del_renderbuffer(renderbuffer); }); + mempool_foreach(&render_backend->renderbuffers, renderbuffer, { + gfx_del_renderbuffer(renderbuffer); + }); - mempool_foreach(&render_backend->shader_programs, prog, - { gfx_del_shader_program(prog); }); + mempool_foreach(&render_backend->shader_programs, prog, { + gfx_del_shader_program(prog); + }); - mempool_foreach(&render_backend->shaders, shader, - { gfx_del_shader(shader); }); + mempool_foreach( + &render_backend->shaders, shader, { gfx_del_shader(shader); }); - mempool_foreach(&render_backend->textures, texture, - { gfx_del_texture(texture); }); + mempool_foreach( + &render_backend->textures, texture, { gfx_del_texture(texture); }); } // ----------------------------------------------------------------------------- @@ -62,8 +65,8 @@ void gfx_del_render_backend(RenderBackend* render_backend) { void gfx_start_frame(RenderBackend* render_backend) { assert(render_backend); - glViewport(0, 0, render_backend->viewport.width, - render_backend->viewport.height); + glViewport( + 0, 0, render_backend->viewport.width, render_backend->viewport.height); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -77,7 +80,7 @@ void gfx_end_frame(RenderBackend* render_backend) { void gfx_set_viewport(RenderBackend* render_backend, int width, int height) { assert(render_backend); - render_backend->viewport.width = width; + render_backend->viewport.width = width; render_backend->viewport.height = height; } @@ -85,7 +88,7 @@ void gfx_get_viewport(RenderBackend* render_backend, int* width, int* height) { assert(render_backend); assert(width); assert(height); - *width = render_backend->viewport.width; + *width = render_backend->viewport.width; *height = render_backend->viewport.height; } @@ -93,8 +96,8 @@ void gfx_get_viewport(RenderBackend* render_backend, int* width, int* height) { // Buffers. // ----------------------------------------------------------------------------- -Buffer* gfx_make_buffer(RenderBackend* render_backend, const void* data, - size_t size_bytes) { +Buffer* gfx_make_buffer( + RenderBackend* render_backend, const void* data, size_t size_bytes) { assert(render_backend); Buffer* buffer = mempool_alloc(&render_backend->buffers); if (!buffer) { @@ -107,8 +110,8 @@ Buffer* gfx_make_buffer(RenderBackend* render_backend, const void* data, return buffer; } -Buffer* gfx_make_buffer2d(RenderBackend* render_backend, const vec2* verts, - size_t count) { +Buffer* gfx_make_buffer2d( + RenderBackend* render_backend, const vec2* verts, size_t count) { assert(render_backend); Buffer* buffer = mempool_alloc(&render_backend->buffers); if (!buffer) { @@ -121,8 +124,8 @@ Buffer* gfx_make_buffer2d(RenderBackend* render_backend, const vec2* verts, return buffer; } -Buffer* gfx_make_buffer3d(RenderBackend* render_backend, const vec3* verts, - size_t count) { +Buffer* gfx_make_buffer3d( + RenderBackend* render_backend, const vec3* verts, size_t count) { assert(render_backend); Buffer* buffer = mempool_alloc(&render_backend->buffers); if (!buffer) { @@ -135,8 +138,8 @@ Buffer* gfx_make_buffer3d(RenderBackend* render_backend, const vec3* verts, return buffer; } -Buffer* gfx_make_buffer4d(RenderBackend* render_backend, const vec4* verts, - size_t count) { +Buffer* gfx_make_buffer4d( + RenderBackend* render_backend, const vec4* verts, size_t count) { assert(render_backend); Buffer* buffer = mempool_alloc(&render_backend->buffers); if (!buffer) { @@ -160,8 +163,8 @@ void gfx_destroy_buffer(RenderBackend* render_backend, Buffer** buffer) { // Geometry. // ----------------------------------------------------------------------------- -Geometry* gfx_make_geometry(RenderBackend* render_backend, - const GeometryDesc* desc) { +Geometry* gfx_make_geometry( + RenderBackend* render_backend, const GeometryDesc* desc) { assert(render_backend); assert(desc); Geometry* geometry = mempool_alloc(&render_backend->geometries); @@ -186,8 +189,8 @@ void gfx_destroy_geometry(RenderBackend* render_backend, Geometry** geometry) { // Textures. // ----------------------------------------------------------------------------- -Texture* gfx_make_texture(RenderBackend* render_backend, - const TextureDesc* desc) { +Texture* gfx_make_texture( + RenderBackend* render_backend, const TextureDesc* desc) { assert(render_backend); assert(desc); Texture* texture = mempool_alloc(&render_backend->textures); @@ -213,8 +216,8 @@ void gfx_destroy_texture(RenderBackend* render_backend, Texture** texture) { // Renderbuffers. // ----------------------------------------------------------------------------- -RenderBuffer* gfx_make_renderbuffer(RenderBackend* render_backend, - const RenderBufferDesc* desc) { +RenderBuffer* gfx_make_renderbuffer( + RenderBackend* render_backend, const RenderBufferDesc* desc) { assert(render_backend); assert(desc); RenderBuffer* renderbuffer = mempool_alloc(&render_backend->renderbuffers); @@ -227,8 +230,8 @@ RenderBuffer* gfx_make_renderbuffer(RenderBackend* render_backend, return renderbuffer; } -void gfx_destroy_renderbuffer(RenderBackend* render_backend, - RenderBuffer** renderbuffer) { +void gfx_destroy_renderbuffer( + RenderBackend* render_backend, RenderBuffer** renderbuffer) { assert(render_backend); assert(renderbuffer); assert(*renderbuffer); @@ -240,8 +243,8 @@ void gfx_destroy_renderbuffer(RenderBackend* render_backend, // Framebuffers. // ----------------------------------------------------------------------------- -FrameBuffer* gfx_make_framebuffer(RenderBackend* render_backend, - const FrameBufferDesc* desc) { +FrameBuffer* gfx_make_framebuffer( + RenderBackend* render_backend, const FrameBufferDesc* desc) { assert(render_backend); assert(desc); FrameBuffer* framebuffer = mempool_alloc(&render_backend->framebuffers); @@ -255,8 +258,8 @@ FrameBuffer* gfx_make_framebuffer(RenderBackend* render_backend, return framebuffer; } -void gfx_destroy_framebuffer(RenderBackend* render_backend, - FrameBuffer** framebuffer) { +void gfx_destroy_framebuffer( + RenderBackend* render_backend, FrameBuffer** framebuffer) { assert(render_backend); assert(framebuffer); assert(*framebuffer); @@ -264,8 +267,6 @@ void gfx_destroy_framebuffer(RenderBackend* render_backend, mempool_free(&render_backend->framebuffers, framebuffer); } -void gfx_activate_framebuffer(const FrameBuffer* framebuffer); - // ----------------------------------------------------------------------------- // Shaders. // ----------------------------------------------------------------------------- @@ -292,8 +293,8 @@ void gfx_destroy_shader(RenderBackend* render_backend, Shader** shader) { mempool_free(&render_backend->shaders, shader); } -ShaderProgram* gfx_make_shader_program(RenderBackend* render_backend, - const ShaderProgramDesc* desc) { +ShaderProgram* gfx_make_shader_program( + RenderBackend* render_backend, const ShaderProgramDesc* desc) { assert(render_backend); assert(desc); ShaderProgram* prog = mempool_alloc(&render_backend->shader_programs); @@ -307,8 +308,8 @@ ShaderProgram* gfx_make_shader_program(RenderBackend* render_backend, return prog; } -void gfx_destroy_shader_program(RenderBackend* render_backend, - ShaderProgram** prog) { +void gfx_destroy_shader_program( + RenderBackend* render_backend, ShaderProgram** prog) { assert(render_backend); assert(prog); 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 @@ #include "gl_util.h" +#include #include #include @@ -20,6 +21,19 @@ static GLenum shader_type_to_gl(ShaderType type) { } } +static lstring make_defines_string(const ShaderDesc* desc) { + lstring defines = {0}; + for (size_t i = 0; i < desc->num_defines; ++i) { + const ShaderCompilerDefine* define = &desc->defines[i]; + lstring_append_cstr(&defines, "#define "); + lstring_append_cstr(&defines, sstring_cstring(&define->name)); + lstring_append_cstr(&defines, " "); + lstring_append_cstr(&defines, sstring_cstring(&define->value)); + lstring_append_cstr(&defines, "\n"); + } + return defines; +} + /// Creates an OpenGL shader. /// Returns non-zero on success, 0 on failure. static GLuint create_shader(const ShaderDesc* desc) { @@ -34,10 +48,13 @@ static GLuint create_shader(const ShaderDesc* desc) { const char* header = "#version 400 core\n\n"; #endif - const char* source_bits[] = {header, desc->code}; - const GLint source_lengths[] = {strlen(header), strlen(desc->code)}; + lstring defines = make_defines_string(desc); + + const char* source_bits[] = {header, lstring_cstring(&defines), desc->code}; + const GLint source_lengths[] = { + strlen(header), lstring_length(defines), strlen(desc->code)}; - glShaderSource(shader, 2, source_bits, source_lengths); + glShaderSource(shader, 3, source_bits, source_lengths); glCompileShader(shader); GLint result; glGetShaderiv(shader, GL_COMPILE_STATUS, &result); @@ -47,10 +64,11 @@ static GLuint create_shader(const ShaderDesc* desc) { if (log_len > 0) { char* log = calloc(log_len, sizeof(char)); glGetShaderInfoLog(shader, log_len, NULL, log); - LOGE("Failed loading shader: %s\n\nShader code: %s", log, desc->code); + static const char* sep = "----------"; + LOGE("Failed loading shader: %s\n%s\n%s\n%s", log, sep, desc->code, sep); free(log); } else { - LOGE("Failed loading shader: %s", desc->code); + LOGE("Failed loading shader:\n%s", desc->code); } glDeleteShader(shader); 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) { return false; } if (!game_new(game, desc->argc, desc->argv)) { - LOGE("Failed to initialize game\n"); + LOGE("Failed to initialize game"); return false; } *app_state = game; @@ -44,22 +44,24 @@ static void resize(void* app_state, int width, int height) { } int main(int argc, const char** argv) { - const int initial_width = 1350; + const int initial_width = 1350; const int initial_height = 900; - const int max_fps = 60; + const int max_fps = 60; - gfx_app_run(&(GfxAppDesc){.argc = argc, - .argv = argv, - .width = initial_width, - .height = initial_height, - .max_fps = max_fps, - .update_delta_time = - max_fps > 0 ? 1.0 / (double)max_fps : 0.0}, - &(GfxAppCallbacks){.init = init, - .update = update, - .render = render, - .resize = resize, - .shutdown = shutdown}); + gfx_app_run( + &(GfxAppDesc){ + .argc = argc, + .argv = argv, + .width = initial_width, + .height = initial_height, + .max_fps = max_fps, + .update_delta_time = max_fps > 0 ? 1.0 / (double)max_fps : 0.0}, + &(GfxAppCallbacks){ + .init = init, + .update = update, + .render = render, + .resize = resize, + .shutdown = shutdown}); return 0; } -- cgit v1.2.3