medfall

A super great game engine
Log | Files | Refs

renderer.h (7524B)


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