Tue, 19 Aug 2025 18:51:46 +0200
further improve names and docu of the uniform location init functions
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * Copyright 2023 Mike Becker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef ASCENSION_SHADER_H #define ASCENSION_SHADER_H #include <cx/allocator.h> #include "camera.h" typedef struct asc_scene_node_s AscSceneNode; // avoids full include of scene_node.h typedef int asc_uniform_loc; struct asc_shader_code_s { /** * File name of the shader. * Set to @c NULL if the specific type of shader is not used in the program. */ const char *source_file; /** * An array of code segments, usually preprocessor defines. * * The maximum number of elements in this array is 64. * The preamble_code_flags integer decides which elements of this array shall be prepended to * the shader code before compilation. */ const char * const *preamble_code; /** * Flags for deciding which code segments shall be added to the preamble of the shader. */ uint64_t preamble_code_flags; }; typedef struct asc_shader_codes_s { struct asc_shader_code_s vtx; struct asc_shader_code_s frag; } AscShaderCodes; typedef struct asc_shader_program_s { unsigned int id; unsigned int gl_id; int model; int view; int projection; cx_destructor_func destr_func; } AscShaderProgram; /** * The maximum ID for a user-defined shader. * * The IDs above this number are reserved for the engine. */ #define ASC_SHADER_ID_USER_MAX 1'000'000'000u /** * A function to create a shader program. * Should return @c NULL when creation fails. * * Usually this function calls asc_shader_create() with * a configuration that depends on the flags passed as parameter. * * @see asc_shader_create() */ typedef AscShaderProgram*(*asc_shader_create_func)(int); /** * Initialization function for a shader. * * This usually gets all uniform locations and stores them as integers in the struct. * * To be used with asc_shader_create(). * @see asc_shader_create() * @see asc_shader_set_uniform_loc() */ typedef void(*asc_shader_init_func)(AscShaderProgram*, int); /** * Creates a shader program. * * @param code_info the information about the code that should be loaded * @param mem_size the memory size required for the target structure * @param init_func the initialization function * @param flags the creation flags * @return the compiled and linked shader program as a structure of size @p mem_size * that contains @c AscShaderProgram as base struct */ AscShaderProgram *asc_shader_create(AscShaderCodes code_info, size_t mem_size, asc_shader_init_func init_func, int flags); /** * Frees a shader program. * * @param program the program */ void asc_shader_free(AscShaderProgram *program); /** * Activates a shader for use. * * Does nothing and immediately returns zero when the shader is already active. * * @param shader the shader program to use or @c NULL to deactivate any shader * @param camera the camera matrices (view/projection) to upload * @retval zero when the shader is now active * @retval non-zero when the shader that was supposed to be activated is invalid */ int asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera); /** * Looks up a shader by ID or registers a new one if no shader exists with the specified ID. * * @param id the custom ID of the shader * @param create_func the function to create the shader * @param create_flags flags passed to create_func * @return the found shader or the newly created shader or @c NULL when shader compilation failed */ const AscShaderProgram *asc_shader_lookup(unsigned int id, asc_shader_create_func create_func, int create_flags); /** * Frees all registered shaders. * * The still required shaders are re-created when they are used next. * * @see asc_shader_lookup() */ void asc_shader_clear_registry(void); /** * Gets the location of a uniform as an integer. * * Usually you will not need this function. Instead, it is recommended to create a custom * shader program struct which uses AscShaderProgram as the base struct and then add the uniform locations * as fields to that struct. * Then you can use asc_shader_set_uniform_loc_by_name() to initialize all uniform locations. * * @param shader a pointer to the shader struct * @param name the name of the uniform * @return the uniform's location */ asc_uniform_loc asc_shader_get_uniform_loc(const AscShaderProgram *shader, const char *name); /** * Gets the location of a uniform as an integer and stores it directly in the struct. * * @param shader a pointer to the shader struct * @param mem_offset the offset of the @c asc_uniform_loc field in the shader program struct * @param name the name of the uniform */ void asc_shader_set_uniform_loc(AscShaderProgram *shader, off_t mem_offset, const char *name); /** * Gets the location of a uniform as an integer and stores it in the struct. * * Use this macro for asc_shader_set_uniform_loc() when the name in your struct is identical to the uniform's name. * * @param shader a pointer to the shader struct * @param type_name the type name of the shader struct * @param field_name the field name which must match the uniform's name */ #define asc_shader_set_uniform_loc_by_name(shader, type_name, field_name) \ asc_shader_set_uniform_loc(shader, offsetof(type_name, field_name), #field_name) void asc_shader_upload_model_matrix(const AscShaderProgram *shader, const AscSceneNode *node); void asc_shader_upload_color(int uniform_id, asc_color color); void asc_shader_upload_float(int uniform_id, float value); void asc_shader_upload_vec2f(int uniform_id, asc_vec2f value); #endif //ASCENSION_SHADER_H