@ -22,31 +22,19 @@
# include "im_render.h"
# include "im_render.h"
# include "../common/variant.h"
# include "../common/variant.h"
# include "../common/common.h"
# include "../common/common.h"
# include "scene.h"
# include <string.h>
# include <string.h>
# include <stdio.h>
# include <stdio.h>
# include <stdlib.h>
# include <stdlib.h>
# include <assert.h>
# define MAX_UNIFORM_NAME_LEN 64
/* TODO: Move all this into a struct called renderer state */
static int def_fbo = - 1 ;
static int def_albedo_tex = - 1 ;
static int def_depth_tex = - 1 ;
static int quad_geo = - 1 ;
static int composition_shader = - 1 ;
static int debug_shader = - 1 ;
static int num_culled = 0 , num_rendered = 0 , num_indices = 0 ;
static int num_culled_slot = - 1 , num_rendered_slot = - 1 , num_indices_slot = - 1 ;
static struct Sprite_Batch * sprite_batch = NULL ;
void on_framebuffer_size_change ( int width , int height ) ;
void on_framebuffer_size_change ( int width , int height ) ;
void renderer_init ( void )
void renderer_init ( struct Renderer * renderer )
{
{
assert ( renderer ) ;
glClearColor ( 0.3f , 0.6f , 0.9f , 1.0f ) ;
glClearColor ( 0.3f , 0.6f , 0.9f , 1.0f ) ;
glEnable ( GL_DEPTH_TEST ) ;
glEnable ( GL_DEPTH_TEST ) ;
glEnable ( GL_CULL_FACE ) ;
glEnable ( GL_CULL_FACE ) ;
@ -78,7 +66,7 @@ void renderer_init(void)
array_push ( indices , 0 , uint ) ; array_push ( indices , 1 , uint ) ; array_push ( indices , 2 , uint ) ;
array_push ( indices , 0 , uint ) ; array_push ( indices , 1 , uint ) ; array_push ( indices , 2 , uint ) ;
array_push ( indices , 2 , uint ) ; array_push ( indices , 3 , uint ) ; array_push ( indices , 0 , uint ) ;
array_push ( indices , 2 , uint ) ; array_push ( indices , 3 , uint ) ; array_push ( indices , 0 , uint ) ;
quad_geo = geom_create ( " Quad " , vertices , uvs , normals , indices , NULL ) ;
renderer - > quad_geo = geom_create ( " Quad " , vertices , uvs , normals , indices , NULL ) ;
array_free ( vertices ) ;
array_free ( vertices ) ;
array_free ( uvs ) ;
array_free ( uvs ) ;
array_free ( normals ) ;
array_free ( normals ) ;
@ -87,66 +75,70 @@ void renderer_init(void)
int width = - 1 , height = - 1 ;
int width = - 1 , height = - 1 ;
struct Game_State * game_state = game_state_get ( ) ;
struct Game_State * game_state = game_state_get ( ) ;
platform - > window . get_size ( game_state - > window , & width , & height ) ;
platform - > window . get_size ( game_state - > window , & width , & height ) ;
def_albedo_tex = texture_create ( " def_albedo_texture " ,
renderer - > def_albedo_tex = texture_create ( " def_albedo_texture " ,
TU_DIFFUSE ,
TU_DIFFUSE ,
width , height ,
width , height ,
GL_RGB ,
GL_RGB ,
GL_RGB16F ,
GL_RGB16F ,
GL_FLOAT ,
GL_FLOAT ,
NULL ) ;
NULL ) ;
texture_set_param ( def_albedo_tex , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( renderer - > def_albedo_tex , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( def_albedo_tex , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( renderer - > def_albedo_tex , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( def_albedo_tex , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
texture_set_param ( renderer - > def_albedo_tex , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
texture_set_param ( def_albedo_tex , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
texture_set_param ( renderer - > def_albedo_tex , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
def_depth_tex = texture_create ( " def_depth_texture " ,
renderer - > def_depth_tex = texture_create ( " def_depth_texture " ,
TU_SHADOWMAP4 ,
TU_SHADOWMAP4 ,
width , height ,
width , height ,
GL_DEPTH_COMPONENT ,
GL_DEPTH_COMPONENT ,
GL_DEPTH_COMPONENT32F ,
GL_DEPTH_COMPONENT32F ,
GL_FLOAT ,
GL_FLOAT ,
NULL ) ;
NULL ) ;
texture_set_param ( def_depth_tex , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( renderer - > def_depth_tex , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( def_depth_tex , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( renderer - > def_depth_tex , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
texture_set_param ( def_depth_tex , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
texture_set_param ( renderer - > def_depth_tex , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
texture_set_param ( def_depth_tex , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
texture_set_param ( renderer - > def_depth_tex , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
texture_set_param ( def_depth_tex , GL_TEXTURE_COMPARE_MODE , GL_COMPARE_REF_TO_TEXTURE ) ;
texture_set_param ( renderer - > def_depth_tex , GL_TEXTURE_COMPARE_MODE , GL_COMPARE_REF_TO_TEXTURE ) ;
texture_set_param ( def_depth_tex , GL_TEXTURE_COMPARE_FUNC , GL_LEQUAL ) ;
texture_set_param ( renderer - > def_depth_tex , GL_TEXTURE_COMPARE_FUNC , GL_LEQUAL ) ;
def_fbo = framebuffer_create ( width , height , true , false , true ) ;
renderer - > def_fbo = framebuffer_create ( width , height , true , false , true ) ;
framebuffer_texture_set ( def_fbo , def_albedo_tex , FA_COLOR_ATTACHMENT0 ) ;
framebuffer_texture_set ( renderer - > def_fbo , renderer - > def_albedo_tex , FA_COLOR_ATTACHMENT0 ) ;
framebuffer_texture_set ( def_fbo , def_depth_tex , FA_DEPTH_ATTACHMENT ) ;
framebuffer_texture_set ( renderer - > def_fbo , renderer - > def_depth_tex , FA_DEPTH_ATTACHMENT ) ;
composition_shader = shader_create ( " fbo.vert " , " fbo.frag " ) ;
renderer - > composition_shader = shader_create ( " fbo.vert " , " fbo.frag " ) ;
debug_shader = shader_create ( " debug.vert " , " debug.frag " ) ;
renderer - > debug_shader = shader_create ( " debug.vert " , " debug.frag " ) ;
num_culled_slot = editor_debugvar_slot_create ( " Culled Geom " , VT_INT ) ;
renderer - > num_culled_slot = editor_debugvar_slot_create ( " Culled Geom " , VT_INT ) ;
num_rendered_slot = editor_debugvar_slot_create ( " Rendered Geom " , VT_INT ) ;
renderer - > num_rendered_slot = editor_debugvar_slot_create ( " Rendered Geom " , VT_INT ) ;
num_indices_slot = editor_debugvar_slot_create ( " Total Indices " , VT_INT ) ;
renderer - > num_indices_slot = editor_debugvar_slot_create ( " Total Indices " , VT_INT ) ;
sprite_batch = malloc ( sizeof ( * sprite_batch ) ) ;
renderer - > sprite_batch = malloc ( sizeof ( * renderer - > sprite_batch ) ) ;
if ( ! sprite_batch )
if ( ! renderer - > sprite_batch )
{
{
log_error ( " renderer:init " , " Failed to allocated sprite batch " ) ;
log_error ( " renderer:init " , " Failed to allocated sprite batch " ) ;
}
}
else
else
{
{
sprite_batch_create ( sprite_batch , " sprite_map.tga " , " sprite.vert " , " sprite.frag " , GL_TRIANGLES ) ;
sprite_batch_create ( renderer - > sprite_batch , " sprite_map.tga " , " sprite.vert " , " sprite.frag " , GL_TRIANGLES ) ;
}
}
im_init ( ) ;
im_init ( ) ;
// Initialize materials
for ( int i = 0 ; i < MAT_MAX ; i + + )
{
material_init ( & renderer - > materials [ i ] , i ) ;
}
}
}
void renderer_draw ( struct Entity * active_viewer )
void renderer_draw ( struct Renderer * renderer , struct Scene * scene )
{
{
/* Render each camera output into it's framebuffer or to the default framebuffer */
/* Render each camera output into it's framebuffer or to the default framebuffer */
struct Entity * entity_list = entity_get_all ( ) ;
for ( int i = 0 ; i < MAX_CAMERAS ; i + + )
for ( int i = 0 ; i < array_len ( entity_list ) ; i + + )
{
{
struct Entity * viewer = & entity_list [ i ] ;
struct Camera * camera = & scene - > cameras [ i ] ;
if ( entity_list [ i ] . type ! = ET_CAMERA ) continue ;
if ( ! camera - > base . active ) continue ;
struct Camera * camera = & viewer - > camera ;
int fbo = camera - > fbo = = - 1 ? def_fbo : camera - > fbo ;
int fbo = camera - > fbo = = - 1 ? renderer - > def_fbo : camera - > fbo ;
framebuffer_bind ( fbo ) ;
framebuffer_bind ( fbo ) ;
{
{
glViewport ( 0 , 0 , framebuffer_width_get ( fbo ) , framebuffer_height_get ( fbo ) ) ;
glViewport ( 0 , 0 , framebuffer_width_get ( fbo ) , framebuffer_height_get ( fbo ) ) ;
@ -160,35 +152,34 @@ void renderer_draw(struct Entity* active_viewer)
glCullFace ( GL_BACK ) ;
glCullFace ( GL_BACK ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
static mat4 mvp ;
static mat4 mvp ;
struct Material * material_list = material_get_all_materials ( ) ;
for ( int i = 0 ; i < MAT_MAX ; i + + )
for ( int i = 0 ; i < array_len ( material_list ) ; i + + )
{
{
/* for each material, get all the registered models and render them */
/* for each material, get all the registered models and render them */
struct Material * material = & material_li st [ i ] ;
struct Material * material = & renderer - > materials [ i ] ;
if ( ! material - > active | | array_len ( material - > registered_models ) = = 0 )
if ( array_len ( material - > registered_models ) = = 0 )
continue ;
continue ;
shader_bind ( material - > shader ) ;
GL_CHECK ( shader_bind ( material - > shader ) ) ;
renderer_check_glerror ( " model:render_all:shader_bind " ) ;
if ( material - > lit ) /* Set light information */
if ( material - > lit ) /* Set light information */
{
{
int valid_light_count = 0 ;
int * light_index_list = light_get_valid_indices ( & valid_light_count ) ;
char uniform_name [ MAX_UNIFORM_NAME_LEN ] ;
char uniform_name [ MAX_UNIFORM_NAME_LEN ] ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
for ( int i = 0 ; i < valid_light_count ; i + + )
int light_count = 0 ;
for ( int i = 0 ; i < MAX_LIGHTS ; i + + )
{
{
struct Entity * light_entity = entity_get ( light_index_list [ i ] ) ;
struct Light * light = & scene - > lights [ i ] ; /* TODO: Cull lights according to camera frustum */
struct Light * light = & light_entity - > light ; /* TODO: Cull lights according to camera frustum */
if ( ! light - > base . active ) continue ;
light_count + + ;
vec3 light_pos = { 0 , 0 , 0 } ;
vec3 light_pos = { 0 , 0 , 0 } ;
transform_get_absolute_position ( light_entity , & light_pos ) ;
transform_get_absolute_position ( & light - > base , & light_pos ) ;
if ( light - > type ! = LT_POINT )
if ( light - > type ! = LT_POINT )
{
{
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].direction " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].direction " , l ight_count ) ;
vec3 light_dir = { 0.f , 0.f , 0.f } ;
vec3 light_dir = { 0.f , 0.f , 0.f } ;
transform_get_absolute_lookat ( light_entity , & light_dir ) ;
transform_get_absolute_lookat ( & light - > base , & light_dir ) ;
vec3_norm ( & light_dir , & light_dir ) ;
vec3_norm ( & light_dir , & light_dir ) ;
shader_set_uniform_vec3 ( material - > shader , uniform_name , & light_dir ) ;
shader_set_uniform_vec3 ( material - > shader , uniform_name , & light_dir ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
@ -196,171 +187,123 @@ void renderer_draw(struct Entity* active_viewer)
if ( light - > type ! = LT_DIR )
if ( light - > type ! = LT_DIR )
{
{
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].position " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].position " , l ight_count ) ;
shader_set_uniform_vec3 ( material - > shader , uniform_name , & light_pos ) ;
shader_set_uniform_vec3 ( material - > shader , uniform_name , & light_pos ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].outer_angle " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].outer_angle " , l ight_count ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > outer_angle ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > outer_angle ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].inner_angle " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].inner_angle " , l ight_count ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > inner_angle ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > inner_angle ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].falloff " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].falloff " , l ight_count ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > falloff ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > falloff ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].radius " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].radius " , l ight_count ) ;
shader_set_uniform_int ( material - > shader , uniform_name , light - > radius ) ;
shader_set_uniform_int ( material - > shader , uniform_name , light - > radius ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
}
}
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].color " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].color " , l ight_count ) ;
shader_set_uniform_vec3 ( material - > shader , uniform_name , & light - > color ) ;
shader_set_uniform_vec3 ( material - > shader , uniform_name , & light - > color ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].intensity " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].intensity " , l ight_count ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > intensity ) ;
shader_set_uniform_float ( material - > shader , uniform_name , light - > intensity ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].type " , i ) ;
snprintf ( uniform_name , MAX_UNIFORM_NAME_LEN , " lights[%d].type " , l ight_count ) ;
shader_set_uniform_int ( material - > shader , uniform_name , light - > type ) ;
shader_set_uniform_int ( material - > shader , uniform_name , light - > type ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
memset ( uniform_name , ' \0 ' , MAX_UNIFORM_NAME_LEN ) ;
}
}
shader_set_uniform_int ( material - > shader , " total_active_lights " , valid_light_count ) ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_TOTAL_LIGHTS ] . type , material - > pipeline_params [ MPP_TOTAL_LIGHTS ] . location , & light_count ) ) ;
vec3 camera_pos = { 0 , 0 , 0 } ;
vec3 camera_pos = { 0 , 0 , 0 } ;
transform_get_absolute_position ( viewer , & camera_pos ) ;
transform_get_absolute_position ( & camera - > base , & camera_pos ) ;
shader_set_uniform_vec3 ( material - > shader , " camera_pos " , & camera_pos ) ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_CAM_POS ] . type , material - > pipeline_params [ MPP_CAM_POS ] . location , & camera_pos ) ) ;
}
}
/* Set material pipeline uniforms */
/* Set material pipeline uniforms */
static struct Render_Settings render_settings ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_FOG_MODE ] . type , material - > pipeline_params [ MPP_FOG_MODE ] . location , & renderer - > settings . fog . mode ) ) ;
renderer_settings_get ( & render_settings ) ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_FOG_DENSITY ] . type , material - > pipeline_params [ MPP_FOG_DENSITY ] . location , & renderer - > settings . fog . density ) ) ;
for ( int k = 0 ; k < array_len ( material - > pipeline_params ) ; k + + )
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_FOG_START_DIST ] . type , material - > pipeline_params [ MPP_FOG_START_DIST ] . location , & renderer - > settings . fog . start_dist ) ) ;
{
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_FOG_MAX_DIST ] . type , material - > pipeline_params [ MPP_FOG_MAX_DIST ] . location , & renderer - > settings . fog . max_dist ) ) ;
struct Uniform * uniform = & material - > pipeline_params [ k ] ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_FOG_COLOR ] . type , material - > pipeline_params [ MPP_FOG_COLOR ] . location , & renderer - > settings . fog . color ) ) ;
if ( strcmp ( uniform - > name , " view_mat " ) = = 0 )
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_AMBIENT_LIGHT ] . type , material - > pipeline_params [ MPP_AMBIENT_LIGHT ] . location , & renderer - > settings . ambient_light ) ) ;
{
if ( material - > lit ) GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_VIEW_MAT ] . type , material - > pipeline_params [ MPP_VIEW_MAT ] . location , & camera - > view_mat ) ) ;
shader_set_uniform ( uniform - > type , uniform - > location , & viewer - > camera . view_mat ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " fog.mode " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & render_settings . fog . mode ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " fog.density " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & render_settings . fog . density ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " fog.start_dist " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & render_settings . fog . start_dist ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " fog.max_dist " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & render_settings . fog . max_dist ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " fog.color " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & render_settings . fog . color ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " ambient_light " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & render_settings . ambient_light ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
}
for ( int j = 0 ; j < array_len ( material - > registered_models ) ; j + + )
for ( int j = 0 ; j < array_len ( material - > registered_models ) ; j + + )
{
{
/* for each registered model, set up uniforms and render */
/* for each registered model, set up uniforms and render */
struct Entity * entity = entity_get ( material - > registered_models [ j ] ) ;
struct Static_Mesh * mesh = material - > registered_models [ i ] ;
struct Model * model = & entity - > model ;
struct Geometry * geometry = geom_get ( mesh - > model . geometry_index ) ;
struct Transform * transform = & entity - > transform ;
struct Geometry * geometry = geom_get ( model - > geometry_index ) ;
/* Check if model is in frustum */
/* Check if model is in frustum */
int intersection = bv_intersect_frustum_sphere ( viewer - > camera . frustum , & geometry - > bounding_sphere , entity ) ;
vec3 abs_pos , abs_scale ;
transform_get_absolute_position ( & mesh - > base , & abs_pos ) ;
transform_get_absolute_scale ( & mesh - > base , & abs_scale ) ;
int intersection = bv_intersect_frustum_sphere ( & camera - > frustum , & geometry - > bounding_sphere , & abs_pos , & abs_scale ) ;
if ( intersection = = IT_OUTSIDE )
if ( intersection = = IT_OUTSIDE )
{
{
num_culled + + ;
renderer - > num_culled + + ;
continue ;
continue ;
}
}
else
else
{
{
num_indices + = array_len ( geometry - > indices ) ;
renderer - > num_indices + = array_len ( geometry - > indices ) ;
num_rendered + + ;
renderer - > num_rendered + + ;
}
}
/* set material params for the model */
/* set material params for the model */
for ( int k = 0 ; k < array_len ( model - > material_params ) ; k + + )
for ( int k = 0 ; k < MMP_MAX ; k + + )
{
{
struct Material_Param * param = & model - > material_params [ k ] ;
switch ( mesh - > model . material_params [ i ] . type )
struct Uniform * uniform = & material - > model_params [ param - > uniform_index ] ;
{
shader_set_uniform ( uniform - > type , uniform - > location , param - > value ) ;
case VT_INT : GL_CHECK ( shader_set_uniform ( material - > model_params [ i ] . type , material - > model_params [ i ] . location , & mesh - > model . material_params [ i ] . val_int ) ) ; break ;
renderer_check_glerror ( " model:render_all:material_param " ) ;
case VT_FLOAT : GL_CHECK ( shader_set_uniform ( material - > model_params [ i ] . type , material - > model_params [ i ] . location , & mesh - > model . material_params [ i ] . val_float ) ) ; break ;
case VT_VEC3 : GL_CHECK ( shader_set_uniform ( material - > model_params [ i ] . type , material - > model_params [ i ] . location , & mesh - > model . material_params [ i ] . val_vec3 ) ) ; break ;
case VT_VEC4 : GL_CHECK ( shader_set_uniform ( material - > model_params [ i ] . type , material - > model_params [ i ] . location , & mesh - > model . material_params [ i ] . val_vec4 ) ) ; break ;
}
}
}
/* Set pipeline uniforms that are derived per model */
/* Set pipeline uniforms that are derived per model */
for ( int k = 0 ; k < array_len ( material - > pipeline_params ) ; k + + )
mat4_identity ( & mvp ) ;
mat4_mul ( & mvp , & camera - > view_proj_mat , & mesh - > base . transform . trans_mat ) ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_MVP ] . type , material - > pipeline_params [ MPP_MVP ] . location , & mvp ) ) ;
if ( material - > lit )
{
{
/* TODO: change this into something better */
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_VIEW_MAT ] . type , material - > pipeline_params [ MPP_VIEW_MAT ] . location , & camera - > view_mat ) ) ;
struct Uniform * uniform = & material - > pipeline_params [ k ] ;
mat4 inv_mat ;
if ( strcmp ( uniform - > name , " mvp " ) = = 0 )
mat4_identity ( & inv_mat ) ;
{
mat4_inverse ( & inv_mat , & mesh - > base . transform . trans_mat ) ;
mat4_identity ( & mvp ) ;
GL_CHECK ( shader_set_uniform ( material - > pipeline_params [ MPP_INV_MODEL_MAT ] . type , material - > pipeline_params [ MPP_INV_MODEL_MAT ] . location , & inv_mat ) ) ;
mat4_mul ( & mvp , & viewer - > camera . view_proj_mat , & transform - > trans_mat ) ;
shader_set_uniform ( uniform - > type , uniform - > location , & mvp ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " model_mat " ) = = 0 )
{
shader_set_uniform ( uniform - > type , uniform - > location , & transform - > trans_mat ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
else if ( strcmp ( uniform - > name , " inv_model_mat " ) = = 0 )
{
mat4 inv_mat ;
mat4_identity ( & inv_mat ) ;
mat4_inverse ( & inv_mat , & transform - > trans_mat ) ;
shader_set_uniform ( uniform - > type , uniform - > location , & inv_mat ) ;
renderer_check_glerror ( " model:render_all:material_pipeline " ) ;
}
}
}
/* Render the geometry */
/* Render the geometry */
//int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode);
//int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode);
//geom_render(model->geometry_index, draw_mode);
//geom_render(model->geometry_index, draw_mode);
geom_render ( model - > geometry_index , GDM_TRIANGLES ) ;
geom_render ( mesh - > model . geometry_index , GDM_TRIANGLES ) ;
for ( int k = 0 ; k < array_len ( model - > material_params ) ; k + + )
for ( int k = 0 ; k < MMP_MAX ; k + + )
{
{
/* unbind textures, if any */
/* unbind textures, if any */
struct Material_Param * param = & model - > material_params [ k ] ;
if ( material - > model_params [ k ] . type = = UT_TEX )
struct Uniform * uniform = & material - > model_params [ param - > uniform_index ] ;
GL_CHECK ( texture_unbind ( mesh - > model . material_params [ k ] . val_int ) ) ;
if ( uniform - > type = = UT_TEX )
{
texture_unbind ( * ( int * ) param - > value ) ;
renderer_check_glerror ( " model:render_all:unbind_texture_uniform " ) ;
}
}
}
}
}
shader_unbind ( ) ;
shader_unbind ( ) ;
}
}
editor_debugvar_slot_set_int ( num_rendered_slot , num_rendered ) ;
editor_debugvar_slot_set_int ( renderer - > num_rendered_slot , renderer - > num_rendered ) ;
editor_debugvar_slot_set_int ( num_culled_slot , num_culled ) ;
editor_debugvar_slot_set_int ( renderer - > num_culled_slot , renderer - > num_culled ) ;
editor_debugvar_slot_set_int ( num_indices_slot , num_indices ) ;
editor_debugvar_slot_set_int ( renderer - > num_indices_slot , renderer - > num_indices ) ;
num_culled = num_rendered = num_indices = 0 ;
renderer - > num_culled = renderer - > num_rendered = renderer - > num_indices = 0 ;
}
}
framebuffer_unbind ( ) ;
framebuffer_unbind ( ) ;
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_DEPTH_TEST ) ;
@ -368,16 +311,16 @@ void renderer_draw(struct Entity* active_viewer)
}
}
/* Final Render */
/* Final Render */
struct Camera * active_camera = & scene - > cameras [ scene - > active_camera_index ] ;
int width , height ;
int width , height ;
struct Game_State * game_state = game_state_get ( ) ;
struct Game_State * game_state = game_state_get ( ) ;
platform - > window . get_size ( game_state - > window , & width , & height ) ;
platform - > window . get_size ( game_state - > window , & width , & height ) ;
glViewport ( 0 , 0 , width , height ) ;
glViewport ( 0 , 0 , width , height ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
shader_bind ( composition_shader ) ;
shader_bind ( renderer - > composition_shader ) ;
struct Camera * active_camera = & active_viewer - > camera ;
int final_render_tex = active_camera - > render_tex = = - 1 ? renderer - > def_albedo_tex : active_camera - > render_tex ;
int final_render_tex = active_camera - > render_tex = = - 1 ? def_albedo_tex : active_camera - > render_tex ;
texture_bind ( final_render_tex ) ;
texture_bind ( final_render_tex ) ;
geom_render ( quad_geo , GDM_TRIANGLES ) ;
geom_render ( renderer - > quad_geo , GDM_TRIANGLES ) ;
texture_unbind ( final_render_tex ) ;
texture_unbind ( final_render_tex ) ;
shader_unbind ( ) ;
shader_unbind ( ) ;
@ -387,20 +330,20 @@ void renderer_draw(struct Entity* active_viewer)
{
{
glPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ) ;
glPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ) ;
vec4 debug_draw_color = hashmap_vec4_get ( cvars , " debug_draw_color " ) ;
vec4 debug_draw_color = hashmap_vec4_get ( cvars , " debug_draw_color " ) ;
shader_bind ( debug_shader ) ;
shader_bind ( renderer - > debug_shader ) ;
{
{
static mat4 mvp ;
static mat4 mvp ;
shader_set_uniform_vec4 ( debug_shader , " debug_color " , & debug_draw_color ) ;
shader_set_uniform_vec4 ( renderer - > debug_shader , " debug_color " , & debug_draw_color ) ;
struct Entity * entity_list = entity_get_all ( ) ;
for ( int i = 0 ; i < MAX_STATIC_MESHES ; i + + )
for ( int i = 0 ; i < array_len ( entity_list ) ; i + + )
{
{
if ( ! entity_list [ i ] . renderable ) continue ;
struct Static_Mesh * mesh = & scene - > static_meshes [ i ] ;
struct Model * model = & entity_list [ i ] . model ;
if ( ! mesh - > base . active ) continue ;
struct Transform * transform = & entity_list [ i ] . transform ;
struct Model * model = & mesh - > model ;
struct Transform * transform = & mesh - > base . transform ;
int geometry = model - > geometry_index ;
int geometry = model - > geometry_index ;
mat4_identity ( & mvp ) ;
mat4_identity ( & mvp ) ;
mat4_mul ( & mvp , & active_viewer - > camera . view_proj_mat , & transform - > trans_mat ) ;
mat4_mul ( & mvp , & active_camera - > view_proj_mat , & transform - > trans_mat ) ;
shader_set_uniform_mat4 ( debug_shader , " mvp " , & mvp ) ;
shader_set_uniform_mat4 ( renderer - > debug_shader , " mvp " , & mvp ) ;
geom_render ( geometry , hashmap_int_get ( cvars , " debug_draw_mode " ) ) ;
geom_render ( geometry , hashmap_int_get ( cvars , " debug_draw_mode " ) ) ;
}
}
}
}
@ -412,39 +355,38 @@ void renderer_draw(struct Entity* active_viewer)
if ( hashmap_bool_get ( cvars , " debug_draw_physics " ) )
if ( hashmap_bool_get ( cvars , " debug_draw_physics " ) )
{
{
static vec4 physics_draw_color = { 0.f , 0.f , 1.f , 1.f } ;
static vec4 physics_draw_color = { 0.f , 0.f , 1.f , 1.f } ;
struct Entity * entity_list = entity_get_all ( ) ;
for ( int i = 0 ; i < MAX_STATIC_MESHES ; i + + )
for ( int i = 0 ; i < array_len ( entity_list ) ; i + + )
{
{
if ( ! entity_list [ i ] . has_collision ) continue ;
struct Static_Mesh * mesh = & scene - > static_meshes [ i ] ;
struct Entity * entity = & entity_list [ i ] ;
if ( ! mesh - > base . active | | ( ! mesh - > collision . collision_shape & & ! mesh - > collision . rigidbody ) ) continue ;
//Get collision mesh and it's props then render it
//Get collision mesh and it's props then render it
vec3 pos = { 0.f } ;
vec3 pos = { 0.f } ;
quat rot = { 0.f , 0.f , 0.f , 1.f } ;
quat rot = { 0.f , 0.f , 0.f , 1.f } ;
if ( entity - > collision . rigidbody )
if ( mesh - > collision . rigidbody )
{
{
platform - > physics . body_position_get ( entity - > collision . rigidbody , & pos . x , & pos . y , & pos . z ) ;
platform - > physics . body_position_get ( mesh - > collision . rigidbody , & pos . x , & pos . y , & pos . z ) ;
platform - > physics . body_rotation_get ( entity - > collision . rigidbody , & rot . x , & rot . y , & rot . z , & rot . w ) ;
platform - > physics . body_rotation_get ( mesh - > collision . rigidbody , & rot . x , & rot . y , & rot . z , & rot . w ) ;
}
}
else
else
{
{
platform - > physics . cs_position_get ( entity - > collision . collision_shape , & pos . x , & pos . y , & pos . z ) ;
platform - > physics . cs_position_get ( mesh - > collision . collision_shape , & pos . x , & pos . y , & pos . z ) ;
platform - > physics . cs_rotation_get ( entity - > collision . collision_shape , & rot . x , & rot . y , & rot . z , & rot . w ) ;
platform - > physics . cs_rotation_get ( mesh - > collision . collision_shape , & rot . x , & rot . y , & rot . z , & rot . w ) ;
}
}
int collision_shape_type = platform - > physics . cs_type_get ( entity - > collision . collision_shape ) ;
int collision_shape_type = platform - > physics . cs_type_get ( mesh - > collision . collision_shape ) ;
switch ( collision_shape_type )
switch ( collision_shape_type )
{
{
case CST_SPHERE :
case CST_SPHERE :
{
{
float radius = platform - > physics . cs_sphere_radius_get ( entity - > collision . collision_shape ) ;
float radius = platform - > physics . cs_sphere_radius_get ( mesh - > collision . collision_shape ) ;
im_sphere ( radius , pos , rot , physics_draw_color , GDM_TRIANGLES ) ;
im_sphere ( radius , pos , rot , physics_draw_color , GDM_TRIANGLES ) ;
}
}
break ;
break ;
case CST_BOX :
case CST_BOX :
{
{
float x = 0.f , y = 0.f , z = 0.f ;
float x = 0.f , y = 0.f , z = 0.f ;
platform - > physics . cs_box_params_get ( entity - > collision . collision_shape , & x , & y , & z ) ;
platform - > physics . cs_box_params_get ( mesh - > collision . collision_shape , & x , & y , & z ) ;
im_box ( x , y , z , pos , rot , physics_draw_color , GDM_TRIANGLES ) ;
im_box ( x , y , z , pos , rot , physics_draw_color , GDM_TRIANGLES ) ;
} ;
} ;
break ;
break ;
@ -454,11 +396,11 @@ void renderer_draw(struct Entity* active_viewer)
}
}
//Immediate mode geometry render
//Immediate mode geometry render
im_render ( active_viewer ) ;
im_render ( active_camera ) ;
/* Render 2D stuff */
/* Render 2D stuff */
shader_bind ( sprite_batch - > shader ) ;
shader_bind ( renderer - > sprite_batch - > shader ) ;
{
{
static mat4 ortho_mat ;
static mat4 ortho_mat ;
mat4_identity ( & ortho_mat ) ;
mat4_identity ( & ortho_mat ) ;
@ -467,9 +409,9 @@ void renderer_draw(struct Entity* active_viewer)
platform - > window . get_size ( game_state - > window , & width , & height ) ;
platform - > window . get_size ( game_state - > window , & width , & height ) ;
mat4_ortho ( & ortho_mat , 0.f , ( float ) width , ( float ) height , 0.f , - 10.f , 10.f ) ;
mat4_ortho ( & ortho_mat , 0.f , ( float ) width , ( float ) height , 0.f , - 10.f , 10.f ) ;
shader_set_uniform_mat4 ( sprite_batch - > shader , " mvp " , & ortho_mat ) ;
shader_set_uniform_mat4 ( renderer - > sprite_batch - > shader , " mvp " , & ortho_mat ) ;
sprite_batch_render ( sprite_batch ) ;
sprite_batch_render ( renderer - > sprite_batch ) ;
}
}
shader_unbind ( ) ;
shader_unbind ( ) ;
@ -477,28 +419,30 @@ void renderer_draw(struct Entity* active_viewer)
gui_render ( NK_ANTI_ALIASING_ON ) ;
gui_render ( NK_ANTI_ALIASING_ON ) ;
}
}
void renderer_cleanup ( void )
void renderer_cleanup ( struct Renderer * renderer )
{
{
for ( int i = 0 ; i < MAT_MAX ; i + + )
{
material_reset ( & renderer - > materials [ i ] , i ) ;
}
im_cleanup ( ) ;
im_cleanup ( ) ;
sprite_batch_remove ( sprite_batch ) ;
sprite_batch_remove ( renderer - > sprite_batch ) ;
free ( sprite_batch ) ;
free ( renderer - > sprite_batch ) ;
gui_cleanup ( ) ;
gui_cleanup ( ) ;
geom_remove ( quad_geo ) ;
geom_remove ( renderer - > quad_geo ) ;
framebuffer_remove ( def_fbo ) ;
framebuffer_remove ( renderer - > def_fbo ) ;
texture_remove ( def_albedo_tex ) ;
texture_remove ( renderer - > def_albedo_tex ) ;
texture_remove ( def_depth_tex ) ;
texture_remove ( renderer - > def_depth_tex ) ;
}
}
void on_framebuffer_size_change ( int width , int height )
void on_framebuffer_size_change ( int width , int height )
{
{
struct Entity * entity_list = entity_get_all ( ) ;
struct Scene * scene = & game_state_get ( ) - > scene ;
float aspect = ( float ) width / ( float ) height ;
float aspect = ( float ) width / ( float ) height ;
for ( int i = 0 ; i < array_len ( entity_list ) ; i + + )
for ( int i = 0 ; i < MAX_CAMERAS ; i + + )
{
{
struct Entity * viewer = & entity_list [ i ] ;
struct Camera * viewer = & scene - > cameras [ i ] ;
if ( viewer - > type ! = ET_CAMERA ) continue ;
viewer - > aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f ;
viewer - > camera . aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f ;
camera_update_proj ( viewer ) ;
camera_update_proj ( viewer ) ;
}
}
@ -533,9 +477,9 @@ int renderer_check_glerror(const char* context)
return error ;
return error ;
}
}
struct Sprite_Batch * get_batch ( void )
struct Material * renderer_material_get ( int material_type )
{
{
return sprite_batch ;
return NULL ;
}
}
void renderer_debug_draw_enabled ( bool enabled )
void renderer_debug_draw_enabled ( bool enabled )