medfall

A super great game engine
Log | Files | Refs

renderer.h (8728B)


      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_DEBUG,
     20 	UNIFORMS_VIEW,
     21 	UNIFORMS_MODEL,
     22 	UNIFORMS_LIGHT_VIEW,
     23 	UNIFORMS_WINDOW,
     24 	UNIFORMS_SUN,
     25 	UNIFORMS_SKY,
     26 	UNIFORMS_CLIPMAP,
     27 	UNIFORMS_CLIPMAP_SKIRT,
     28 
     29 	UNIFORMS_COUNT,
     30 };
     31 
     32 enum OutputSlots {
     33 	OUTPUT_ALBEDO,
     34 	OUTPUT_NORMAL,
     35 
     36 	OUTPUT_DEPTH,
     37 
     38 	OUTPUTS_COUNT,
     39 };
     40 
     41 #define RENDERER_MAX_TEXTURES 4
     42 #define RENDERER_MAX_TEXTURE_BUFFERS 4
     43 
     44 const u32 INVALID_SHADER = 0;
     45 
     46 enum CullFace {
     47 	CULLFACE_BACK,
     48 	CULLFACE_FRONT,
     49 	CULLFACE_DISABLED,
     50 };
     51 
     52 enum DepthFunc {
     53 	DEPTHFUNC_LESS,
     54 	DEPTHFUNC_EQUAL,
     55 	DEPTHFUNC_ALWAYS,
     56 	DEPTHFUNC_DISABLED, // also disables writing
     57 };
     58 
     59 enum BufferUsage {
     60 	BUFFERUSAGE_STATIC,
     61 	BUFFERUSAGE_DYNAMIC, // TODO: remove dynamic?
     62 	BUFFERUSAGE_STREAM,
     63 };
     64 
     65 enum PrimitiveType {
     66 	PRIMITIVETYPE_TRIANGLES,
     67 	PRIMITIVETYPE_TRIANGLE_STRIP,
     68 	PRIMITIVETYPE_POINTS,
     69 	PRIMITIVETYPE_LINES,
     70 };
     71 
     72 enum TextureFormat {
     73 	TEXFMT_INVALID,
     74 
     75 	TEXFMT_R_U8,
     76 	TEXFMT_R_U8NORM,
     77 	TEXFMT_R_U16,
     78 	TEXFMT_R_FLOAT,
     79 
     80 	TEXFMT_RGB_U8,
     81 	TEXFMT_RGB_U8_SRGB,
     82 	TEXFMT_RGB_HALF,
     83 	TEXFMT_RGB_FLOAT,
     84 
     85 	TEXFMT_RGBA_U8,
     86 	TEXFMT_RGBA_U8_SRGB,
     87 	TEXFMT_RGBA_FLOAT,
     88 
     89 	TEXFMT_DEPTH,
     90 
     91 	TEXFMT_BC1,
     92 	TEXFMT_BC1_SRGB,
     93 	TEXFMT_BC4,
     94 	TEXFMT_BC5,
     95 };
     96 
     97 enum TextureWrapMode {
     98 	TEXWRAP_REPEAT,
     99 	TEXWRAP_CLAMP,
    100 	TEXWRAP_MIRROR,
    101 	TEXWRAP_BORDER,
    102 };
    103 
    104 enum TextureFilterMode {
    105 	TEXFILTER_LINEAR,
    106 	TEXFILTER_POINT,
    107 };
    108 
    109 enum FramebufferAttachment {
    110 	FB_COLOUR,
    111 	FB_DEPTH,
    112 	FB_NORMAL,
    113 };
    114 
    115 struct TB {
    116 	TextureBufferObject tbo;
    117 	Texture texture;
    118 };
    119 
    120 struct FB {
    121 	FramebufferObject fbo;
    122 	StaticArray< Texture, OUTPUTS_COUNT > textures = { };
    123 	u32 width, height;
    124 };
    125 
    126 struct UniformBinding {
    127 	// TODO: might be able to make these u16
    128 	u32 offset;
    129 	u32 size;
    130 };
    131 
    132 struct RenderState {
    133 	StaticArray< UniformBinding, UNIFORMS_COUNT > uniforms = { };
    134 	StaticArray< Texture, RENDERER_MAX_TEXTURES > textures = { };
    135 	StaticArray< TB, RENDERER_MAX_TEXTURE_BUFFERS > tbs = { };
    136 	Shader shader = INVALID_SHADER;
    137 	DepthFunc depth_func = DEPTHFUNC_LESS;
    138 	CullFace cull_face = CULLFACE_BACK;
    139 	bool disable_depth_writes = false;
    140 	bool disable_colour_writes = false;
    141 	bool enable_alpha_blending = false;
    142 	bool wireframe = false;
    143 };
    144 
    145 enum VertexFormat {
    146 	VERTEXFMT_U8x3,
    147 	VERTEXFMT_U8x4,
    148 
    149 	VERTEXFMT_HALFx2,
    150 	VERTEXFMT_HALFx3,
    151 	VERTEXFMT_HALFx4,
    152 
    153 	VERTEXFMT_FLOATx2,
    154 	VERTEXFMT_FLOATx3,
    155 	VERTEXFMT_FLOATx4,
    156 };
    157 
    158 enum IndexFormat {
    159 	INDEXFMT_U16,
    160 	INDEXFMT_U32,
    161 };
    162 
    163 struct Mesh {
    164 	u32 num_vertices;
    165 	PrimitiveType primitive_type;
    166 	u32 vao;
    167 	VB positions;
    168 	VB normals;
    169 	VB tex_coords0;
    170 	VB tex_coords1;
    171 	VB colours;
    172 	IB indices;
    173 	IndexFormat indices_format;
    174 };
    175 
    176 struct MeshConfig {
    177 	MeshConfig() {
    178 		positions = 0;
    179 		normals = 0;
    180 		tex_coords0 = 0;
    181 		tex_coords1 = 0;
    182 		colours = 0;
    183 	}
    184 
    185 	VB unified_buffer = 0;
    186 	u32 stride = 0;
    187 
    188 	union {
    189 		struct {
    190 			VB positions;
    191 			VB normals;
    192 			VB tex_coords0;
    193 			VB tex_coords1;
    194 			VB colours;
    195 		};
    196 		struct {
    197 			u32 positions_offset;
    198 			u32 normals_offset;
    199 			u32 tex_coords0_offset;
    200 			u32 tex_coords1_offset;
    201 			u32 colours_offset;
    202 		};
    203 	};
    204 
    205 	VertexFormat positions_format = VERTEXFMT_FLOATx3;
    206 	VertexFormat normals_format = VERTEXFMT_FLOATx3;
    207 	VertexFormat tex_coords0_format = VERTEXFMT_FLOATx2;
    208 	VertexFormat tex_coords1_format = VERTEXFMT_FLOATx2;
    209 	VertexFormat colours_format = VERTEXFMT_FLOATx3;
    210 	IndexFormat indices_format = INDEXFMT_U32;
    211 
    212 	IB indices = 0;
    213 	u32 num_vertices = 0;
    214 
    215 	PrimitiveType primitive_type = PRIMITIVETYPE_TRIANGLES;
    216 };
    217 
    218 struct ShaderConfig {
    219 	StaticArray< const char *, 8 > srcs = { };
    220 	StaticArray< const char *, RENDERER_MAX_TEXTURES > texture_uniform_names = { };
    221 	StaticArray< const char *, RENDERER_MAX_TEXTURE_BUFFERS > texture_buffer_uniform_names = { };
    222 };
    223 
    224 struct TextureConfig {
    225 	u32 width = 0;
    226 	u32 height = 0;
    227 
    228 	const void * data = NULL;
    229 	u32 data_size;
    230 
    231 	TextureFormat format = TEXFMT_INVALID;
    232 	TextureWrapMode wrap = TEXWRAP_REPEAT;
    233 	TextureFilterMode filter = TEXFILTER_LINEAR;
    234 	bool has_mipmaps = false;
    235 
    236 	v4 border_colour;
    237 };
    238 
    239 struct RenderPassConfig {
    240 	FB target = { };
    241 
    242 	bool clear_colour = false;
    243 	v4 colour = v4( 0 );
    244 
    245 	bool clear_depth = false;
    246 	float depth = 1.0f;
    247 };
    248 
    249 struct FramebufferConfig {
    250 	struct FramebufferTexture {
    251 		TextureConfig config;
    252 		FramebufferAttachment attachment;
    253 	};
    254 
    255 	StaticArray< FramebufferTexture, OUTPUTS_COUNT > textures = { };
    256 };
    257 
    258 enum ClearColourBool { RENDERER_CLEAR_COLOUR_DONT, RENDERER_CLEAR_COLOUR_DO };
    259 enum ClearDepthBool { RENDERER_CLEAR_DEPTH_DONT, RENDERER_CLEAR_DEPTH_DO };
    260 
    261 void renderer_init();
    262 void renderer_term();
    263 
    264 void renderer_begin_frame();
    265 void renderer_begin_pass( const RenderPassConfig & pass );
    266 void renderer_begin_pass( FB target, ClearColourBool clear_colour, ClearDepthBool clear_depth );
    267 void renderer_begin_pass( ClearColourBool clear_colour, ClearDepthBool clear_depth );
    268 void renderer_end_pass();
    269 void renderer_end_frame();
    270 
    271 u32 renderer_num_draw_calls();
    272 u32 renderer_num_vertices();
    273 
    274 Texture renderer_blue_noise();
    275 
    276 UniformBinding renderer_upload_uniforms( const void * data, size_t size, size_t alignment );
    277 
    278 VB renderer_new_vb( const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_STATIC );
    279 void renderer_delete_vb( VB vb );
    280 
    281 IB renderer_new_ib( const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_STATIC );
    282 void renderer_delete_ib( IB ib );
    283 
    284 TB renderer_new_tb( TextureFormat format, const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_DYNAMIC );
    285 void renderer_tb_data( TB tb, const void * data, u32 len, BufferUsage usage = BUFFERUSAGE_DYNAMIC );
    286 void renderer_delete_tb( TB tb );
    287 
    288 FB renderer_new_fb( TextureConfig texture_format, FramebufferAttachment attachment );
    289 FB renderer_new_fb( const FramebufferConfig & config );
    290 void renderer_delete_fb( FB fb );
    291 
    292 Shader renderer_new_shader( ShaderConfig config );
    293 Shader renderer_new_shader( const char * src );
    294 void renderer_delete_shader( Shader shader );
    295 
    296 Texture renderer_new_texture( TextureConfig config );
    297 void renderer_delete_texture( Texture texture );
    298 
    299 Mesh renderer_new_mesh( MeshConfig config );
    300 void renderer_draw_mesh( const Mesh & mesh, const RenderState & state );
    301 void renderer_draw_instances( const Mesh & mesh, const RenderState & state, u32 num_instances, VB instace_data );
    302 void renderer_delete_mesh( const Mesh & mesh );
    303 
    304 void renderer_draw_fullscreen_triangle( const RenderState & state );
    305 
    306 /*
    307  * renderer_new_*( array ) helpers
    308  */
    309 
    310 template< typename T >
    311 VB renderer_new_vb( const array< T > data, BufferUsage usage = BUFFERUSAGE_STATIC ) {
    312 	return renderer_new_vb( data.ptr(), checked_cast< u32 >( data.num_bytes() ), usage );
    313 }
    314 
    315 template< typename T >
    316 VB renderer_new_ib( const array< T > data, BufferUsage usage = BUFFERUSAGE_STATIC ) {
    317 	return renderer_new_ib( data.ptr(), checked_cast< u32 >( data.num_bytes() ), usage );
    318 }
    319 
    320 /*
    321  * renderer_uniform helper
    322  */
    323 
    324 template< typename T >
    325 constexpr size_t renderer_ubo_alignment() {
    326 	return min( align4( sizeof( T ) ), 4 * sizeof( float ) );
    327 }
    328 
    329 template<>
    330 constexpr size_t renderer_ubo_alignment< v3 >() {
    331 	return 4 * sizeof( float );
    332 }
    333 
    334 template< typename T >
    335 constexpr size_t renderer_ub_alignment() {
    336 	return renderer_ubo_alignment< T >();
    337 }
    338 
    339 template< typename S, typename T, typename... Rest >
    340 constexpr size_t renderer_ub_alignment() {
    341 	return max( renderer_ub_alignment< T, Rest... >(), renderer_ubo_alignment< S >() );
    342 }
    343 
    344 template< typename T >
    345 constexpr size_t renderer_uniforms_size( size_t size ) {
    346 	return sizeof( T ) + align_power_of_2( size, renderer_ubo_alignment< T >() );
    347 }
    348 
    349 template< typename S, typename T, typename... Rest >
    350 constexpr size_t renderer_uniforms_size( size_t size ) {
    351 	return renderer_uniforms_size< T, Rest... >( sizeof( S ) + align_power_of_2( size, renderer_ubo_alignment< S >() ) );
    352 }
    353 
    354 inline void renderer_serialise_uniforms( char * buf, size_t len ) { }
    355 
    356 template< typename T, typename... Rest >
    357 inline void renderer_serialise_uniforms( char * buf, size_t len, const T & first, Rest... rest ) {
    358 	len = align_power_of_2( len, renderer_ubo_alignment< T >() );
    359 	memcpy( buf + len, &first, sizeof( first ) );
    360 	renderer_serialise_uniforms( buf, len + sizeof( first ), rest... );
    361 }
    362 
    363 template< typename... Rest >
    364 inline UniformBinding renderer_uniforms( Rest... rest ) {
    365 	constexpr size_t buf_size = renderer_uniforms_size< Rest... >( 0 );
    366 	constexpr size_t alignment = renderer_ub_alignment< Rest... >();
    367 	char buf[ buf_size ];
    368 	memset( buf, 0, sizeof( buf ) );
    369 	renderer_serialise_uniforms( buf, 0, rest... );
    370 	return renderer_upload_uniforms( buf, sizeof( buf ), alignment );
    371 }