medfall

A super great game engine
Log | Files | Refs

renderer.h (7507B)


      1 #pragma once
      2 
      3 #include "intrinsics.h"
      4 #include "array.h"
      5 #include "linear_algebra.h"
      6 
      7 /*
      8  * forward declare things so only the implementation includes the full GL headers
      9  */
     10 
     11 typedef u32 VB;
     12 typedef u32 IB;
     13 typedef u32 Shader;
     14 typedef u32 Texture;
     15 typedef u32 TextureBufferObject;
     16 typedef u32 FramebufferObject;
     17 
     18 enum UniformSlots {
     19 	UNIFORMS_VIEW,
     20 	UNIFORMS_MODEL,
     21 	UNIFORMS_LIGHT_VIEW,
     22 	UNIFORMS_WINDOW,
     23 	UNIFORMS_SUN,
     24 	UNIFORMS_SKY,
     25 	UNIFORMS_CLIPMAP,
     26 	UNIFORMS_CLIPMAP_SKIRT,
     27 
     28 	UNIFORMS_COUNT,
     29 };
     30 
     31 #define RENDERER_MAX_TEXTURES 4
     32 #define RENDERER_MAX_TEXTURE_BUFFERS 4
     33 
     34 const u32 INVALID_SHADER = 0;
     35 
     36 enum CullFace {
     37 	CULLFACE_BACK,
     38 	CULLFACE_FRONT,
     39 	CULLFACE_DISABLED,
     40 };
     41 
     42 enum DepthFunc {
     43 	DEPTHFUNC_LESS,
     44 	DEPTHFUNC_EQUAL,
     45 	DEPTHFUNC_ALWAYS,
     46 	DEPTHFUNC_DISABLED, // also disables writing
     47 };
     48 
     49 enum BufferUsage {
     50 	BUFFERUSAGE_STATIC,
     51 	BUFFERUSAGE_DYNAMIC, // TODO: remove dynamic?
     52 	BUFFERUSAGE_STREAM,
     53 };
     54 
     55 enum PrimitiveType {
     56 	PRIMITIVETYPE_TRIANGLES,
     57 	PRIMITIVETYPE_TRIANGLE_STRIP,
     58 	PRIMITIVETYPE_POINTS,
     59 	PRIMITIVETYPE_LINES,
     60 };
     61 
     62 enum TextureFormat {
     63 	TEXFMT_INVALID,
     64 
     65 	TEXFMT_R_U8,
     66 	TEXFMT_R_U8NORM,
     67 	TEXFMT_R_U16,
     68 	TEXFMT_R_FLOAT,
     69 
     70 	TEXFMT_RGB_U8,
     71 	TEXFMT_RGB_U8_SRGB,
     72 	TEXFMT_RGB_FLOAT,
     73 
     74 	TEXFMT_RGBA_U8,
     75 	TEXFMT_RGBA_U8_SRGB,
     76 	TEXFMT_RGBA_FLOAT,
     77 
     78 	TEXFMT_DEPTH,
     79 
     80 	TEXFMT_BC1,
     81 	TEXFMT_BC1_SRGB,
     82 	TEXFMT_BC4,
     83 	TEXFMT_BC5,
     84 };
     85 
     86 enum TextureWrapMode {
     87 	TEXWRAP_REPEAT,
     88 	TEXWRAP_CLAMP,
     89 	TEXWRAP_MIRROR,
     90 	TEXWRAP_BORDER,
     91 };
     92 
     93 enum TextureFilterMode {
     94 	TEXFILTER_LINEAR,
     95 	TEXFILTER_POINT,
     96 };
     97 
     98 enum FramebufferAttachment {
     99 	FB_COLOUR,
    100 	FB_DEPTH,
    101 };
    102 
    103 struct TB {
    104 	TextureBufferObject tbo;
    105 	Texture texture;
    106 };
    107 
    108 struct FB {
    109 	FramebufferObject fbo;
    110 	FramebufferAttachment attachment;
    111 	Texture texture;
    112 	u32 width, height;
    113 };
    114 
    115 struct UniformBinding {
    116 	// TODO: might be able to make these u16
    117 	u32 offset;
    118 	u32 size;
    119 };
    120 
    121 struct RenderState {
    122 	StaticArray< UniformBinding, UNIFORMS_COUNT > uniforms = { };
    123 	StaticArray< Texture, RENDERER_MAX_TEXTURES > textures = { };
    124 	StaticArray< TB, RENDERER_MAX_TEXTURE_BUFFERS > tbs = { };
    125 	Shader shader = INVALID_SHADER;
    126 	DepthFunc depth_func = DEPTHFUNC_LESS;
    127 	CullFace cull_face = CULLFACE_BACK;
    128 	bool disable_depth_writes = false;
    129 	bool disable_colour_writes = false;
    130 	bool enable_alpha_blending = false;
    131 	bool wireframe = false;
    132 };
    133 
    134 struct Mesh {
    135 	u32 num_vertices;
    136 	PrimitiveType primitive_type;
    137 	u32 vao;
    138 	VB positions;
    139 	VB normals;
    140 	VB tex_coords0;
    141 	VB tex_coords1;
    142 	VB colours;
    143 	IB indices;
    144 };
    145 
    146 struct MeshConfig {
    147 	MeshConfig() {
    148 		positions = 0;
    149 		normals = 0;
    150 		tex_coords0 = 0;
    151 		tex_coords1 = 0;
    152 		colours = 0;
    153 	}
    154 
    155 	VB unified_buffer = 0;
    156 	u32 stride = 0;
    157 	union {
    158 		struct {
    159 			VB positions;
    160 			VB normals;
    161 			VB tex_coords0;
    162 			VB tex_coords1;
    163 			VB colours;
    164 		};
    165 		struct {
    166 			u32 positions_offset;
    167 			u32 normals_offset;
    168 			u32 tex_coords0_offset;
    169 			u32 tex_coords1_offset;
    170 			u32 colours_offset;
    171 		};
    172 	};
    173 	IB indices = 0;
    174 	u32 num_vertices = 0;
    175 	PrimitiveType primitive_type = PRIMITIVETYPE_TRIANGLES;
    176 };
    177 
    178 struct ShaderConfig {
    179 	StaticArray< const char *, 8 > srcs = { };
    180 	StaticArray< const char *, RENDERER_MAX_TEXTURES > texture_uniform_names = { };
    181 	StaticArray< const char *, RENDERER_MAX_TEXTURE_BUFFERS > texture_buffer_uniform_names = { };
    182 };
    183 
    184 struct TextureConfig {
    185 	u32 width = 0;
    186 	u32 height = 0;
    187 
    188 	const void * data = NULL;
    189 	u32 data_size;
    190 
    191 	TextureFormat format = TEXFMT_INVALID;
    192 	TextureWrapMode wrap = TEXWRAP_REPEAT;
    193 	TextureFilterMode filter = TEXFILTER_LINEAR;
    194 	bool has_mipmaps = false;
    195 
    196 	v4 border_colour;
    197 };
    198 
    199 enum ClearColourBool { RENDERER_CLEAR_COLOUR_DONT, RENDERER_CLEAR_COLOUR_DO };
    200 enum ClearDepthBool { RENDERER_CLEAR_DEPTH_DONT, RENDERER_CLEAR_DEPTH_DO };
    201 
    202 void renderer_init();
    203 void renderer_term();
    204 
    205 void renderer_begin_frame();
    206 void renderer_begin_pass( FB render_target, ClearColourBool clear_colour, ClearDepthBool clear_depth );
    207 void renderer_begin_pass( ClearColourBool clear_colour, ClearDepthBool clear_depth );
    208 void renderer_end_pass();
    209 void renderer_end_frame();
    210 
    211 u32 renderer_num_draw_calls();
    212 u32 renderer_num_vertices();
    213 
    214 Texture renderer_blue_noise();
    215 
    216 UniformBinding renderer_upload_uniforms( const void * data, size_t size, size_t alignment );
    217 
    218 VB renderer_new_vb( const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_STATIC );
    219 void renderer_delete_vb( VB vb );
    220 
    221 IB renderer_new_ib( const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_STATIC );
    222 void renderer_delete_ib( IB ib );
    223 
    224 TB renderer_new_tb( TextureFormat format, const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_DYNAMIC );
    225 void renderer_tb_data( TB tb, const void * data, u32 len, BufferUsage usage = BUFFERUSAGE_DYNAMIC );
    226 void renderer_delete_tb( TB tb );
    227 
    228 FB renderer_new_fb( TextureConfig texture_format, FramebufferAttachment attachment );
    229 void renderer_delete_fb( FB fb );
    230 
    231 Shader renderer_new_shader( ShaderConfig config );
    232 Shader renderer_new_shader( const char * src );
    233 void renderer_delete_shader( Shader shader );
    234 
    235 Texture renderer_new_texture( TextureConfig config );
    236 void renderer_delete_texture( Texture texture );
    237 
    238 Mesh renderer_new_mesh( MeshConfig config );
    239 void renderer_draw_mesh( const Mesh & mesh, const RenderState & state );
    240 void renderer_draw_instances( const Mesh & mesh, const RenderState & state, u32 num_instances, VB instace_data );
    241 void renderer_delete_mesh( const Mesh & mesh );
    242 
    243 /*
    244  * renderer_new_*( array ) helpers
    245  */
    246 
    247 template< typename T >
    248 VB renderer_new_vb( const array< T > data, BufferUsage usage = BUFFERUSAGE_STATIC ) {
    249 	return renderer_new_vb( data.ptr(), checked_cast< u32 >( data.num_bytes() ), usage );
    250 }
    251 
    252 template< typename T >
    253 VB renderer_new_ib( const array< T > data, BufferUsage usage = BUFFERUSAGE_STATIC ) {
    254 	return renderer_new_ib( data.ptr(), checked_cast< u32 >( data.num_bytes() ), usage );
    255 }
    256 
    257 /*
    258  * renderer_uniform helper
    259  */
    260 
    261 template< typename T >
    262 constexpr size_t renderer_ubo_alignment() {
    263 	return min( align4( sizeof( T ) ), 4 * sizeof( float ) );
    264 }
    265 
    266 template<>
    267 constexpr size_t renderer_ubo_alignment< v3 >() {
    268 	return 4 * sizeof( float );
    269 }
    270 
    271 template< typename T >
    272 constexpr size_t renderer_ub_alignment() {
    273 	return renderer_ubo_alignment< T >();
    274 }
    275 
    276 template< typename S, typename T, typename... Rest >
    277 constexpr size_t renderer_ub_alignment() {
    278 	return max( renderer_ub_alignment< T, Rest... >(), renderer_ubo_alignment< S >() );
    279 }
    280 
    281 template< typename T >
    282 constexpr size_t renderer_uniforms_size( size_t size ) {
    283 	return sizeof( T ) + align_power_of_2( size, renderer_ubo_alignment< T >() );
    284 }
    285 
    286 template< typename S, typename T, typename... Rest >
    287 constexpr size_t renderer_uniforms_size( size_t size ) {
    288 	return renderer_uniforms_size< T, Rest... >( sizeof( S ) + align_power_of_2( size, renderer_ubo_alignment< S >() ) );
    289 }
    290 
    291 inline void renderer_serialise_uniforms( char * buf, size_t len ) { }
    292 
    293 template< typename T, typename... Rest >
    294 inline void renderer_serialise_uniforms( char * buf, size_t len, const T & first, Rest... rest ) {
    295 	len = align_power_of_2( len, renderer_ubo_alignment< T >() );
    296 	memcpy( buf + len, &first, sizeof( first ) );
    297 	renderer_serialise_uniforms( buf, len + sizeof( first ), rest... );
    298 }
    299 
    300 template< typename... Rest >
    301 inline UniformBinding renderer_uniforms( Rest... rest ) {
    302 	constexpr size_t buf_size = renderer_uniforms_size< Rest... >( 0 );
    303 	constexpr size_t alignment = renderer_ub_alignment< Rest... >();
    304 	char buf[ buf_size ];
    305 	memset( buf, 0, sizeof( buf ) );
    306 	renderer_serialise_uniforms( buf, 0, rest... );
    307 	return renderer_upload_uniforms( buf, sizeof( buf ), alignment );
    308 }