|
|
@ -17,7 +17,16 @@ |
|
|
|
#include "config_vars.h" |
|
|
|
#include "config_vars.h" |
|
|
|
#include "hashmap.h" |
|
|
|
#include "hashmap.h" |
|
|
|
#include "geometry.h" |
|
|
|
#include "geometry.h" |
|
|
|
|
|
|
|
#include "material.h" |
|
|
|
|
|
|
|
#include "editor.h" |
|
|
|
|
|
|
|
#include "variant.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
#include <stdio.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_fbo = -1; |
|
|
|
static int def_albedo_tex = -1; |
|
|
|
static int def_albedo_tex = -1; |
|
|
|
static int def_depth_tex = -1; |
|
|
|
static int def_depth_tex = -1; |
|
|
@ -25,6 +34,10 @@ static int quad_geo = -1; |
|
|
|
static int composition_shader = -1; |
|
|
|
static int composition_shader = -1; |
|
|
|
static int debug_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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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(void) |
|
|
@ -100,6 +113,10 @@ void renderer_init(void) |
|
|
|
framebuffer_set_texture(def_fbo, def_depth_tex, FA_DEPTH_ATTACHMENT); |
|
|
|
framebuffer_set_texture(def_fbo, def_depth_tex, FA_DEPTH_ATTACHMENT); |
|
|
|
composition_shader = shader_create("fbo.vert", "fbo.frag"); |
|
|
|
composition_shader = shader_create("fbo.vert", "fbo.frag"); |
|
|
|
debug_shader = shader_create("debug.vert", "debug.frag"); |
|
|
|
debug_shader = shader_create("debug.vert", "debug.frag"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
num_culled_slot = editor_debugvar_slot_create("Culled Geom", VT_INT); |
|
|
|
|
|
|
|
num_rendered_slot = editor_debugvar_slot_create("Rendered Geom", VT_INT); |
|
|
|
|
|
|
|
num_indices_slot = editor_debugvar_slot_create("Total Indices", VT_INT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void renderer_draw(struct Entity* active_viewer) |
|
|
|
void renderer_draw(struct Entity* active_viewer) |
|
|
@ -125,31 +142,214 @@ void renderer_draw(struct Entity* active_viewer) |
|
|
|
glEnable(GL_CULL_FACE ); |
|
|
|
glEnable(GL_CULL_FACE ); |
|
|
|
glCullFace(GL_BACK); |
|
|
|
glCullFace(GL_BACK); |
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
|
model_render_all(viewer, GDM_TRIANGLES); |
|
|
|
static mat4 mvp; |
|
|
|
|
|
|
|
struct Material* material_list = material_get_all_materials(); |
|
|
|
|
|
|
|
for(int i = 0; i < array_len(material_list); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
/* for each material, get all the registered models and render them */ |
|
|
|
|
|
|
|
struct Material* material = &material_list[i]; |
|
|
|
|
|
|
|
if(!material->active || array_len(material->registered_models) == 0) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shader_bind(material->shader); |
|
|
|
|
|
|
|
renderer_check_glerror("model:render_all:shader_bind"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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]; |
|
|
|
|
|
|
|
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); |
|
|
|
|
|
|
|
for(int i = 0; i < valid_light_count; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct Entity* light_entity = entity_get(light_index_list[i]); |
|
|
|
|
|
|
|
struct Light* light = &light_entity->light; /* TODO: Cull lights according to camera frustum */ |
|
|
|
|
|
|
|
vec3 light_pos = {0, 0, 0}; |
|
|
|
|
|
|
|
transform_get_absolute_pos(light_entity, &light_pos); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(light->type != LT_POINT) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", i); |
|
|
|
|
|
|
|
transform_get_absolute_lookat(light_entity, &light_pos); |
|
|
|
|
|
|
|
vec3_norm(&light_pos, &light_pos); |
|
|
|
|
|
|
|
shader_set_uniform_vec3(material->shader, uniform_name, &light_pos); |
|
|
|
|
|
|
|
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(light->type != LT_DIR) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", i); |
|
|
|
|
|
|
|
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", i); |
|
|
|
|
|
|
|
shader_set_uniform_float(material->shader, uniform_name, light->outer_angle); |
|
|
|
|
|
|
|
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", i); |
|
|
|
|
|
|
|
shader_set_uniform_float(material->shader, uniform_name, light->inner_angle); |
|
|
|
|
|
|
|
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", i); |
|
|
|
|
|
|
|
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", i); |
|
|
|
|
|
|
|
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", i); |
|
|
|
|
|
|
|
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", i); |
|
|
|
|
|
|
|
shader_set_uniform_float(material->shader, uniform_name, light->intensity); |
|
|
|
|
|
|
|
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", i); |
|
|
|
|
|
|
|
shader_set_uniform_int(material->shader, uniform_name, light->type); |
|
|
|
|
|
|
|
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shader_set_uniform_int(material->shader, "total_active_lights", valid_light_count); |
|
|
|
|
|
|
|
vec3 camera_pos = {0, 0, 0}; |
|
|
|
|
|
|
|
transform_get_absolute_pos(viewer, &camera_pos); |
|
|
|
|
|
|
|
shader_set_uniform_vec3(material->shader, "camera_pos", &camera_pos); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Set material pipeline uniforms */ |
|
|
|
|
|
|
|
static struct Render_Settings render_settings; |
|
|
|
|
|
|
|
renderer_settings_get(&render_settings); |
|
|
|
|
|
|
|
for(int k = 0; k < array_len(material->pipeline_params); k++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct Uniform* uniform = &material->pipeline_params[k]; |
|
|
|
|
|
|
|
if(strcmp(uniform->name, "view_mat") == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
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 each registered model, set up uniforms and render */ |
|
|
|
|
|
|
|
struct Entity* entity = entity_get(material->registered_models[j]); |
|
|
|
|
|
|
|
struct Model* model = &entity->model; |
|
|
|
|
|
|
|
struct Transform* transform = &entity->transform; |
|
|
|
|
|
|
|
struct Geometry* geometry = geom_get(model->geometry_index); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if model is in frustum */ |
|
|
|
|
|
|
|
int intersection = bv_intersect_frustum_sphere(viewer->camera.frustum, &geometry->bounding_sphere, entity); |
|
|
|
|
|
|
|
if(intersection == IT_OUTSIDE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
num_culled++; |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
num_indices += array_len(geometry->indices); |
|
|
|
|
|
|
|
num_rendered++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* set material params for the model */ |
|
|
|
|
|
|
|
for(int k = 0; k < array_len(model->material_params); k++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct Material_Param* param = &model->material_params[k]; |
|
|
|
|
|
|
|
struct Uniform* uniform = &material->model_params[param->uniform_index]; |
|
|
|
|
|
|
|
shader_set_uniform(uniform->type, uniform->location, param->value); |
|
|
|
|
|
|
|
renderer_check_glerror("model:render_all:material_param"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Set pipeline uniforms that are derived per model */ |
|
|
|
|
|
|
|
for(int k = 0; k < array_len(material->pipeline_params); k++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
/* TODO: change this into something better */ |
|
|
|
|
|
|
|
struct Uniform* uniform = &material->pipeline_params[k]; |
|
|
|
|
|
|
|
if(strcmp(uniform->name, "mvp") == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
mat4_identity(&mvp); |
|
|
|
|
|
|
|
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 */ |
|
|
|
|
|
|
|
//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, GDM_TRIANGLES); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int k = 0; k < array_len(model->material_params); k++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
/* unbind textures, if any */ |
|
|
|
|
|
|
|
struct Material_Param* param = &model->material_params[k]; |
|
|
|
|
|
|
|
struct Uniform* uniform = &material->model_params[param->uniform_index]; |
|
|
|
|
|
|
|
if(uniform->type == UT_TEX) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
texture_unbind(*(int*)param->value); |
|
|
|
|
|
|
|
renderer_check_glerror("model:render_all:unbind_texture_uniform"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
shader_unbind(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
editor_debugvar_slot_set_int(num_rendered_slot, num_rendered); |
|
|
|
|
|
|
|
editor_debugvar_slot_set_int(num_culled_slot, num_culled); |
|
|
|
|
|
|
|
editor_debugvar_slot_set_int(num_indices_slot, num_indices); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
num_culled = num_rendered = num_indices = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
framebuffer_unbind(); |
|
|
|
framebuffer_unbind(); |
|
|
|
glDisable(GL_DEPTH_TEST); |
|
|
|
glDisable(GL_DEPTH_TEST); |
|
|
|
glDisable(GL_CULL_FACE); |
|
|
|
glDisable(GL_CULL_FACE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* struct Camera* camera = camera_get_primary(); */ |
|
|
|
|
|
|
|
/* { */ |
|
|
|
|
|
|
|
/* int width, height; */ |
|
|
|
|
|
|
|
/* struct Game_State* game_state = game_state_get(); */ |
|
|
|
|
|
|
|
/* window_get_size(game_state->window, &width, &height); */ |
|
|
|
|
|
|
|
/* glViewport(0, 0, width, height); */ |
|
|
|
|
|
|
|
/* glEnable(GL_DEPTH_TEST); */ |
|
|
|
|
|
|
|
/* glDepthFunc(GL_LEQUAL); */ |
|
|
|
|
|
|
|
/* 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); */ |
|
|
|
|
|
|
|
/* model_render_all(camera); */ |
|
|
|
|
|
|
|
/* } */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Final Render */ |
|
|
|
int width, height; |
|
|
|
int width, height; |
|
|
|
struct Game_State* game_state = game_state_get(); |
|
|
|
struct Game_State* game_state = game_state_get(); |
|
|
|
window_get_size(game_state->window, &width, &height); |
|
|
|
window_get_size(game_state->window, &width, &height); |
|
|
@ -163,14 +363,30 @@ void renderer_draw(struct Entity* active_viewer) |
|
|
|
texture_unbind(final_render_tex); |
|
|
|
texture_unbind(final_render_tex); |
|
|
|
shader_unbind(); |
|
|
|
shader_unbind(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Debug Render */ |
|
|
|
struct Hashmap* cvars = config_vars_get(); |
|
|
|
struct Hashmap* cvars = config_vars_get(); |
|
|
|
//if(settings.debug_draw_enabled)
|
|
|
|
|
|
|
|
if(hashmap_bool_get(cvars, "debug_draw_enabled")) |
|
|
|
if(hashmap_bool_get(cvars, "debug_draw_enabled")) |
|
|
|
{ |
|
|
|
{ |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
|
|
|
//model_render_all_debug(active_viewer, debug_shader, settings.debug_draw_mode, &settings.debug_draw_color);
|
|
|
|
|
|
|
|
vec4 debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); |
|
|
|
vec4 debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); |
|
|
|
model_render_all_debug(active_viewer, debug_shader, hashmap_int_get(cvars, "debug_draw_mode"), &debug_draw_color); |
|
|
|
shader_bind(debug_shader); |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static mat4 mvp; |
|
|
|
|
|
|
|
shader_set_uniform_vec4(debug_shader, "debug_color", &debug_draw_color); |
|
|
|
|
|
|
|
struct Entity* entity_list = entity_get_all(); |
|
|
|
|
|
|
|
for(int i = 0; i < array_len(entity_list); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(!entity_list[i].renderable) continue; |
|
|
|
|
|
|
|
struct Model* model = &entity_list[i].model; |
|
|
|
|
|
|
|
struct Transform* transform = &entity_list[i].transform; |
|
|
|
|
|
|
|
int geometry = model->geometry_index; |
|
|
|
|
|
|
|
mat4_identity(&mvp); |
|
|
|
|
|
|
|
mat4_mul(&mvp, &active_viewer->camera.view_proj_mat, &transform->trans_mat); |
|
|
|
|
|
|
|
shader_set_uniform_mat4(debug_shader, "mvp", &mvp); |
|
|
|
|
|
|
|
geom_render(geometry, hashmap_int_get(cvars, "debug_draw_mode")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
shader_unbind(); |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|