Fri, 13 Jun 2025 17:45:19 +0200
compute frame time before syncing to avoid div-by-zero in first frame
/* * 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 "camera.h" struct asc_shader_code_files_s { /** * File name of the vertex shader. */ const char *vtx; /** * File name of the fragment shader. */ const char *frag; }; struct asc_shader_code_defines_s { /** * Preprocessor code that shall be prepended to the vertex shader. */ const char *vtx; /** * Preprocessor code that shall be prepended to the fragment shader. */ const char *frag; }; typedef struct asc_shader_code_info_s { struct asc_shader_code_files_s files; struct asc_shader_code_defines_s defines; } AscShaderCodeInfo; typedef struct asc_shader_codes_s { char *vtx; char *frag; /** * Optional preprocessor code for the vertex shader. */ const char *vtx_pp; /** * Optional preprocessor code for the fragment shader. */ const char *frag_pp; } 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 typedef AscShaderProgram*(*asc_shader_create_func)(void); /** * Loads shader codes from files. * * @param info the structure containing the file names and preprocessing info * @param codes the structure where to store the loaded codes * @return zero on success, non-zero on failure */ int asc_shader_load_code_files(AscShaderCodeInfo info, AscShaderCodes *codes); /** * Deallocates the memory for the source codes. * * @param codes the structure containing pointers to the source codes */ void asc_shader_free_codes(AscShaderCodes codes); /** * Creates a shader program. * * @note This function intentionally has an unspecified pointer return type * so that you can assign the return value to your shader struct pointer without casts. * * @param codes the (zero-terminated) source codes * @param mem_size the memory size required for the structure * @return the compiled and linked shader program with @c AscShaderProgram as base struct */ void *asc_shader_create(AscShaderCodes codes, size_t mem_size); /** * Frees a shader program. * * @param program the program */ void asc_shader_free(AscShaderProgram *program); /** * Activates a shader for use. * * Does nothing 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 */ void asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera); /** * Registers a shader under a certain ID. * * @note This function intentionally has an unspecified pointer return type * so that you can assign the return value to your shader struct pointer without casts. * All shader structs must be based on @c AscShaderProgram. * * @param id the custom ID of the shader * @param create_func the function that creates the shader * @return the shader created by the @c create_func * @see asc_shader_lookup() */ const void *asc_shader_register(unsigned int id, asc_shader_create_func create_func); /** * Looks up a shader by ID. * * @note This function intentionally has an unspecified pointer return type * so that you can assign the return value to your shader struct pointer without casts. * All shader structs must be based on @c AscShaderProgram. * * @param id the ID of the shader to look up * @return the shader or @c NULL if no shader with such ID exists * @see asc_shader_register() */ const void *asc_shader_lookup(unsigned int id); /** * Looks up a shader by ID or registers a new one if no shader exists with the specified ID. * * This function can be used for lazy initialization of shaders. * * @note This function intentionally has an unspecified pointer return type * so that you can assign the return value to your shader struct pointer without casts. * All shader structs must be based on @c AscShaderProgram. * * @param id the custom ID of the shader * @param create_func the function to create the shader * @return the found shader or the newly created shader * @see asc_shader_lookup() * @see asc_shader_register() */ const void *asc_shader_lookup_or_create(unsigned int id, asc_shader_create_func create_func); /** * Frees all registered shaders. * * Completely wipes all shaders. * Be careful with this function when shaders are needed that have been registered with @c asc_shader_register(). * Those need to be registered again, or @a asc_shader_lookup() will fail. * Shaders that are used with @a asc_shader_lookup_or_create() will be re-created automatically. * * TODO: maybe we should add another function that only clears lazy-initialized shaders * another alternative would be to keep the initialization info and lazy-initialize cleared shaders on lookup * * @see asc_shader_lookup_or_create() */ void asc_shader_clear_registry(void); #endif //ASCENSION_SHADER_H