Implemented checking if mouse cursor is hovering window before ray casting and moved out gui state to game state

dev
Shariq Shah 6 years ago
parent e45c143f52
commit 330ec6c3fa
  1. 2
      src/game/console.c
  2. 4
      src/game/console.h
  3. 445
      src/game/editor.c
  4. 15
      src/game/game.c
  5. 4
      src/game/game.h
  6. 212
      src/game/gui.c
  7. 17
      src/game/gui.h
  8. 13
      src/game/renderer.c
  9. 6
      todo.txt

@ -42,7 +42,7 @@ void console_toggle(struct Console* console)
if(console->visible) console->scroll_to_bottom = true; if(console->visible) console->scroll_to_bottom = true;
} }
void console_update(struct Console* console, struct Gui_State* gui_state, float dt) void console_update(struct Console* console, struct Gui* gui_state, float dt)
{ {
if(!console->visible) return; if(!console->visible) return;

@ -7,7 +7,7 @@
#define MAX_CONSOLE_MESSAGE_LEN 256 #define MAX_CONSOLE_MESSAGE_LEN 256
#define MAX_CONSOLE_MESSAGES 1024 #define MAX_CONSOLE_MESSAGES 1024
struct Gui_State; struct Gui;
enum Console_Message_Type enum Console_Message_Type
{ {
@ -38,7 +38,7 @@ struct Console
void console_init(struct Console* console); void console_init(struct Console* console);
void console_toggle(struct Console* console); void console_toggle(struct Console* console);
void console_update(struct Console* console, struct Gui_State* gui_state, float dt); void console_update(struct Console* console, struct Gui* gui_state, float dt);
void console_destroy(struct Console* console); void console_destroy(struct Console* console);
void console_on_log_message(struct Console* console, const char* message, va_list args); void console_on_log_message(struct Console* console, const char* message, va_list args);
void console_on_log_warning(struct Console* console, const char* warning_message, va_list args); void console_on_log_warning(struct Console* console, const char* warning_message, va_list args);

@ -28,6 +28,7 @@
#include "event.h" #include "event.h"
#include "im_render.h" #include "im_render.h"
#include "geometry.h" #include "geometry.h"
#include "gui.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -69,7 +70,7 @@ void editor_init(struct Editor* editor)
editor->renderer_settings_window = false; editor->renderer_settings_window = false;
editor->camera_looking_around = false; editor->camera_looking_around = false;
editor->selected_entity = NULL; editor->selected_entity = NULL;
editor->top_panel_height = 20; editor->top_panel_height = 30;
editor->camera_turn_speed = 50.f; editor->camera_turn_speed = 50.f;
editor->camera_move_speed = 20.f; editor->camera_move_speed = 20.f;
editor->camera_sprint_multiplier = 2.f; editor->camera_sprint_multiplier = 2.f;
@ -102,23 +103,24 @@ void editor_init_camera(struct Editor* editor)
void editor_render(struct Editor* editor, struct Camera * active_camera) void editor_render(struct Editor* editor, struct Camera * active_camera)
{ {
//Disabling this for now until better handling of bounding box and scale of the entity is implemented
//Get the selected entity if any, see if it has a mesh and render it in the selected entity colour //Get the selected entity if any, see if it has a mesh and render it in the selected entity colour
if(editor->selected_entity) // if(editor->selected_entity)
{ // {
if(editor->selected_entity->type == ET_STATIC_MESH) // if(editor->selected_entity->type == ET_STATIC_MESH)
{ // {
struct Static_Mesh* mesh = (struct Static_Mesh*)editor->selected_entity; // struct Static_Mesh* mesh = (struct Static_Mesh*)editor->selected_entity;
struct Geometry* geom = geom_get(mesh->model.geometry_index); // struct Geometry* geom = geom_get(mesh->model.geometry_index);
vec3 abs_pos; // vec3 abs_pos;
vec3 abs_scale; // vec3 abs_scale;
quat abs_rot; // quat abs_rot;
transform_get_absolute_position(mesh, &abs_pos); // transform_get_absolute_position(mesh, &abs_pos);
transform_get_absolute_scale(mesh, &abs_scale); // transform_get_absolute_scale(mesh, &abs_scale);
transform_get_absolute_rot(mesh, &abs_rot); // transform_get_absolute_rot(mesh, &abs_rot);
im_box(geom->bounding_box.max.x, geom->bounding_box.max.y, geom->bounding_box.max.z, abs_pos, abs_rot, editor->selected_entity_colour, GDM_TRIANGLES); // im_box(geom->bounding_box.max.x, geom->bounding_box.max.y, geom->bounding_box.max.z, abs_pos, abs_rot, editor->selected_entity_colour, GDM_TRIANGLES);
} // }
} // }
} }
int editor_debugvar_slot_create(const char* name, int value_type) int editor_debugvar_slot_create(const char* name, int value_type)
@ -201,8 +203,7 @@ void editor_update(struct Editor* editor, float dt)
editor_camera_update(editor, dt); editor_camera_update(editor, dt);
struct Game_State* game_state = game_state_get(); struct Game_State* game_state = game_state_get();
struct Gui_State* gui_state = gui_state_get(); struct nk_context* context = &game_state->gui->context;
struct nk_context* context = &gui_state->context;
int win_width = 0, win_height = 0; int win_width = 0, win_height = 0;
window_get_drawable_size(game_state->window, &win_width, &win_height); window_get_drawable_size(game_state->window, &win_width, &win_height);
int half_width = win_width / 2, half_height = win_height / 2; int half_width = win_width / 2, half_height = win_height / 2;
@ -212,17 +213,11 @@ void editor_update(struct Editor* editor, float dt)
NK_WINDOW_SCROLL_AUTO_HIDE | NK_WINDOW_SCROLL_AUTO_HIDE |
NK_WINDOW_SCALABLE; NK_WINDOW_SCALABLE;
/* Main enacapsulating window */
struct nk_style_item default_background = context->style.window.fixed_background; /* Top Panel */
struct nk_vec2 default_padding = context->style.window.padding; if(nk_begin(context, "Top Panel", nk_recti(0, 0, win_width, editor->top_panel_height), NK_WINDOW_NO_SCROLLBAR))
context->style.window.padding = nk_vec2(0.f, 0.f);
context->style.window.fixed_background = nk_style_item_hide();
if(nk_begin(context, "Editor", nk_recti(0, 0, win_width, win_height), NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND))
{ {
context->style.window.fixed_background = default_background; nk_layout_row_dynamic(context, editor->top_panel_height, 1);
/* Top Panel */
nk_layout_row_dynamic(context, editor->top_panel_height + 10.f, 1);
nk_group_begin(context, "Menubar", NK_WINDOW_NO_SCROLLBAR); nk_group_begin(context, "Menubar", NK_WINDOW_NO_SCROLLBAR);
{ {
static float top_panel_ratios[] = { 0.1f, 0.1f, 0.7f, 0.1f }; static float top_panel_ratios[] = { 0.1f, 0.1f, 0.7f, 0.1f };
@ -247,246 +242,252 @@ void editor_update(struct Editor* editor, float dt)
nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps); nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps);
} }
nk_group_end(context); nk_group_end(context);
}
nk_end(context);
static float main_editor_ratios[] = { 0.2f, 0.6f, 0.2f }; /* Left */
nk_layout_row(context, NK_DYNAMIC, win_height - editor->top_panel_height, sizeof(main_editor_ratios) / sizeof(float), main_editor_ratios); if(nk_begin(context, "Editor Left", nk_recti(0, editor->top_panel_height, 300, 700), window_flags))
/* Left */ {
if(nk_group_begin(context, "Editor Left", NK_WINDOW_SCROLL_AUTO_HIDE)) /* Entities List */
struct Scene* scene = game_state_get()->scene;
if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED))
{ {
/* Entities List */ nk_layout_row_dynamic(context, 250, 1);
struct Scene* scene = game_state_get()->scene; if(nk_group_begin(context, "Entity Name", NK_WINDOW_SCROLL_AUTO_HIDE))
if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED))
{ {
nk_layout_row_dynamic(context, 250, 1);
if(nk_group_begin(context, "Entity Name", NK_WINDOW_SCROLL_AUTO_HIDE))
{
for(int i = 0; i < MAX_ENTITIES; i++) editor_show_entity_in_list(editor, context, scene, &scene->entities[i]); for(int i = 0; i < MAX_ENTITIES; i++) editor_show_entity_in_list(editor, context, scene, &scene->entities[i]);
for(int i = 0; i < MAX_CAMERAS; i++) editor_show_entity_in_list(editor, context, scene, &scene->cameras[i]); for(int i = 0; i < MAX_CAMERAS; i++) editor_show_entity_in_list(editor, context, scene, &scene->cameras[i]);
for(int i = 0; i < MAX_LIGHTS; i++) editor_show_entity_in_list(editor, context, scene, &scene->lights[i]); for(int i = 0; i < MAX_LIGHTS; i++) editor_show_entity_in_list(editor, context, scene, &scene->lights[i]);
for(int i = 0; i < MAX_STATIC_MESHES; i++) editor_show_entity_in_list(editor, context, scene, &scene->static_meshes[i]); for(int i = 0; i < MAX_STATIC_MESHES; i++) editor_show_entity_in_list(editor, context, scene, &scene->static_meshes[i]);
nk_group_end(context); nk_group_end(context);
}
nk_tree_pop(context);
} }
nk_tree_pop(context);
}
/* Debug Variables */ /* Debug Variables */
if(nk_tree_push(context, NK_TREE_TAB, "Debug Variables", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Debug Variables", NK_MAXIMIZED))
{
static char variant_str[MAX_VARIANT_STR_LEN] = { '\0' };
nk_layout_row_dynamic(context, 250, 1);
if(nk_group_begin(context, "Name", NK_WINDOW_SCROLL_AUTO_HIDE))
{ {
static char variant_str[MAX_VARIANT_STR_LEN] = { '\0' }; for(int i = 0; i < array_len(debug_vars_list); i++)
nk_layout_row_dynamic(context, 250, 1);
if(nk_group_begin(context, "Name", NK_WINDOW_SCROLL_AUTO_HIDE))
{ {
for(int i = 0; i < array_len(debug_vars_list); i++) struct Debug_Variable* debug_var = &debug_vars_list[i];
{ if(debug_var->data.type == VT_NONE) continue;
struct Debug_Variable* debug_var = &debug_vars_list[i]; nk_layout_row_dynamic(context, 20, 2);
if(debug_var->data.type == VT_NONE) continue; nk_label(context, debug_var->name, NK_TEXT_ALIGN_LEFT);
nk_layout_row_dynamic(context, 20, 2); variant_to_str(&debug_var->data, variant_str, MAX_VARIANT_STR_LEN);
nk_label(context, debug_var->name, NK_TEXT_ALIGN_LEFT); nk_label(context, variant_str, NK_TEXT_ALIGN_RIGHT);
variant_to_str(&debug_var->data, variant_str, MAX_VARIANT_STR_LEN); memset(variant_str, '\0', MAX_VARIANT_STR_LEN);
nk_label(context, variant_str, NK_TEXT_ALIGN_RIGHT);
memset(variant_str, '\0', MAX_VARIANT_STR_LEN);
}
nk_group_end(context);
} }
nk_tree_pop(context); nk_group_end(context);
} }
nk_tree_pop(context);
nk_group_end(context);
} }
}
nk_end(context);
/* Empty Space in the center */ /* Right */
nk_spacing(context, 1); if(nk_begin(context, "Editor Right", nk_recti(win_width - 300, editor->top_panel_height, 400, 700), window_flags))
{
/* Right */ /* Entity Inspector */
if(nk_group_begin(context, "Editor Right", NK_WINDOW_NO_SCROLLBAR)) if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED))
{ {
/* Entity Inspector */ const int row_height = 18;
if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED)) if(editor->selected_entity)
{ {
const int row_height = 18; struct Scene* scene = game_state_get()->scene;
if(editor->selected_entity) struct Entity* entity = editor->selected_entity;
{
struct Scene* scene = game_state_get()->scene;
struct Entity* entity = editor->selected_entity;
struct Entity* parent_ent = entity->transform.parent; struct Entity* parent_ent = entity->transform.parent;
nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT);
nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id);
nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity->editor_selected ? "True" : "False"); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity->editor_selected ? "True" : "False");
nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity));
nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT);
/* Transform */ /* Transform */
{
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Position", NK_TEXT_ALIGN_CENTERED);
vec3 abs_pos = { 0.f, 0.f, 0.f };
transform_get_absolute_position(entity, &abs_pos);
if(editor_widget_v3(context, &abs_pos, "#X", "#Y", "#Z", -FLT_MAX, FLT_MAX, 5.f, 1.f, row_height)) transform_set_position(entity, &abs_pos);
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Rotation", NK_TEXT_ALIGN_CENTERED);
quat abs_rot = { 0.f, 0.f, 0.f, 1.f };
transform_get_absolute_rot(entity, &abs_rot);
vec3 rot_angles = { 0.f, 0.f, 0.f };
rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot));
rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot));
rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot));
vec3 curr_rot = { rot_angles.x, rot_angles.y, rot_angles.z };
nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#X", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f);
nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#Y", -FLT_MAX, &curr_rot.y, FLT_MAX, 5.f, 1.f);
nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#Z", -FLT_MAX, &curr_rot.z, FLT_MAX, 5.f, 1.f);
vec3 delta = { 0.f, 0.f, 0.f };
vec3_sub(&delta, &rot_angles, &curr_rot);
vec3 AXIS_X = { 1.f, 0.f, 0.f };
vec3 AXIS_Y = { 0.f, 1.f, 0.f };
vec3 AXIS_Z = { 0.f, 0.f, 1.f };
const float epsilon = 0.0001f;
if(fabsf(delta.x) > epsilon) transform_rotate(entity, &AXIS_X, delta.x, TS_WORLD);
if(fabsf(delta.y) > epsilon) transform_rotate(entity, &AXIS_Y, delta.y, TS_WORLD);
if(fabsf(delta.z) > epsilon) transform_rotate(entity, &AXIS_Z, delta.z, TS_WORLD);
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Scale", NK_TEXT_ALIGN_CENTERED);
vec3 abs_scale = { 0.f, 0.f, 0.f };
transform_get_absolute_scale(entity, &abs_scale);
if(editor_widget_v3(context, &abs_scale, "#X", "#Y", "#Z", 0.1f, FLT_MAX, 1.f, 0.1f, row_height))
{ {
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Position", NK_TEXT_ALIGN_CENTERED); entity->transform.scale = abs_scale;
vec3 abs_pos = { 0.f, 0.f, 0.f }; transform_update_transmat(entity);
transform_get_absolute_position(entity, &abs_pos);
if(editor_widget_v3(context, &abs_pos, "#X", "#Y", "#Z", -FLT_MAX, FLT_MAX, 5.f, 1.f, row_height)) transform_set_position(entity, &abs_pos);
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Rotation", NK_TEXT_ALIGN_CENTERED);
quat abs_rot = { 0.f, 0.f, 0.f, 1.f };
transform_get_absolute_rot(entity, &abs_rot);
vec3 rot_angles = { 0.f, 0.f, 0.f };
rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot));
rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot));
rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot));
vec3 curr_rot = { rot_angles.x, rot_angles.y, rot_angles.z };
nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#X", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f);
nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#Y", -FLT_MAX, &curr_rot.y, FLT_MAX, 5.f, 1.f);
nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#Z", -FLT_MAX, &curr_rot.z, FLT_MAX, 5.f, 1.f);
vec3 delta = { 0.f, 0.f, 0.f };
vec3_sub(&delta, &rot_angles, &curr_rot);
vec3 AXIS_X = { 1.f, 0.f, 0.f };
vec3 AXIS_Y = { 0.f, 1.f, 0.f };
vec3 AXIS_Z = { 0.f, 0.f, 1.f };
const float epsilon = 0.0001f;
if(fabsf(delta.x) > epsilon) transform_rotate(entity, &AXIS_X, delta.x, TS_WORLD);
if(fabsf(delta.y) > epsilon) transform_rotate(entity, &AXIS_Y, delta.y, TS_WORLD);
if(fabsf(delta.z) > epsilon) transform_rotate(entity, &AXIS_Z, delta.z, TS_WORLD);
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Scale", NK_TEXT_ALIGN_CENTERED);
vec3 abs_scale = { 0.f, 0.f, 0.f };
transform_get_absolute_scale(entity, &abs_scale);
if(editor_widget_v3(context, &abs_scale, "#X", "#Y", "#Z", 0.1f, FLT_MAX, 1.f, 0.1f, row_height))
{
entity->transform.scale = abs_scale;
transform_update_transmat(entity);
}
} }
}
/* Light */ /* Light */
if(entity->type == ET_LIGHT) if(entity->type == ET_LIGHT)
{
if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED))
{ {
if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED)) struct Light* light = (struct Light*)entity;
if(light->type > LT_POINT)
{ {
struct Light* light = (struct Light*)entity; nk_layout_row_dynamic(context, row_height, 1);
if(light->type > LT_POINT) nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED);
{ }
nk_layout_row_dynamic(context, row_height, 1); else
nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED); {
} static const char* light_types[] = { "Spot", "Directional", "Point" };
else float combo_width = nk_widget_width(context), combo_height = row_height * (LT_MAX);
{
static const char* light_types[] = { "Spot", "Directional", "Point" };
float combo_width = nk_widget_width(context), combo_height = row_height * (LT_MAX);
nk_layout_row_dynamic(context, row_height, 2); nk_layout_row_dynamic(context, row_height, 2);
nk_label(context, "Light Type", NK_TEXT_ALIGN_LEFT); nk_label(context, "Light Type", NK_TEXT_ALIGN_LEFT);
nk_combobox(context, light_types, LT_MAX - 1, &light->type, row_height, nk_vec2(combo_width, combo_height)); nk_combobox(context, light_types, LT_MAX - 1, &light->type, row_height, nk_vec2(combo_width, combo_height));
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED); nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED);
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
editor_widget_color_combov3(context, &light->color, 200, 300); editor_widget_color_combov3(context, &light->color, 200, 300);
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f); nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f);
if(light->type != LT_DIR) if(light->type != LT_DIR)
{ {
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
light->outer_angle = TO_RADIANS(nk_propertyf(context, "Outer Angle", TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 360, 1.f, 0.5f)); light->outer_angle = TO_RADIANS(nk_propertyf(context, "Outer Angle", TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 360, 1.f, 0.5f));
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
light->inner_angle = TO_RADIANS(nk_propertyf(context, "Inner Angle", 1.f, TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 1.f, 0.5f)); light->inner_angle = TO_RADIANS(nk_propertyf(context, "Inner Angle", 1.f, TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 1.f, 0.5f));
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 1); nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 1);
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
nk_property_float(context, "Falloff", 0.f, &light->falloff, 100.f, 0.1f, 0.05f); nk_property_float(context, "Falloff", 0.f, &light->falloff, 100.f, 0.1f, 0.05f);
}
} }
nk_tree_pop(context);
} }
nk_tree_pop(context);
} }
}
/* Camera */ /* Camera */
if(entity->type == ET_CAMERA) if(entity->type == ET_CAMERA)
{
if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED))
{ {
if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED)) bool update = false;
{ struct Camera* camera = (struct Camera*)entity;
bool update = false;
struct Camera* camera = (struct Camera*)entity;
nk_layout_row_dynamic(context, row_height, 2); nk_layout_row_dynamic(context, row_height, 2);
nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE);
bool ortho = nk_checkbox_label(context, "", &camera->ortho); bool ortho = nk_checkbox_label(context, "", &camera->ortho);
if(ortho != camera->ortho) if(ortho != camera->ortho)
{ {
update = true; update = true;
} }
if(!camera->ortho)
{
nk_layout_row_dynamic(context, row_height, 1);
float new_fov = nk_propertyf(context, "Fov", 30.f, camera->fov, 90.f, 0.1f, 1.f);
if(new_fov != camera->fov)
{
camera->fov = new_fov;
update = true;
}
nk_layout_row_dynamic(context, row_height, 2);
nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio);
}
nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Clear Color", NK_TEXT_ALIGN_CENTERED);
nk_layout_row_dynamic(context, row_height, 1);
editor_widget_color_combov4(context, &camera->clear_color, 200, 300);
if(!camera->ortho)
{
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
float new_zoom = nk_propertyf(context, "Zoom", 1.f, camera->zoom, FLT_MAX, 0.1f, 1.f); float new_fov = nk_propertyf(context, "Fov", 30.f, camera->fov, 90.f, 0.1f, 1.f);
if(new_zoom != camera->zoom) if(new_fov != camera->fov)
{ {
camera->zoom = new_zoom; camera->fov = new_fov;
update = true; update = true;
} }
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 2);
float new_near_z = nk_propertyf(context, "NearZ", -FLT_MAX, camera->nearz, camera->farz, 0.1f, 1.f); nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio);
if(new_near_z != camera->nearz) }
{
camera->nearz = new_near_z;
update = true;
}
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Clear Color", NK_TEXT_ALIGN_CENTERED);
float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f); nk_layout_row_dynamic(context, row_height, 1);
if(new_far_z != camera->farz) editor_widget_color_combov4(context, &camera->clear_color, 200, 300);
{
camera->farz = new_far_z;
update = true;
}
if(update) nk_layout_row_dynamic(context, row_height, 1);
{ float new_zoom = nk_propertyf(context, "Zoom", 1.f, camera->zoom, FLT_MAX, 0.1f, 1.f);
camera_update_view(entity); if(new_zoom != camera->zoom)
camera_update_proj(entity); {
} camera->zoom = new_zoom;
update = true;
}
nk_tree_pop(context); nk_layout_row_dynamic(context, row_height, 1);
float new_near_z = nk_propertyf(context, "NearZ", -FLT_MAX, camera->nearz, camera->farz, 0.1f, 1.f);
if(new_near_z != camera->nearz)
{
camera->nearz = new_near_z;
update = true;
}
nk_layout_row_dynamic(context, row_height, 1);
float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f);
if(new_far_z != camera->farz)
{
camera->farz = new_far_z;
update = true;
}
if(update)
{
camera_update_view(entity);
camera_update_proj(entity);
} }
nk_tree_pop(context);
} }
} }
else
{
nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED);
}
nk_tree_pop(context);
} }
else
nk_group_end(context); {
nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED);
}
nk_tree_pop(context);
} }
} }
nk_end(context); nk_end(context);
context->style.window.padding = default_padding;
// if(nk_begin(context, "Editor", nk_recti(0, 0, win_width, win_height), NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND))
// {
// context->style.window.fixed_background = default_background;
//
// /* Empty Space in the center */
// nk_spacing(context, 1);
//
// }
// nk_end(context);
// context->style.window.padding = default_padding;
/* Render Settings Window */ /* Render Settings Window */
if(editor->renderer_settings_window) if(editor->renderer_settings_window)
@ -574,7 +575,11 @@ void editor_on_mousebutton(const struct Event* event)
assert(event->type == EVT_MOUSEBUTTON_PRESSED || event->type == EVT_MOUSEBUTTON_RELEASED); assert(event->type == EVT_MOUSEBUTTON_PRESSED || event->type == EVT_MOUSEBUTTON_RELEASED);
struct Editor* editor = game_state_get()->editor; struct Editor* editor = game_state_get()->editor;
if(event->mousebutton.button == MSB_LEFT && event->type == EVT_MOUSEBUTTON_RELEASED && !editor->camera_looking_around) struct Gui* gui = game_state_get()->gui;
if(event->mousebutton.button == MSB_LEFT &&
event->type == EVT_MOUSEBUTTON_RELEASED &&
!editor->camera_looking_around &&
nk_item_is_any_active(&gui->context) == 0)
{ {
log_message("Editor Picking"); log_message("Editor Picking");
struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR];

@ -74,6 +74,7 @@ bool game_init(struct Window* window)
game_state->scene = calloc(1, sizeof(*game_state->scene)); game_state->scene = calloc(1, sizeof(*game_state->scene));
game_state->console = calloc(1, sizeof(*game_state->console)); game_state->console = calloc(1, sizeof(*game_state->console));
game_state->editor = calloc(1, sizeof(*game_state->editor)); game_state->editor = calloc(1, sizeof(*game_state->editor));
game_state->gui = calloc(1, sizeof(*game_state->gui));
game_state->event_manager = calloc(1, sizeof(*game_state->event_manager)); game_state->event_manager = calloc(1, sizeof(*game_state->event_manager));
log_message_callback_set(game_on_log_message); log_message_callback_set(game_on_log_message);
@ -96,7 +97,7 @@ bool game_init(struct Window* window)
shader_init(); shader_init();
texture_init(); texture_init();
framebuffer_init(); framebuffer_init();
gui_init(); gui_init(game_state->gui);
console_init(game_state->console); console_init(game_state->console);
geom_init(); geom_init();
physics_init(); physics_init();
@ -493,10 +494,10 @@ bool game_run(void)
last_time = curr_time; last_time = curr_time;
if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */ if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */
gui_input_begin(); gui_input_begin(game_state->gui);
//platform_poll_events(&should_window_close); //platform_poll_events(&should_window_close);
event_manager_poll_events(game_state->event_manager, &should_window_close); event_manager_poll_events(game_state->event_manager, &should_window_close);
gui_input_end(); gui_input_end(game_state->gui);
game_update(delta_time, &should_window_close); game_update(delta_time, &should_window_close);
game_post_update(delta_time); game_post_update(delta_time);
@ -529,7 +530,7 @@ void game_update(float dt, bool* window_should_close)
//game_debug(dt); //game_debug(dt);
//game_debug_gui(dt); //game_debug_gui(dt);
console_update(game_state->console, gui_state_get(), dt); console_update(game_state->console, game_state->gui, dt);
scene_update(game_state->scene, dt); scene_update(game_state->scene, dt);
if(game_state->game_mode == GAME_MODE_GAME) if(game_state->game_mode == GAME_MODE_GAME)
{ {
@ -550,7 +551,7 @@ void game_post_update(float dt)
void game_debug_gui(float dt) void game_debug_gui(float dt)
{ {
struct Gui_State* gui_state = gui_state_get(); struct Gui* gui_state = gui_state_get();
struct nk_context* ctx = &gui_state->context; struct nk_context* ctx = &gui_state->context;
/* window flags */ /* window flags */
@ -1881,7 +1882,7 @@ void game_cleanup(void)
scene_destroy(game_state->scene); scene_destroy(game_state->scene);
input_cleanup(); input_cleanup();
renderer_cleanup(game_state->renderer); renderer_cleanup(game_state->renderer);
gui_cleanup(); gui_cleanup(game_state->gui);
console_destroy(game_state->console); console_destroy(game_state->console);
geom_cleanup(); geom_cleanup();
framebuffer_cleanup(); framebuffer_cleanup();
@ -1889,10 +1890,12 @@ void game_cleanup(void)
shader_cleanup(); shader_cleanup();
event_manager_cleanup(game_state->event_manager); event_manager_cleanup(game_state->event_manager);
free(game_state->editor);
free(game_state->console); free(game_state->console);
free(game_state->scene); free(game_state->scene);
free(game_state->renderer); free(game_state->renderer);
free(game_state->event_manager); free(game_state->event_manager);
free(game_state->gui);
} }
free(game_state); free(game_state);
game_state = NULL; game_state = NULL;

@ -9,7 +9,7 @@ struct Scene;
struct Entity; struct Entity;
struct Player; struct Player;
struct Console; struct Console;
struct Gui_State; struct Gui;
struct Event_Manager; struct Event_Manager;
struct Editor; struct Editor;
@ -27,7 +27,7 @@ struct Game_State
struct Renderer* renderer; struct Renderer* renderer;
struct Scene* scene; struct Scene* scene;
struct Console* console; struct Console* console;
struct Gui_State* gui; struct Gui* gui;
struct Event_Manager* event_manager; struct Event_Manager* event_manager;
struct Editor* editor; struct Editor* editor;
}; };

@ -32,39 +32,31 @@ static void gui_on_mousemotion(const struct Event* event);
static void gui_on_mousebutton(const struct Event* event); static void gui_on_mousebutton(const struct Event* event);
static void gui_on_key(const struct Event* event); static void gui_on_key(const struct Event* event);
static void gui_upload_atlas(const void *image, int width, int height); static void gui_upload_atlas(struct Gui* gui, const void *image, int width, int height);
static void gui_font_set_default(void); static void gui_font_set_default(struct Gui* gui);
static struct Gui_State* gui_state = NULL; bool gui_init(struct Gui* gui)
bool gui_init(void)
{ {
bool success = false; bool success = false;
gui_state = malloc(sizeof(*gui_state));
if(!gui_state)
{
log_error("gui:init", "Malloc failed, out of memory");
return success;
}
nk_init_default(&gui_state->context, 0); nk_init_default(&gui->context, 0);
nk_buffer_init_default(&gui_state->cmds); nk_buffer_init_default(&gui->cmds);
gui_state->context.clip.copy = gui_on_clipbard_copy; gui->context.clip.copy = gui_on_clipbard_copy;
gui_state->context.clip.paste = gui_on_clipbard_paste; gui->context.clip.paste = gui_on_clipbard_paste;
gui_state->context.clip.userdata = nk_handle_ptr(0); gui->context.clip.userdata = nk_handle_ptr(0);
gui_state->current_font = NULL; gui->current_font = NULL;
gui_state->shader = shader_create("gui.vert", "gui.frag"); gui->shader = shader_create("gui.vert", "gui.frag");
if(gui_state->shader < 0) if(gui->shader < 0)
{ {
log_error("gui:init", "Failed to create shader for gui"); log_error("gui:init", "Failed to create shader for gui");
free(gui_state); free(gui);
return success; return success;
} }
gui_state->uniform_tex = shader_get_uniform_location(gui_state->shader, "sampler"); gui->uniform_tex = shader_get_uniform_location(gui->shader, "sampler");
gui_state->uniform_proj = shader_get_uniform_location(gui_state->shader, "proj_mat"); gui->uniform_proj = shader_get_uniform_location(gui->shader, "proj_mat");
gui_state->attrib_pos = shader_get_attribute_location(gui_state->shader, "vPosition"); gui->attrib_pos = shader_get_attribute_location(gui->shader, "vPosition");
gui_state->attrib_uv = shader_get_attribute_location(gui_state->shader, "vUV"); gui->attrib_uv = shader_get_attribute_location(gui->shader, "vUV");
gui_state->attrib_col = shader_get_attribute_location(gui_state->shader, "vColor"); gui->attrib_col = shader_get_attribute_location(gui->shader, "vColor");
{ {
/* buffer setup */ /* buffer setup */
@ -73,21 +65,21 @@ bool gui_init(void)
size_t vt = offsetof(struct Gui_Vertex, uv); size_t vt = offsetof(struct Gui_Vertex, uv);
size_t vc = offsetof(struct Gui_Vertex, col); size_t vc = offsetof(struct Gui_Vertex, col);
glGenBuffers(1, &gui_state->vbo); glGenBuffers(1, &gui->vbo);
glGenBuffers(1, &gui_state->ebo); glGenBuffers(1, &gui->ebo);
glGenVertexArrays(1, &gui_state->vao); glGenVertexArrays(1, &gui->vao);
glBindVertexArray(gui_state->vao); glBindVertexArray(gui->vao);
glBindBuffer(GL_ARRAY_BUFFER, gui_state->vbo); glBindBuffer(GL_ARRAY_BUFFER, gui->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gui_state->ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gui->ebo);
glEnableVertexAttribArray((GLuint)gui_state->attrib_pos); glEnableVertexAttribArray((GLuint)gui->attrib_pos);
glEnableVertexAttribArray((GLuint)gui_state->attrib_uv); glEnableVertexAttribArray((GLuint)gui->attrib_uv);
glEnableVertexAttribArray((GLuint)gui_state->attrib_col); glEnableVertexAttribArray((GLuint)gui->attrib_col);
glVertexAttribPointer((GLuint)gui_state->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); glVertexAttribPointer((GLuint)gui->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp);
glVertexAttribPointer((GLuint)gui_state->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); glVertexAttribPointer((GLuint)gui->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt);
glVertexAttribPointer((GLuint)gui_state->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); glVertexAttribPointer((GLuint)gui->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc);
} }
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
@ -97,9 +89,9 @@ bool gui_init(void)
//gui_font_set("Ubuntu-R.ttf", 14); //gui_font_set("Ubuntu-R.ttf", 14);
//gui_font_set("FiraSans-Regular.ttf", 14); //gui_font_set("FiraSans-Regular.ttf", 14);
gui_font_set("roboto_condensed.ttf", 18); gui_font_set(gui, "roboto_condensed.ttf", 18);
// gui_theme_set(GT_RED); // gui_theme_set(GT_RED);
gui_theme_set(GT_DEFAULT); gui_theme_set(gui, GT_DEFAULT);
struct Event_Manager* event_manager = game_state_get()->event_manager; struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_subscribe(event_manager, EVT_KEY_PRESSED, &gui_on_key); event_manager_subscribe(event_manager, EVT_KEY_PRESSED, &gui_on_key);
@ -114,20 +106,20 @@ bool gui_init(void)
return success; return success;
} }
void gui_upload_atlas(const void *image, int width, int height) void gui_upload_atlas(struct Gui* gui, const void *image, int width, int height)
{ {
gui_state->font_tex = texture_create("Gui_Font_Tex", gui->font_tex = texture_create("Gui_Font_Tex",
TU_DIFFUSE, TU_DIFFUSE,
width, height, width, height,
GL_RGBA, GL_RGBA,
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
image); image);
texture_set_param(gui_state->font_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); texture_set_param(gui->font_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(gui_state->font_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); texture_set_param(gui->font_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} }
void gui_cleanup(void) void gui_cleanup(struct Gui* gui)
{ {
struct Event_Manager* event_manager = game_state_get()->event_manager; struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_unsubscribe(event_manager, EVT_KEY_PRESSED, &gui_on_key); event_manager_unsubscribe(event_manager, EVT_KEY_PRESSED, &gui_on_key);
@ -137,17 +129,16 @@ void gui_cleanup(void)
event_manager_unsubscribe(event_manager, EVT_MOUSEMOTION, &gui_on_mousemotion); event_manager_unsubscribe(event_manager, EVT_MOUSEMOTION, &gui_on_mousemotion);
event_manager_unsubscribe(event_manager, EVT_MOUSEWHEEL, &gui_on_mousewheel); event_manager_unsubscribe(event_manager, EVT_MOUSEWHEEL, &gui_on_mousewheel);
nk_font_atlas_clear(&gui_state->atlas); nk_font_atlas_clear(&gui->atlas);
nk_free(&gui_state->context); nk_free(&gui->context);
shader_remove(gui_state->shader); shader_remove(gui->shader);
texture_remove(gui_state->font_tex); texture_remove(gui->font_tex);
glDeleteBuffers(1, &gui_state->vbo); glDeleteBuffers(1, &gui->vbo);
glDeleteBuffers(1, &gui_state->ebo); glDeleteBuffers(1, &gui->ebo);
nk_buffer_free(&gui_state->cmds); nk_buffer_free(&gui->cmds);
free(gui_state);
} }
void gui_render(enum nk_anti_aliasing AA) void gui_render(struct Gui* gui, enum nk_anti_aliasing AA)
{ {
int width, height; int width, height;
int display_width, display_height; int display_width, display_height;
@ -173,9 +164,9 @@ void gui_render(enum nk_anti_aliasing AA)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
/* setup program */ /* setup program */
shader_bind(gui_state->shader); shader_bind(gui->shader);
glUniform1i(gui_state->uniform_tex, 0); glUniform1i(gui->uniform_tex, 0);
shader_set_uniform(UT_MAT4, gui_state->uniform_proj, &gui_mat); shader_set_uniform(UT_MAT4, gui->uniform_proj, &gui_mat);
{ {
/* convert from command queue into draw list and draw to screen */ /* convert from command queue into draw list and draw to screen */
const struct nk_draw_command *cmd; const struct nk_draw_command *cmd;
@ -183,9 +174,9 @@ void gui_render(enum nk_anti_aliasing AA)
const nk_draw_index *offset = NULL; const nk_draw_index *offset = NULL;
/* allocate vertex and element buffer */ /* allocate vertex and element buffer */
glBindVertexArray(gui_state->vao); glBindVertexArray(gui->vao);
glBindBuffer(GL_ARRAY_BUFFER, gui_state->vbo); glBindBuffer(GL_ARRAY_BUFFER, gui->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gui_state->ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gui->ebo);
glBufferData(GL_ARRAY_BUFFER, MAX_GUI_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, MAX_GUI_VERTEX_MEMORY, NULL, GL_STREAM_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_GUI_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_GUI_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW);
@ -207,7 +198,7 @@ void gui_render(enum nk_anti_aliasing AA)
config.vertex_layout = vertex_layout; config.vertex_layout = vertex_layout;
config.vertex_size = sizeof(struct Gui_Vertex); config.vertex_size = sizeof(struct Gui_Vertex);
config.vertex_alignment = NK_ALIGNOF(struct Gui_Vertex); config.vertex_alignment = NK_ALIGNOF(struct Gui_Vertex);
config.null = gui_state->null; config.null = gui->null;
config.circle_segment_count = 22; config.circle_segment_count = 22;
config.curve_segment_count = 22; config.curve_segment_count = 22;
config.arc_segment_count = 22; config.arc_segment_count = 22;
@ -219,13 +210,13 @@ void gui_render(enum nk_anti_aliasing AA)
struct nk_buffer vbuf, ebuf; struct nk_buffer vbuf, ebuf;
nk_buffer_init_fixed(&vbuf, vertices, (nk_size)MAX_GUI_VERTEX_MEMORY); nk_buffer_init_fixed(&vbuf, vertices, (nk_size)MAX_GUI_VERTEX_MEMORY);
nk_buffer_init_fixed(&ebuf, elements, (nk_size)MAX_GUI_ELEMENT_MEMORY); nk_buffer_init_fixed(&ebuf, elements, (nk_size)MAX_GUI_ELEMENT_MEMORY);
nk_convert(&gui_state->context, &gui_state->cmds, &vbuf, &ebuf, &config); nk_convert(&gui->context, &gui->cmds, &vbuf, &ebuf, &config);
} }
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
/* iterate over and execute each draw command */ /* iterate over and execute each draw command */
nk_draw_foreach(cmd, &gui_state->context, &gui_state->cmds) nk_draw_foreach(cmd, &gui->context, &gui->cmds)
{ {
if (!cmd->elem_count) continue; if (!cmd->elem_count) continue;
texture_bind(cmd->texture.id); texture_bind(cmd->texture.id);
@ -236,11 +227,11 @@ void gui_render(enum nk_anti_aliasing AA)
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
offset += cmd->elem_count; offset += cmd->elem_count;
} }
nk_clear(&gui_state->context); nk_clear(&gui->context);
} }
shader_unbind(); shader_unbind();
texture_unbind(gui_state->font_tex); texture_unbind(gui->font_tex);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
@ -278,7 +269,7 @@ void gui_on_key(const struct Event* event)
int key = event->key.key; int key = event->key.key;
bool mod_ctrl = event->key.mod_ctrl; bool mod_ctrl = event->key.mod_ctrl;
struct nk_context* ctx = &gui_state->context; struct nk_context* ctx = &game_state_get()->gui->context;
int down = event->type == EVT_KEY_PRESSED ? 1 : 0; int down = event->type == EVT_KEY_PRESSED ? 1 : 0;
@ -351,7 +342,7 @@ void gui_on_mousebutton(const struct Event* event)
int x = event->mousebutton.x; int x = event->mousebutton.x;
int y = event->mousebutton.y; int y = event->mousebutton.y;
int down = event->type == EVT_MOUSEBUTTON_PRESSED ? 1 : 0; int down = event->type == EVT_MOUSEBUTTON_PRESSED ? 1 : 0;
struct nk_context* ctx = &gui_state->context; struct nk_context* ctx = &game_state_get()->gui->context;
if(button == MSB_LEFT) nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); if(button == MSB_LEFT) nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
if(button == MSB_MIDDLE) nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); if(button == MSB_MIDDLE) nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
@ -364,7 +355,7 @@ void gui_on_mousemotion(const struct Event* event)
int y = event->mousemotion.y; int y = event->mousemotion.y;
int xrel = event->mousemotion.xrel; int xrel = event->mousemotion.xrel;
int yrel = event->mousemotion.yrel; int yrel = event->mousemotion.yrel;
struct nk_context* ctx = &gui_state->context; struct nk_context* ctx = &game_state_get()->gui->context;
if(ctx->input.mouse.grabbed) if(ctx->input.mouse.grabbed)
{ {
@ -379,7 +370,7 @@ void gui_on_mousemotion(const struct Event* event)
void gui_on_textinput(const struct Event* event) void gui_on_textinput(const struct Event* event)
{ {
struct nk_context *ctx = &gui_state->context; struct nk_context *ctx = &game_state_get()->gui->context;
nk_glyph glyph; nk_glyph glyph;
memcpy(glyph, event->text_input.text, NK_UTF_SIZE); memcpy(glyph, event->text_input.text, NK_UTF_SIZE);
nk_input_glyph(ctx, glyph); nk_input_glyph(ctx, glyph);
@ -389,29 +380,24 @@ void gui_on_mousewheel(const struct Event* event)
{ {
int x = event->mousewheel.x; int x = event->mousewheel.x;
int y = event->mousewheel.y; int y = event->mousewheel.y;
struct nk_context* ctx = &gui_state->context; struct nk_context* ctx = &game_state_get()->gui->context;
nk_input_scroll(ctx, nk_vec2(x, y)); nk_input_scroll(ctx, nk_vec2(x, y));
} }
struct Gui_State* gui_state_get(void) void gui_input_begin(struct Gui* gui)
{
return gui_state;
}
void gui_input_begin(void)
{ {
nk_input_begin(&gui_state->context); nk_input_begin(&gui->context);
} }
void gui_input_end(void) void gui_input_end(struct Gui* gui)
{ {
nk_input_end(&gui_state->context); nk_input_end(&gui->context);
} }
void gui_font_set(const char* font_name, float font_size) void gui_font_set(struct Gui* gui, const char* font_name, float font_size)
{ {
assert(font_name && font_size > 1.f); assert(font_name && font_size > 1.f);
struct nk_font_atlas* atlas = &gui_state->atlas; struct nk_font_atlas* atlas = &gui->atlas;
long size = 0; long size = 0;
char* font_file_name = str_new("fonts/%s", font_name); char* font_file_name = str_new("fonts/%s", font_name);
char* font_data = io_file_read(DIRT_INSTALL, font_file_name, "rb", &size); char* font_data = io_file_read(DIRT_INSTALL, font_file_name, "rb", &size);
@ -419,16 +405,16 @@ void gui_font_set(const char* font_name, float font_size)
if(!font_data) if(!font_data)
{ {
log_error("gui:init", "Could not load font %s, reverting to default", font_name); log_error("gui:init", "Could not load font %s, reverting to default", font_name);
if(!gui_state->current_font) gui_font_set_default(); if(!gui->current_font) gui_font_set_default(gui);
} }
else else
{ {
if(gui_state->current_font) if(gui->current_font)
{ {
nk_font_atlas_clear(&gui_state->atlas); nk_font_atlas_clear(&gui->atlas);
texture_remove(gui_state->font_tex); texture_remove(gui->font_tex);
gui_state->font_tex = -1; gui->font_tex = -1;
gui_state->current_font = NULL; gui->current_font = NULL;
} }
const void *image = NULL; const void *image = NULL;
int w = 0, h = 0; int w = 0, h = 0;
@ -436,43 +422,43 @@ void gui_font_set(const char* font_name, float font_size)
nk_font_atlas_begin(atlas); nk_font_atlas_begin(atlas);
struct nk_font *new_font = nk_font_atlas_add_from_memory(atlas, font_data, size, font_size, NULL); struct nk_font *new_font = nk_font_atlas_add_from_memory(atlas, font_data, size, font_size, NULL);
image = nk_font_atlas_bake(atlas, &w, &h, NK_FONT_ATLAS_RGBA32); image = nk_font_atlas_bake(atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
gui_upload_atlas(image, w, h); gui_upload_atlas(gui, image, w, h);
nk_font_atlas_end(atlas, nk_handle_id((int)gui_state->font_tex), &gui_state->null); nk_font_atlas_end(atlas, nk_handle_id((int)gui->font_tex), &gui->null);
if(new_font) if(new_font)
{ {
nk_style_set_font(&gui_state->context, &new_font->handle); nk_style_set_font(&gui->context, &new_font->handle);
log_message("Set %s as current font", font_name); log_message("Set %s as current font", font_name);
gui_state->current_font = new_font; gui->current_font = new_font;
} }
else else
{ {
log_error("gui:init", "Could not add font %s, reverting to default", font_name); log_error("gui:init", "Could not add font %s, reverting to default", font_name);
gui_font_set_default(); gui_font_set_default(gui);
} }
free(font_data); free(font_data);
} }
} }
void gui_font_set_default(void) void gui_font_set_default(struct Gui* gui)
{ {
if(gui_state->current_font) if(gui->current_font)
{ {
nk_font_atlas_clear(&gui_state->atlas); nk_font_atlas_clear(&gui->atlas);
texture_remove(gui_state->font_tex); texture_remove(gui->font_tex);
} }
struct nk_font_atlas* atlas = &gui_state->atlas; struct nk_font_atlas* atlas = &gui->atlas;
nk_font_atlas_init_default(atlas); nk_font_atlas_init_default(atlas);
const void *image = NULL; const void *image = NULL;
int w = 0, h = 0; int w = 0, h = 0;
image = nk_font_atlas_bake(atlas, &w, &h, NK_FONT_ATLAS_RGBA32); image = nk_font_atlas_bake(atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
gui_upload_atlas(image, w, h); gui_upload_atlas(gui, image, w, h);
nk_style_set_font(&gui_state->context, &atlas->default_font->handle); nk_style_set_font(&gui->context, &atlas->default_font->handle);
gui_state->current_font = atlas->default_font; gui->current_font = atlas->default_font;
nk_font_atlas_end(atlas, nk_handle_id((int)gui_state->font_tex), &gui_state->null); nk_font_atlas_end(atlas, nk_handle_id((int)gui->font_tex), &gui->null);
log_message("Set default font"); log_message("Set default font");
} }
void gui_theme_set(enum Gui_Theme theme) void gui_theme_set(struct Gui* gui, enum Gui_Theme theme)
{ {
struct nk_color table[NK_COLOR_COUNT]; struct nk_color table[NK_COLOR_COUNT];
if(theme == GT_WHITE) if(theme == GT_WHITE)
@ -505,7 +491,7 @@ void gui_theme_set(enum Gui_Theme theme)
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(150, 150, 150, 255); table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(150, 150, 150, 255);
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(160, 160, 160, 255); table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(160, 160, 160, 255);
table[NK_COLOR_TAB_HEADER] = nk_rgba(180, 180, 180, 255); table[NK_COLOR_TAB_HEADER] = nk_rgba(180, 180, 180, 255);
nk_style_from_table(&gui_state->context, table); nk_style_from_table(&gui->context, table);
} }
else if(theme == GT_RED) else if(theme == GT_RED)
{ {
@ -537,7 +523,7 @@ void gui_theme_set(enum Gui_Theme theme)
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255); table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255);
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255); table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255);
table[NK_COLOR_TAB_HEADER] = nk_rgba(181, 45, 69, 220); table[NK_COLOR_TAB_HEADER] = nk_rgba(181, 45, 69, 220);
nk_style_from_table(&gui_state->context, table); nk_style_from_table(&gui->context, table);
} }
else if(theme == GT_BLUE) else if(theme == GT_BLUE)
{ {
@ -569,7 +555,7 @@ void gui_theme_set(enum Gui_Theme theme)
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255); table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255);
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255); table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255);
table[NK_COLOR_TAB_HEADER] = nk_rgba(156, 193, 220, 255); table[NK_COLOR_TAB_HEADER] = nk_rgba(156, 193, 220, 255);
nk_style_from_table(&gui_state->context, table); nk_style_from_table(&gui->context, table);
} }
else if(theme == GT_DARK) else if(theme == GT_DARK)
{ {
@ -601,15 +587,15 @@ void gui_theme_set(enum Gui_Theme theme)
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255); table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255);
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255); table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255);
table[NK_COLOR_TAB_HEADER] = nk_rgba(48, 83, 111, 255); table[NK_COLOR_TAB_HEADER] = nk_rgba(48, 83, 111, 255);
nk_style_from_table(&gui_state->context, table); nk_style_from_table(&gui->context, table);
} }
else if(theme == GT_DEFAULT) else if(theme == GT_DEFAULT)
{ {
nk_style_default(&gui_state->context); nk_style_default(&gui->context);
} }
else else
{ {
log_error("gui:theme_set", "Unrecognized theme, reverting to default"); log_error("gui:theme_set", "Unrecognized theme, reverting to default");
nk_style_default(&gui_state->context); nk_style_default(&gui->context);
} }
} }

@ -14,7 +14,7 @@
#include "gl_load.h" #include "gl_load.h"
#include "../common/num_types.h" #include "../common/num_types.h"
struct Gui_State struct Gui
{ {
struct nk_buffer cmds; struct nk_buffer cmds;
struct nk_draw_null_texture null; struct nk_draw_null_texture null;
@ -42,13 +42,12 @@ enum Gui_Theme
GT_DARK GT_DARK
}; };
bool gui_init(void); bool gui_init(struct Gui* gui);
void gui_cleanup(void); void gui_cleanup(struct Gui* gui);
void gui_render(enum nk_anti_aliasing AA); void gui_render(struct Gui* gui, enum nk_anti_aliasing AA);
void gui_input_begin(void); void gui_input_begin(struct Gui* gui);
void gui_input_end(void); void gui_input_end(struct Gui* gui);
void gui_font_set(const char* font_name, float font_height); void gui_font_set(struct Gui* gui, const char* font_name, float font_height);
void gui_theme_set(enum Gui_Theme theme); void gui_theme_set(struct Gui* gui, enum Gui_Theme theme);
struct Gui_State* gui_state_get(void);
#endif #endif

@ -428,12 +428,21 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene)
mat4_identity(&mvp); mat4_identity(&mvp);
mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat);
shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp);
geom_render(geometry, GDM_LINES); geom_render(geometry, GDM_TRIANGLES);
} }
shader_unbind(); shader_unbind();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} }
else
{
//For now just draw a placeholder sphere just to visually denote that the entity is selected
vec3 abs_pos;
quat abs_rot;
transform_get_absolute_position(game_state->editor->selected_entity, &abs_pos);
transform_get_absolute_rot(game_state->editor->selected_entity, &abs_rot);
im_sphere(1.f, abs_pos, abs_rot, game_state->editor->selected_entity_colour, GDM_TRIANGLES);
}
} }
//Immediate mode geometry render //Immediate mode geometry render
@ -457,7 +466,7 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene)
shader_unbind(); shader_unbind();
/* Render UI */ /* Render UI */
gui_render(NK_ANTI_ALIASING_ON); gui_render(game_state->gui, NK_ANTI_ALIASING_ON);
} }
void renderer_cleanup(struct Renderer* renderer) void renderer_cleanup(struct Renderer* renderer)

@ -62,6 +62,7 @@ Improvements:
- Better naming semantics for examples, init/deinit for initialization and cleanup and create/destroy when memory is allocated or deallocated - Better naming semantics for examples, init/deinit for initialization and cleanup and create/destroy when memory is allocated or deallocated
- Reset mouse cursor position to the center of the screen in editor mode after the right click is released - Reset mouse cursor position to the center of the screen in editor mode after the right click is released
- 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
- Remove fixed editor windows locations and bring back floating windows
Bugs: Bugs:
- Better handling of wav format checking at load time - Better handling of wav format checking at load time
@ -69,6 +70,7 @@ Bugs:
- Fix lights type not being correctly saved/loaded from file - Fix lights type not being correctly saved/loaded from file
- Fix culling - Fix culling
- Fix bounding boxes not aligning in editor - Fix bounding boxes not aligning in editor
- Investigate memory usage increase when window is maximized
Done: Done:
* Input * Input
@ -202,3 +204,7 @@ Done:
* Ray picking for editor * Ray picking for editor
* Highlight entity selected in editor in a specific color * Highlight entity selected in editor in a specific color
* Deselect selected entity in editor when nothing is hit on click and an entity is already selected * Deselect selected entity in editor when nothing is hit on click and an entity is already selected
* Implemented showing a placeholder when an entity other than a static mesh is selected
* Prevented ray casting when clicking on editor window and buttons
* Implemented handling drawing other entity types that can be selected in the editor but are not static meshes

Loading…
Cancel
Save