Simplified rendering by removing unnecessary fbos and rendering to backbuffer directly which also brought back msaa

dev
Shariq Shah 6 years ago
parent 1447a9403f
commit 33c2ea7ceb
  1. 2
      src/common/version.h
  2. 16
      src/game/editor.c
  3. 2
      src/game/editor.h
  4. 14
      src/game/player.c
  5. 378
      src/game/renderer.c
  6. 5
      src/game/renderer.h
  7. 2
      src/game/scene.c
  8. 16
      todo.txt

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */ /* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0 #define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1 #define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 302 #define SYMMETRY_VERSION_REVISION 303
#define SYMMETRY_VERSION_BRANCH "dev" #define SYMMETRY_VERSION_BRANCH "dev"
#endif #endif

@ -170,7 +170,7 @@ void editor_init_entities(struct Editor* editor)
editor->cursor_entity->base.flags |= EF_TRANSIENT | EF_SKIP_RENDER | EF_HIDE_IN_EDITOR_SCENE_HIERARCHY | EF_IGNORE_RAYCAST; editor->cursor_entity->base.flags |= EF_TRANSIENT | EF_SKIP_RENDER | EF_HIDE_IN_EDITOR_SCENE_HIERARCHY | EF_IGNORE_RAYCAST;
} }
void editor_init_camera(struct Editor* editor, struct Hashmap* cvars) void editor_camera_init(struct Editor* editor, struct Hashmap* cvars)
{ {
struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR];
entity_rename(editor_camera, "Editor_Camera"); entity_rename(editor_camera, "Editor_Camera");
@ -180,13 +180,13 @@ void editor_init_camera(struct Editor* editor, struct Hashmap* cvars)
editor_camera->clear_color.z = 0.9f; editor_camera->clear_color.z = 0.9f;
editor_camera->clear_color.w = 1.f; editor_camera->clear_color.w = 1.f;
if(editor_camera->fbo == -1) //if(editor_camera->fbo == -1)
{ //{
int render_width = hashmap_int_get(cvars, "render_width"); // int render_width = hashmap_int_get(cvars, "render_width");
int render_height = hashmap_int_get(cvars, "render_height"); // int render_height = hashmap_int_get(cvars, "render_height");
window_get_drawable_size(game_state_get()->window, &render_width, &render_height); // window_get_drawable_size(game_state_get()->window, &render_width, &render_height);
camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); // camera_attach_fbo(editor_camera, render_width, render_height, true, true, true);
} //}
vec3 cam_pos = {5.f, 20.f, 50.f}; vec3 cam_pos = {5.f, 20.f, 50.f};
transform_translate(editor_camera, &cam_pos, TS_WORLD); transform_translate(editor_camera, &cam_pos, TS_WORLD);

@ -60,7 +60,7 @@ struct Editor
}; };
void editor_init(struct Editor* editor_state); void editor_init(struct Editor* editor_state);
void editor_init_camera(struct Editor* editor_state, struct Hashmap* cvars); void editor_camera_init(struct Editor* editor_state, struct Hashmap* cvars);
void editor_init_entities(struct Editor* editor); void editor_init_entities(struct Editor* editor);
void editor_render(struct Editor* editor_state, struct Camera* active_camera); void editor_render(struct Editor* editor_state, struct Camera* active_camera);
void editor_update(struct Editor* editor_state, float dt); void editor_update(struct Editor* editor_state, float dt);

@ -42,13 +42,13 @@ void player_init(struct Player* player, struct Scene* scene)
player->camera_node->base.flags |= EF_TRANSIENT; player->camera_node->base.flags |= EF_TRANSIENT;
player->mesh->base.flags |= EF_TRANSIENT; player->mesh->base.flags |= EF_TRANSIENT;
if(player_camera->fbo == -1) //if(player_camera->fbo == -1)
{ //{
int render_width = hashmap_int_get(config, "render_width"); // int render_width = hashmap_int_get(config, "render_width");
int render_height = hashmap_int_get(config, "render_height"); // int render_height = hashmap_int_get(config, "render_height");
window_get_drawable_size(game_state->window, &render_width, &render_height); // window_get_drawable_size(game_state->window, &render_width, &render_height);
camera_attach_fbo(player_camera, render_width, render_height, true, true, true); // camera_attach_fbo(player_camera, render_width, render_height, true, true, true);
} //}
transform_parent_set(player_camera, player, true); transform_parent_set(player_camera, player, true);

@ -59,286 +59,191 @@ void renderer_init(struct Renderer* renderer)
renderer->settings.debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); renderer->settings.debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color");
renderer->settings.ambient_light = hashmap_vec3_get(cvars, "ambient_light"); renderer->settings.ambient_light = hashmap_vec3_get(cvars, "ambient_light");
/* Quad geometry for final render */ renderer->debug_shader = shader_create("debug.vert", "debug.frag", NULL);
vec3* vertices = array_new(vec3);
vec2* uvs = array_new(vec2);
vec3* normals = array_new(vec3);
uint* indices = array_new(uint);
vec3 temp_v3;
vec2 temp_v2;
/* Vertices */
temp_v3.x = -1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
temp_v3.x = 1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
temp_v3.x = 1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
temp_v3.x = -1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
/* Normals */
temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3);
temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3);
/* Uvs */
temp_v2.x = 0; temp_v2.y = 0; array_push(uvs, temp_v2, vec2);
temp_v2.x = 1; temp_v2.y = 0; array_push(uvs, temp_v2, vec2);
temp_v2.x = 1; temp_v2.y = 1; array_push(uvs, temp_v2, vec2);
temp_v2.x = 0; temp_v2.y = 1; array_push(uvs, temp_v2, vec2);
/* Indices */
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);
renderer->quad_geo = geom_create("Quad", vertices, uvs, normals, indices, NULL);
array_free(vertices);
array_free(uvs);
array_free(normals);
array_free(indices);
int width = -1, height = -1;
window_get_size(game_state->window, &width, &height);
renderer->def_albedo_tex = texture_create("def_albedo_texture",
TU_DIFFUSE,
width, height,
GL_RGB,
GL_RGB16F,
GL_FLOAT,
NULL);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
renderer->def_depth_tex = texture_create("def_depth_texture",
TU_SHADOWMAP4,
width, height,
GL_DEPTH_COMPONENT,
GL_DEPTH_COMPONENT32F,
GL_FLOAT,
NULL);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
renderer->def_fbo = framebuffer_create(width, height, true, false, true);
framebuffer_texture_set(renderer->def_fbo, renderer->def_albedo_tex, FA_COLOR_ATTACHMENT0);
framebuffer_texture_set(renderer->def_fbo, renderer->def_depth_tex, FA_DEPTH_ATTACHMENT);
renderer->composition_shader = shader_create("fbo.vert", "fbo.frag", NULL);
renderer->debug_shader = shader_create("debug.vert", "debug.frag", NULL);
// renderer->num_culled_slot = editor_debugvar_slot_create("Culled Geom", VT_INT);
// renderer->num_rendered_slot = editor_debugvar_slot_create("Rendered Geom", VT_INT);
// renderer->num_indices_slot = editor_debugvar_slot_create("Total Indices", VT_INT);
renderer->sprite_batch = malloc(sizeof(*renderer->sprite_batch)); renderer->sprite_batch = malloc(sizeof(*renderer->sprite_batch));
if(!renderer->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(renderer->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 // Initialize materials
for(int i = 0; i < MAT_MAX; i++) for(int i = 0; i < MAT_MAX; i++)
{
material_init(&renderer->materials[i], i); material_init(&renderer->materials[i], i);
}
} }
void renderer_render(struct Renderer* renderer, struct Scene* scene) void renderer_render(struct Renderer* renderer, struct Scene* scene)
{ {
struct Camera* camera = &scene->cameras[scene->active_camera_index]; struct Game_State* game_state = game_state_get();
int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo; struct Camera* active_camera = &scene->cameras[scene->active_camera_index];
framebuffer_bind(fbo); int width = 0, height = 0;
window_get_drawable_size(game_state->window, &width, &height);
glViewport(0, 0, width, height);
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearColor(active_camera->clear_color.x,
active_camera->clear_color.y,
active_camera->clear_color.z,
active_camera->clear_color.w);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static mat4 mvp;
for(int i = 0; i < MAT_MAX; i++)
{ {
glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo)); /* for each material, get all the registered models and render them */
glEnable(GL_DEPTH_TEST); struct Material* material = &renderer->materials[i];
glDepthFunc(GL_LEQUAL); GL_CHECK(shader_bind(material->shader));
glClearColor(camera->clear_color.x,
camera->clear_color.y,
camera->clear_color.z,
camera->clear_color.w);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static mat4 mvp;
for(int i = 0; i < MAT_MAX; i++)
{
/* for each material, get all the registered models and render them */
struct Material* material = &renderer->materials[i];
GL_CHECK(shader_bind(material->shader));
if(material->lit) /* Set light information */ if(material->lit) /* Set light information */
{
char uniform_name[MAX_UNIFORM_NAME_LEN];
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
int light_count = -1;
for(int j = 0; j < MAX_LIGHTS; j++)
{ {
char uniform_name[MAX_UNIFORM_NAME_LEN]; struct Light* light = &scene->lights[j]; /* TODO: Cull lights according to camera frustum */
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); if(!(light->base.flags & EF_ACTIVE) || !light->valid) continue;
int light_count = -1; light_count++;
for(int j = 0; j < MAX_LIGHTS; j++)
vec3 light_pos = { 0, 0, 0 };
transform_get_absolute_position(&light->base, &light_pos);
if(light->type != LT_POINT)
{ {
struct Light* light = &scene->lights[j]; /* TODO: Cull lights according to camera frustum */ snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count);
if(!(light->base.flags & EF_ACTIVE) || !light->valid) continue; vec3 light_dir = { 0.f, 0.f, 0.f };
light_count++; transform_get_absolute_forward(&light->base, &light_dir);
vec3_norm(&light_dir, &light_dir);
vec3 light_pos = { 0, 0, 0 }; shader_set_uniform_vec3(material->shader, uniform_name, &light_dir);
transform_get_absolute_position(&light->base, &light_pos); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
if(light->type != LT_POINT)
{ if(light->type != LT_DIR)
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count); {
vec3 light_dir = { 0.f, 0.f, 0.f }; snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count);
transform_get_absolute_forward(&light->base, &light_dir); shader_set_uniform_vec3(material->shader, uniform_name, &light_pos);
vec3_norm(&light_dir, &light_dir); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
shader_set_uniform_vec3(material->shader, uniform_name, &light_dir);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count);
} shader_set_uniform_float(material->shader, uniform_name, TO_RADIANS(light->outer_angle));
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
if(light->type != LT_DIR)
{ snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count); shader_set_uniform_float(material->shader, uniform_name, TO_RADIANS(light->inner_angle));
shader_set_uniform_vec3(material->shader, uniform_name, &light_pos);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, TO_RADIANS(light->outer_angle));
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, TO_RADIANS(light->inner_angle));
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->falloff);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->radius);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count);
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", light_count); snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->intensity); 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].type", light_count); snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->type); 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);
} }
light_count++; // this variable is going to be sent as a uniform and be used for looping an array so increase its length by one snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count)); shader_set_uniform_vec3(material->shader, uniform_name, &light->color);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->intensity);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
vec3 camera_pos = { 0, 0, 0 }; snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count);
transform_get_absolute_position(&camera->base, &camera_pos); shader_set_uniform_int(material->shader, uniform_name, light->type);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos)); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
} }
/* Set material pipeline uniforms */ light_count++; // this variable is going to be sent as a uniform and be used for looping an array so increase its length by one
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode)); GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density));
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));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color));
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));
vec3 camera_pos = { 0, 0, 0 };
transform_get_absolute_position(&active_camera->base, &camera_pos);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos));
}
for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++) /* Set material pipeline uniforms */
{ GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode));
if(!material->registered_static_meshes[j] || (material->registered_static_meshes[j]->base.flags & EF_SKIP_RENDER)) continue; GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density));
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));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color));
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, &active_camera->view_mat));
/* for each registered model, set up uniforms and render */
struct Static_Mesh* mesh = material->registered_static_meshes[j];
struct Geometry* geometry = geom_get(mesh->model.geometry_index);
/* Check if model is in frustum */ for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++)
{
if(!material->registered_static_meshes[j] || (material->registered_static_meshes[j]->base.flags & EF_SKIP_RENDER)) continue;
int intersection = bv_intersect_frustum_box(&camera->frustum, &mesh->base.derived_bounding_box); /* for each registered model, set up uniforms and render */
if(intersection == IT_INSIDE || intersection == IT_INTERSECT) struct Static_Mesh* mesh = material->registered_static_meshes[j];
{ struct Geometry* geometry = geom_get(mesh->model.geometry_index);
renderer->num_indices += array_len(geometry->indices);
renderer->num_rendered++;
}
else
{
renderer->num_culled++;
continue;
}
/* set material params for the model */ /* Check if model is in frustum */
for(int k = 0; k < MMP_MAX; k++)
{
switch(mesh->model.material_params[k].type)
{
case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break;
case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break;
case VT_VEC2: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec2)); break;
case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break;
case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break;
}
}
/* Set pipeline uniforms that are derived per model */ int intersection = bv_intersect_frustum_box(&active_camera->frustum, &mesh->base.derived_bounding_box);
mat4_identity(&mvp); if(intersection == IT_INSIDE || intersection == IT_INTERSECT)
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)); renderer->num_indices += array_len(geometry->indices);
renderer->num_rendered++;
}
else
{
renderer->num_culled++;
continue;
}
if(material->lit) /* set material params for the model */
for(int k = 0; k < MMP_MAX; k++)
{
switch(mesh->model.material_params[k].type)
{ {
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat)); case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break;
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat)); case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break;
mat4 inv_mat; case VT_VEC2: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec2)); break;
mat4_identity(&inv_mat); case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break;
mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat); case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break;
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat));
} }
}
/* Render the geometry */ /* Set pipeline uniforms that are derived per model */
//int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode); mat4_identity(&mvp);
//geom_render(model->geometry_index, draw_mode); mat4_mul(&mvp, &active_camera->view_proj_mat, &mesh->base.transform.trans_mat);
geom_render(mesh->model.geometry_index, GDM_TRIANGLES); GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp));
for(int k = 0; k < MMP_MAX; k++) if(material->lit)
{ {
/* unbind textures, if any */ GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &active_camera->view_mat));
if(material->model_params[k].type == UT_TEX) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat));
GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int)); mat4 inv_mat;
} mat4_identity(&inv_mat);
mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat));
} }
shader_unbind();
}
debug_vars_show_int("Rendered", renderer->num_rendered); /* Render the geometry */
debug_vars_show_int("Culled", renderer->num_culled); geom_render(mesh->model.geometry_index, GDM_TRIANGLES);
debug_vars_show_int("Num Indices", renderer->num_indices);
//editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered);
//editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled);
//editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices);
renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0; for(int k = 0; k < MMP_MAX; k++)
{
/* unbind textures, if any */
if(material->model_params[k].type == UT_TEX)
GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int));
}
}
shader_unbind();
} }
framebuffer_unbind();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
/* Final Render */ debug_vars_show_int("Rendered", renderer->num_rendered);
struct Camera* active_camera = &scene->cameras[scene->active_camera_index]; debug_vars_show_int("Culled", renderer->num_culled);
int width, height; debug_vars_show_int("Num Indices", renderer->num_indices);
struct Game_State* game_state = game_state_get();
//window_get_size(game_state->window, &width, &height); renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0;
window_get_drawable_size(game_state->window, &width, &height);
glViewport(0, 0, width, height);
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
shader_bind(renderer->composition_shader);
int final_render_tex = active_camera->render_tex == -1 ? renderer->def_albedo_tex : active_camera->render_tex;
texture_bind(final_render_tex);
geom_render(renderer->quad_geo, GDM_TRIANGLES);
texture_unbind(final_render_tex);
shader_unbind();
/* Debug Render */ /* Debug Render */
if(renderer->settings.debug_draw_enabled) if(renderer->settings.debug_draw_enabled)
@ -416,7 +321,6 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene)
} }
//Immediate mode geometry render //Immediate mode geometry render
// Maybe try binding the old frame buffer, clear the drawing but let the depth buffer remain to check depth?
im_render(active_camera); im_render(active_camera);
/* Render 2D stuff */ /* Render 2D stuff */
@ -448,10 +352,6 @@ void renderer_cleanup(struct Renderer* renderer)
im_cleanup(); im_cleanup();
sprite_batch_remove(renderer->sprite_batch); sprite_batch_remove(renderer->sprite_batch);
free(renderer->sprite_batch); free(renderer->sprite_batch);
geom_remove(renderer->quad_geo);
framebuffer_remove(renderer->def_fbo);
texture_remove(renderer->def_albedo_tex);
texture_remove(renderer->def_depth_tex);
} }
void renderer_on_framebuffer_size_changed(const struct Event* event) void renderer_on_framebuffer_size_changed(const struct Event* event)

@ -38,11 +38,6 @@ struct Render_Settings
struct Renderer struct Renderer
{ {
int def_fbo;
int def_albedo_tex;
int def_depth_tex;
int quad_geo;
int composition_shader;
int debug_shader; int debug_shader;
int num_culled , num_rendered , num_indices; int num_culled , num_rendered , num_indices;
int num_culled_slot, num_rendered_slot, num_indices_slot; int num_culled_slot, num_rendered_slot, num_indices_slot;

@ -72,7 +72,7 @@ void scene_init(struct Scene* scene)
memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN); memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN);
player_init(&scene->player, scene); player_init(&scene->player, scene);
editor_init_camera(game_state->editor, game_state->cvars); editor_camera_init(game_state->editor, game_state->cvars);
editor_init_entities(game_state->editor); editor_init_entities(game_state->editor);
scene->active_camera_index = game_state_get()->game_mode == GAME_MODE_GAME ? CAM_GAME : CAM_EDITOR; scene->active_camera_index = game_state_get()->game_mode == GAME_MODE_GAME ? CAM_GAME : CAM_EDITOR;

@ -7,7 +7,6 @@ Todo:
- Command to create a placeholder entity of a particular type in a file - Command to create a placeholder entity of a particular type in a file
- Reduce the opacity of wireframe around selected entity in editor - Reduce the opacity of wireframe around selected entity in editor
- Release mouse when window loses focus and limit fps - Release mouse when window loses focus and limit fps
? Maybe reuse that same framebuffer/textures for active viewers
? When saving a scene entity entry, save the changed properties as well, that way when the scene is loaded, we load the base properties from archetype and the ones we changed per entry are saved when we saved the entity ? When saving a scene entity entry, save the changed properties as well, that way when the scene is loaded, we load the base properties from archetype and the ones we changed per entry are saved when we saved the entity
this will prevent us from having needless amount of entities with only minor changes from one another this will prevent us from having needless amount of entities with only minor changes from one another
? Split up material declarations into their own separate files. Materials have a base material like Blinn or Unshaded and in the file we save an instance with modified properties. ? Split up material declarations into their own separate files. Materials have a base material like Blinn or Unshaded and in the file we save an instance with modified properties.
@ -15,7 +14,6 @@ Todo:
? Change hierarchical transformations from parent/child to an entity having attachments/slots where another entity can be attached or mounted. This way we can have hierarchical transformations and not have to store ? Change hierarchical transformations from parent/child to an entity having attachments/slots where another entity can be attached or mounted. This way we can have hierarchical transformations and not have to store
a whole enitity hierarchy when saving the entity. When loading the entity, we load the entity and see which entites are attached to it and get references to those entity in the scene, if they are not loaded we could a whole enitity hierarchy when saving the entity. When loading the entity, we load the entity and see which entites are attached to it and get references to those entity in the scene, if they are not loaded we could
either load them there and then or complain to the scene that we couldn't find the attachements and just carry on as usual either load them there and then or complain to the scene that we couldn't find the attachements and just carry on as usual
- When loading entities, show an additional optional textfield where user can enter the name they want for the entity after it is loaded
- Add editor undo for transformation operations - Add editor undo for transformation operations
- Decide how to handle scale when checking sphere-ray intersection - Decide how to handle scale when checking sphere-ray intersection
- Add material export for blender exporter? - Add material export for blender exporter?
@ -34,7 +32,6 @@ Todo:
- Basic Enemy - Basic Enemy
- Main Menu Scene - Main Menu Scene
? Split this todo into gameplay/engine todos ? Split this todo into gameplay/engine todos
- Multisampled buffers to bring back aa
- Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode - Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode
- Folder management api to create/delete folders when none exist. Dirent would suffice for our simple needs? - Folder management api to create/delete folders when none exist. Dirent would suffice for our simple needs?
? Entity creator window to create new types of entities and write them ? Entity creator window to create new types of entities and write them
@ -43,10 +40,8 @@ Todo:
where new entities can be creating by dragging and dropping on to where new entities can be creating by dragging and dropping on to
the current scene the current scene
- Editor related messages/notifications in the bottom status bar - Editor related messages/notifications in the bottom status bar
? Disable entity picking when tool is in use or only allow picking when pressing ALT
? Maybe remove physics engine and ode all together if we're not using it or investigate the memory leaks that it causes if we're going to keep it? ? Maybe remove physics engine and ode all together if we're not using it or investigate the memory leaks that it causes if we're going to keep it?
- Disable editor event recievers on game mode change - Disable editor event recievers on game mode change
- Editor Undo
- Color picker - Color picker
- Color palette, picker and dropper - Color palette, picker and dropper
- Key binding and function to snap editor camera to selected entity - Key binding and function to snap editor camera to selected entity
@ -55,16 +50,11 @@ Todo:
- Mouse warp to opposite side of the window when it reaches bounds - Mouse warp to opposite side of the window when it reaches bounds
- Add other axis combinations like YZ and XY to transform tool - Add other axis combinations like YZ and XY to transform tool
- Transformation space selection for translation, rotation and scale. - Transformation space selection for translation, rotation and scale.
- Subscribe and Unsubscribe based on game mode changes
- Add warning to genie build script when running on windows and WindowsSdkVersion cannot be found. This happens when the script is not run from vcvarsall command prompt - Add warning to genie build script when running on windows and WindowsSdkVersion cannot be found. This happens when the script is not run from vcvarsall command prompt
- Improve README and add a screenshot to make the repository ready for making it public
- Show Transformation deltas for example a line showing where we are to where we are going to be if we click and apply the selected transformation
- Refactor all global application state into 'Application_Context' struct. A single global instance of which is available everywhere - Refactor all global application state into 'Application_Context' struct. A single global instance of which is available everywhere
? Improve bounding sphere calculation ? Improve bounding sphere calculation
- Change the way lights are set as uniforms to remove snprintf calls per frame for every light attribute - Change the way lights are set as uniforms to remove snprintf calls per frame for every light attribute
- Filter Scene hierarchy by search using entity name
- Command interface that allows applying commands to selected entity like r x 30 would rotate the selected entity or entities on x axis by 30 degrees - Command interface that allows applying commands to selected entity like r x 30 would rotate the selected entity or entities on x axis by 30 degrees
- Quick scene filter and entity selection by popping up a menu which has list of entities and fuzzy matches them based on the typed name
- Screen mouse coordinates to world-coordinates for aiming - Screen mouse coordinates to world-coordinates for aiming
- Player projectiles and sounds - Player projectiles and sounds
- Space partitioning and scene handling - Space partitioning and scene handling
@ -85,9 +75,7 @@ Todo:
- Implement Game States - Implement Game States
- Store Materials in new format supported by parser - Store Materials in new format supported by parser
- Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards - Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards
- Add creating distributable build and uploading to itch.io account support to GENie under windows and linux.
- Remove hardcoded numerical values from sscanf and other format strings. - Remove hardcoded numerical values from sscanf and other format strings.
? Recalculated bounding boxes for rotated meshes
? Wrap malloc and free calls in custom functions to track usage ? Wrap malloc and free calls in custom functions to track usage
? File extension checking for asset loading ? File extension checking for asset loading
? Only allocate hashmap bucket when required ? Only allocate hashmap bucket when required
@ -108,6 +96,9 @@ Todo:
- Profit! - Profit!
Improvements: Improvements:
- Quick scene filter and entity selection by popping up a menu which has list of entities and fuzzy matches them based on the typed name
- Filter Scene hierarchy by search using entity name
- Show Transformation deltas for example a line showing where we are to where we are going to be if we click and apply the selected transformation
- Make selected mesh wireframe alpha in editor configurable - Make selected mesh wireframe alpha in editor configurable
- Better naming semantics for example, init/deinit for initialization and cleanup and create/destroy when memory is allocated or deallocated - Better naming semantics for example, init/deinit for initialization and cleanup and create/destroy when memory is allocated or deallocated
- Categorized entity list in editor for example different subtree for lights and static meshes - Categorized entity list in editor for example different subtree for lights and static meshes
@ -403,3 +394,4 @@ Done:
* Show version number in editor and console * Show version number in editor and console
* Save/Load base bounding boxes for entity types other than static mesh * Save/Load base bounding boxes for entity types other than static mesh
* Disabled picking when a tool is active in editor * Disabled picking when a tool is active in editor
* Simplified rendering further and removed unnecessary intermediate fbos
Loading…
Cancel
Save