#pragma once #include // #include #include #include "../util.h" #include "../util/matrix.h" typedef struct GL_FONT *PGL_FONT; typedef struct GL_DATA *PGL_DATA; typedef void(*GL_RESIZE_REPAINT_CB)( void* userdata ); struct VERTEX { VEC2 pos; VEC2 uv; CLR clr; U8 sampler = 255; }; struct GL_SHADER_DEF { const char* name; const char* code; I32 type; U32 id; U8 compiled; }; struct GL_SHADER_PROGRAM { const char* name; GL_SHADER_DEF fsh; GL_SHADER_DEF vsh; U32 id; U32 vbuffer; GL_DATA* gl; }; struct GL_TEX2D { GLuint id; char name[256]; U32 width; U32 height; U32 channels; U8* data; }; typedef struct GL_DATA { SDL_Window* window; SDL_GLContext ctx; SDL_Renderer* renderer; I32 canvas_size[2]; LIST programs; LIST textures; LIST fonts; I32 shader_texture_limit; U64 last_tick; F32 frametime; F32 fps; GLuint vbuffer; VEC2 clip_start; VEC2 clip_dim; VEC2 viewport_start; VEC2 viewport_dim; MAT4* proj_matrix; GLuint vao; GL_RESIZE_REPAINT_CB resize_repaint_cb{}; void* resize_repaint_userdata{}; U8 resize_repaint_active{}; U8 window_constraint_active{}; } *PGL_DATA; GL_DATA* gl_instance(); GL_DATA* gl_create( I32* _canvas ); void gl_destroy( GL_DATA* gl ); void gl_gen_buffers( GL_DATA* gl ); STAT gl_beginframe( GL_DATA* gl ); STAT gl_endframe( GL_DATA* gl ); STAT gl_poll_events( GL_DATA* gl ); STAT gl_shader_compile( GL_DATA* gl, GL_SHADER_DEF* shader ); void gl_shader_destroy( GL_DATA* gl, GL_SHADER_DEF* shader ); GL_SHADER_PROGRAM* gl_program_create( GL_DATA* gl, const char* name, U32 size = sizeof(GL_SHADER_PROGRAM) ); STAT gl_program_compile( GL_DATA* gl, GL_SHADER_PROGRAM* program ); void gl_program_destroy( GL_DATA* gl, GL_SHADER_PROGRAM* program ); GL_TEX2D* gl_texture_create( GL_DATA* gl, const char* name ); GL_TEX2D* gl_texture_from_file( GL_DATA* gl, const char* name ); GL_TEX2D* gl_texture_from_bitmap( GL_DATA* gl, const char* name, U8* bitmap, U32 width, U32 height ); void gl_texture_destroy( GL_DATA* gl, GL_TEX2D* tex ); void gl_update_window( GL_DATA* gl, I32* size ); void gl_sync_window_size( GL_DATA* gl ); void gl_set_resize_repaint_callback( GL_DATA* gl, GL_RESIZE_REPAINT_CB cb, void* userdata ); void gl_set_clip( GL_DATA* gl, VEC2 start, VEC2 dim ); void gl_get_clip( GL_DATA* gl, VEC2* start, VEC2* dim ); void gl_set_viewport( GL_DATA* gl, VEC2 start, VEC2 dim ); void gl_get_viewport( GL_DATA* gl, VEC2* start, VEC2* dim ); void gl_reset_clip( GL_DATA* gl ); // special sampler id for no texture const U8 SAMPLER_ID_NONE = 255; extern I32 SAMPLER_INDICES[255]; template LIST triangle_fan_to_list( VERTEX* vertices, U32 vert_count ) { LIST ret{}; if( vert_count < 3 ) { return ret; } ret.reserve( (vert_count - 2) * 3 ); VERTEX* start = &vertices[0]; VERTEX* last = &vertices[1]; for( U32 i = 2; i < vert_count; ++i ) { ret.push( *start ); ret.push( *last ); ret.push( vertices[i] ); last = &vertices[i]; } return ret; }