#pragma once #if defined (_WIN32) #include #else #include #endif #include #include #include "camera.h" #include "entity.h" #include "lights.h" #include "util.h" #include "shader_program.h" // NOTE: array of entities rendered with the same shader program struct render_group { // TODO: also needs to be resizable entity* entities; uint entity_count; shader_wrapper shader; // TODO: does it makes sense to have the mesh_type stored on the // render_group? can then easily pass to roDraw() along with the entity // render_objects... // only the mesh object and render object really need to know about the // mesh_type... // //mesh_t mesh_type; }; struct SDL_Handles { SDL_Window *window; SDL_GLContext glContext; SDL_DisplayMode currentDisplayMode; }; // -------------------------- // Memory allocation WIP struct mesh_asset { // header size_t size; uint num_vertices; uint num_indices; mesh_asset* next; // data glm::vec3* vertices; uint* indices; glm::vec3* texture_coords; glm::mat4* model_transform; }; #define MAX_PATH_SIZE 256 struct render_asset { // header size_t size; uint num_meshes; uint name_len; render_asset* next; // data char* filepath; mesh_asset* meshes; // FIXME: also need to flatten diffuse_texture->pixels and track size of // util_image structure, ie) another heaader + pixels util_image* diffuse_texture; // FIXME: node_animation has a pointer to a render_object. need to decouple // that somehow //node_animation* node_anim; }; // NOTE: This is a linearly allocated block to contain all used mesh assets // Assets are loaded once, and then copied to video memory as needed. struct asset_memory_block { uint asset_count; size_t max_size; render_asset* first; render_asset* next_free; }; #define INITIAL_ASSET_BLOCK_SIZE 256 * 1024 * 1024 // 256MB asset_memory_block* memInitBlock(size_t initial_size = INITIAL_ASSET_BLOCK_SIZE); render_asset* memAddAsset(const char* filepath); void memFreeBlock(asset_memory_block* block); // Memory allocation WIP // -------------------------- struct render_state { glm::vec2 viewport_dims; camera cam; util_RGBA clear_col; SDL_Handles* handles; bool running; // TODO: this really needs to be a resizable array, or linked list, or // ...gasp, std::vector render_group** render_groups; uint render_group_count; // TODO: hide shaders behind a better abstraction than 'shader_wrapper' default_shader_program* default_shader; simple_shader_program* simple_shader; light_group* lights; }; render_state* renInit(const char* title = "Tangerine", glm::vec2 viewport_dims = glm::vec2(1280, 720), Uint32 SDL_init_flags = 0); void renShutdown(render_state* rs); render_group* renAllocateGroup(uint entity_count, shader_wrapper shader); // NOTE: callback function signature to use with renDoRenderLoop() typedef void (*frame_callback_fn) (render_state*); // NOTE: There are 2 callbacks to use here, cb_func_pre is called before // the call to renRenderFrame(), cb_fun_post is called after // NOTE: if you use cb_func_pre, you will have to use SDL_PollEvent() manually // and at minimum set rs->running = false on SDL_QUIT event void renDoRenderLoop(render_state* rs, uint framerate = 60, frame_callback_fn cb_func_pre = nullptr, frame_callback_fn cb_func_post = nullptr); void renRenderFrame(render_state* rs); bool renAddLight(render_state* rs, glm::vec3 pos = glm::vec3(0, 0, 0), glm::vec3 color = glm::vec3(1, 1, 1), float intensity = 1.0); glm::vec2 renGetWindowDims(render_state* rs);