#pragma once #include #include "asset.h" #include "entity.h" #include "dumbLog.h" #include "GLDebug.h" #include "shader.h" #include "types.h" #include "util.h" /* * === TODO: === * - full lighting model * - test complex entities * - need a separate GLBufferToAttribMapping for each mesh on an entity * - fix debug load times (either by using cgltf, or hiding tinygltf.h) * - RenderGroups and Entities need to come into and out of existence during * gameplay. So, we need to extend MemoryArena to be a pool allocator * instead of an allocate only linear allocator * - add libTangerine namespace? * - merge back into libTangerine * * === TODONE: === * - don't allocate Asset structure on asset arena * - store on RenderState as reference * - store asset arena to asset structure * - condense get_X_ByPath functions with assetLoad functions * - move to asset interface * - load diffuse texture automatically when loading a model * - move entity structure and functions to new file? * - load diffuse texture into OpenGL, and store GLTexture structure onto * GLContext * - need a cache algorithm starting in initEntity() * - check for GLTexture by path hash * - load texture into gl if not cached * - pass result GLTexture to loadGLMesh() * - update loadScene function with textured models, and test texture loading * - work on cleaner interface for initEntity and loadScene... * - add a LOGF macro for printf style logging * - replace instances of printf * - rename data structures to be in the new format, eg) UpperCaseStyleNames * - rename instances of 'model_xform' that refer to a mesh node to something * like node_xform. model_xform should be reserved for the entity node * - move default shaders out of git-lfs */ struct SDLHandles { SDL_Window* window; SDL_GLContext sdl_gl_ctx; SDL_DisplayMode display_mode; }; // TODO: node/tree structure for entities struct Node; struct RenderGroup { ShaderProgram* shader; u32 num_entities; u32 max_entities; Entity* entities; char* name; }; struct GLClearColor { GLfloat R; GLfloat G; GLfloat B; GLfloat A; }; struct RenderState { bool running; Transforms* xforms; // NOTE: would be part of camera in libTangerine SDLHandles* handles; GLContext* gl_ctx; Assets assets; MemoryArena* rg_arena; u32 num_render_groups; u32 max_render_groups; RenderGroup* render_groups; GLClearColor clear_col; // TODO: full lighting #if 0 u32 num_lights; u32 max_lights; PointLight* lights; #endif }; #define DEFAULT_MODEL_COUNT 256 #define DEFAULT_TEXTURE_COUNT 64 #define DEFAULT_SHADER_COUNT 64 #define DEFAULT_UBO_COUNT 32 #define DEFAULT_RENDER_GROUP_COUNT 256 RenderState* initRenderState(u32 max_models = DEFAULT_MODEL_COUNT, u32 max_textures = DEFAULT_TEXTURE_COUNT, u32 max_shaders = DEFAULT_SHADER_COUNT, u32 max_render_groups = DEFAULT_RENDER_GROUP_COUNT, u32 max_ubos = DEFAULT_UBO_COUNT); void freeRenderState(RenderState*& rs); #define DEFAULT_ENTITY_COUNT 256 void initRenderGroup(RenderGroup* rg, MemoryArena* arena, ShaderProgram* shader, u32 num_entities = DEFAULT_ENTITY_COUNT, const char* name = ""); void freeRenderGroup(RenderGroup* rg, MemoryArena* arena); RenderGroup* getFreeRenderGroup(RenderState* rs); Entity* getFreeEntity(RenderGroup* rg); // NOTE: callback function signature to use with renDoRenderLoop() typedef void (*frame_callback_fn) (RenderState*); // 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 doRenderLoop(RenderState* rs, uint framerate = 60, frame_callback_fn cb_func_pre = nullptr, frame_callback_fn cb_func_post = nullptr); void renderFrame(RenderState* rs, const GLClearColor& clear_col); // NOTE: automatic loading of default shaders struct ShaderInit { const char* name; const char* vert_path; const char* frag_path; }; #define DEFAULT_SHADER_INIT { "default", \ "../data/shader.vert", \ "../data/shader.frag" } #define DEBUG_SHADER_INIT { "debug", \ "../data/debug.vert", \ "../data/debug.frag", } #define COLORED_VERT_SHADER_INIT { "colored_vertices", \ "../data/colored_vertices.vert", \ "../data/colored_vertices.frag", } #define SHADER_INIT_COUNT 3 const ShaderInit SHADER_INIT_LIST[SHADER_INIT_COUNT] { DEFAULT_SHADER_INIT, DEBUG_SHADER_INIT, COLORED_VERT_SHADER_INIT }; bool loadDefaultShaders(RenderState* rs, u32 num_shaders = SHADER_INIT_COUNT, const ShaderInit shaders[] = SHADER_INIT_LIST); // NOTE: only useful if the shader attribute names match the names in the // default shaders. If loading a custom shader, this may not work as expected, // and you should use getVertexAttribByName instead GLVertexAttrib* getVertexAttribByType(ShaderProgram* shader, MeshBufferType buf_type);