Changed top bar in editor and removed several editor related bugs. Learnt lesson about dangers of interchangeably using bool from stdbool and int in C

dev
Shariq Shah 6 years ago
parent e3e471e8bf
commit 124b02e566
  1. 544
      src/game/editor.c
  2. 7
      src/game/editor.h
  3. 58
      src/game/renderer.c
  4. 3
      todo.txt

@ -47,6 +47,11 @@ struct Debug_Variable
static struct Debug_Variable* debug_vars_list = NULL; static struct Debug_Variable* debug_vars_list = NULL;
static int* empty_indices = NULL; static int* empty_indices = NULL;
static int window_flags = NK_WINDOW_BORDER |
NK_WINDOW_CLOSABLE |
NK_WINDOW_MOVABLE |
NK_WINDOW_SCROLL_AUTO_HIDE |
NK_WINDOW_SCALABLE;
static void editor_on_mousebutton(const struct Event* event); static void editor_on_mousebutton(const struct Event* event);
static void editor_camera_update(struct Editor* editor, float dt); static void editor_camera_update(struct Editor* editor, float dt);
@ -64,15 +69,22 @@ static bool editor_widget_v3(struct nk_context* context,
float inc_per_pixel, float inc_per_pixel,
int row_height); int row_height);
static void editor_window_scene_heirarchy(struct nk_context* context, struct Editor* editor, struct Game_State* game_state);
static void editor_window_debug_variables(struct nk_context* context, struct Editor* editor);
static void editor_window_property_inspector(struct nk_context* context, struct Editor* editor, struct Game_State* game_state);
void editor_init(struct Editor* editor) void editor_init(struct Editor* editor)
{ {
editor->renderer_settings_window = false; editor->renderer_settings_window = 0;
editor->camera_looking_around = false; editor->window_debug_variables = 0;
editor->selected_entity = NULL; editor->window_property_inspector = 0;
editor->top_panel_height = 30; editor->window_scene_heirarchy = 0;
editor->camera_turn_speed = 50.f; editor->camera_looking_around = 0;
editor->camera_move_speed = 20.f; editor->selected_entity = NULL;
editor->camera_sprint_multiplier = 2.f; editor->top_panel_height = 30;
editor->camera_turn_speed = 50.f;
editor->camera_move_speed = 20.f;
editor->camera_sprint_multiplier = 2.f;
vec4_fill(&editor->selected_entity_colour, 0.f, 1.f, 0.f, 1.f); vec4_fill(&editor->selected_entity_colour, 0.f, 1.f, 0.f, 1.f);
debug_vars_list = array_new(struct Debug_Variable); debug_vars_list = array_new(struct Debug_Variable);
empty_indices = array_new(int); empty_indices = array_new(int);
@ -204,13 +216,8 @@ void editor_update(struct Editor* editor, float dt)
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;
static int window_flags = NK_WINDOW_BORDER |
NK_WINDOW_CLOSABLE |
NK_WINDOW_MOVABLE |
NK_WINDOW_SCROLL_AUTO_HIDE |
NK_WINDOW_SCALABLE;
/* Top Panel */ /* Top Panel */
if(nk_begin(context, "Top Panel", nk_recti(0, 0, win_width, editor->top_panel_height), NK_WINDOW_NO_SCROLLBAR)) if(nk_begin(context, "Top Panel", nk_recti(0, 0, win_width, editor->top_panel_height), NK_WINDOW_NO_SCROLLBAR))
{ {
@ -227,260 +234,55 @@ void editor_update(struct Editor* editor, float dt)
frames = 0; frames = 0;
} }
nk_layout_row(context, NK_DYNAMIC, editor->top_panel_height - 10, sizeof(top_panel_ratios) / sizeof(float), top_panel_ratios); nk_menubar_begin(context);
if(nk_button_label(context, "Render Settings"))
editor->renderer_settings_window = !editor->renderer_settings_window;
if(nk_button_label(context, "Save config"))
config_vars_save("config.symtres", DIRT_USER);
nk_spacing(context, 1);
nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps);
nk_layout_row_dynamic(context, editor->top_panel_height, 1);
}
nk_end(context);
/* Left */ nk_layout_row_begin(context, NK_DYNAMIC, editor->top_panel_height, 5);
if(nk_begin(context, "Editor Left", nk_recti(0, editor->top_panel_height, 300, 700), window_flags)) nk_layout_row_push(context, 0.1f);
{ if(nk_menu_begin_label(context, "File", NK_TEXT_CENTERED | NK_TEXT_ALIGN_MIDDLE, nk_vec2(150, 100)))
/* Entities List */
struct Scene* scene = game_state_get()->scene;
if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED))
{ {
nk_layout_row_dynamic(context, 250, 1); nk_layout_row_dynamic(context, 25, 1);
if(nk_group_begin(context, "Entity Name", NK_WINDOW_SCROLL_AUTO_HIDE)) nk_menu_item_label(context, "Open", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE);
nk_menu_item_label(context, "Save", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE);
if(nk_menu_item_label(context, "Back to Game", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE))
{ {
game_state->game_mode = GAME_MODE_GAME;
for(int i = 0; i < MAX_ENTITIES; i++) editor_show_entity_in_list(editor, context, scene, &scene->entities[i]); game_state->scene->active_camera_index = CAM_GAME;
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_STATIC_MESHES; i++) editor_show_entity_in_list(editor, context, scene, &scene->static_meshes[i]);
nk_group_end(context);
} }
nk_tree_pop(context); nk_menu_end(context);
} }
/* Debug Variables */ nk_layout_row_push(context, 0.1f);
if(nk_tree_push(context, NK_TREE_TAB, "Debug Variables", NK_MAXIMIZED)) if(nk_menu_begin_label(context, "Settings", NK_TEXT_CENTERED | NK_TEXT_ALIGN_MIDDLE, nk_vec2(150, 100)))
{ {
static char variant_str[MAX_VARIANT_STR_LEN] = { '\0' }; nk_layout_row_dynamic(context, 25, 1);
nk_layout_row_dynamic(context, 250, 1); if(nk_menu_item_label(context, "Render Settings", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE)) editor->renderer_settings_window = !editor->renderer_settings_window;
if(nk_group_begin(context, "Name", NK_WINDOW_SCROLL_AUTO_HIDE)) nk_menu_end(context);
{
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;
nk_layout_row_dynamic(context, 20, 2);
nk_label(context, debug_var->name, NK_TEXT_ALIGN_LEFT);
variant_to_str(&debug_var->data, variant_str, 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_end(context);
/* Right */ nk_layout_row_push(context, 0.1f);
if(nk_begin(context, "Editor Right", nk_recti(win_width - 300, editor->top_panel_height, 400, 700), window_flags)) if(nk_menu_begin_label(context, "Windows", NK_TEXT_CENTERED | NK_TEXT_ALIGN_MIDDLE, nk_vec2(180, 100)))
{
/* Entity Inspector */
if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED))
{ {
const int row_height = 18; nk_layout_row_dynamic(context, 25, 1);
if(editor->selected_entity) nk_checkbox_label(context, "Scene Heirarchy", &editor->window_scene_heirarchy);
{ nk_checkbox_label(context, "Property Inspector", &editor->window_property_inspector);
struct Scene* scene = game_state_get()->scene; nk_checkbox_label(context, "Debug Variables", &editor->window_debug_variables);
struct Entity* entity = editor->selected_entity; nk_menu_end(context);
}
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, "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, "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);
/* 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))
{
entity->transform.scale = abs_scale;
transform_update_transmat(entity);
}
}
/* Light */
if(entity->type == ET_LIGHT)
{
if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED))
{
struct Light* light = (struct Light*)entity;
if(light->type > LT_POINT)
{
nk_layout_row_dynamic(context, row_height, 1);
nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED);
}
else
{
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_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_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED);
nk_layout_row_dynamic(context, row_height, 1);
editor_widget_color_combov3(context, &light->color, 200, 300);
nk_layout_row_dynamic(context, row_height, 1);
nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f);
if(light->type != LT_DIR)
{
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));
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));
nk_layout_row_dynamic(context, row_height, 1);
nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 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_tree_pop(context);
}
}
/* Camera */
if(entity->type == ET_CAMERA)
{
if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED))
{
bool update = false;
struct Camera* camera = (struct Camera*)entity;
nk_layout_row_dynamic(context, row_height, 2);
nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE);
bool ortho = nk_checkbox_label(context, "", &camera->ortho);
if(ortho != camera->ortho)
{
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);
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);
if(new_zoom != camera->zoom)
{
camera->zoom = new_zoom;
update = true;
}
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); nk_layout_row_push(context, 0.6f);
float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f); nk_spacing(context, 1);
if(new_far_z != camera->farz)
{
camera->farz = new_far_z;
update = true;
}
if(update) nk_layout_row_push(context, 0.1f);
{ nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps);
camera_update_view(entity);
camera_update_proj(entity); nk_menubar_end(context);
}
nk_tree_pop(context);
}
}
}
else
{
nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED);
}
nk_tree_pop(context);
}
} }
nk_end(context); nk_end(context);
// 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);
// if(editor->window_scene_heirarchy) editor_window_scene_heirarchy(context, editor, game_state);
// } if(editor->window_debug_variables) editor_window_debug_variables(context, editor);
// nk_end(context); if(editor->window_property_inspector) editor_window_property_inspector(context, editor, game_state);
// context->style.window.padding = default_padding;
/* Render Settings Window */ /* Render Settings Window */
if(editor->renderer_settings_window) if(editor->renderer_settings_window)
@ -821,6 +623,246 @@ void editor_show_entity_in_list(struct Editor* editor, struct nk_context* contex
if(entity->editor_selected) if(entity->editor_selected)
{ {
editor->selected_entity = entity; editor->selected_entity = entity;
if(!editor->window_property_inspector) editor->window_property_inspector = true;
}
}
}
void editor_window_scene_heirarchy(struct nk_context* context, struct Editor* editor, struct Game_State* game_state)
{
if(nk_begin(context, "Scene Heirarchy", nk_recti(0, editor->top_panel_height, 300, 400), window_flags))
{
struct Scene* scene = game_state_get()->scene;
nk_layout_row_dynamic(context, 350, 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_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_STATIC_MESHES; i++) editor_show_entity_in_list(editor, context, scene, &scene->static_meshes[i]);
nk_group_end(context);
} }
} }
else
{
editor->window_scene_heirarchy = false;
}
nk_end(context);
}
void editor_window_debug_variables(struct nk_context* context, struct Editor* editor)
{
if(nk_begin(context, "Debug Variables", nk_recti(0, 500, 300, 400), window_flags))
{
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))
{
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;
nk_layout_row_dynamic(context, 20, 2);
nk_label(context, debug_var->name, NK_TEXT_ALIGN_LEFT);
variant_to_str(&debug_var->data, variant_str, 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);
}
}
else
{
editor->window_debug_variables = false;
}
nk_end(context);
}
void editor_window_property_inspector(struct nk_context* context, struct Editor* editor, struct Game_State* game_state)
{
int win_width = 0, win_height = 0;
window_get_drawable_size(game_state->window, &win_width, &win_height);
if(nk_begin(context, "Properties", nk_recti(win_width - 300, editor->top_panel_height, 300, 600), window_flags))
{
const int row_height = 18;
if(editor->selected_entity)
{
struct Scene* scene = game_state_get()->scene;
struct Entity* entity = editor->selected_entity;
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, "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, "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);
/* 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))
{
entity->transform.scale = abs_scale;
transform_update_transmat(entity);
}
}
/* Light */
if(entity->type == ET_LIGHT)
{
if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED))
{
struct Light* light = (struct Light*)entity;
if(light->type > LT_POINT)
{
nk_layout_row_dynamic(context, row_height, 1);
nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED);
}
else
{
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_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_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED);
nk_layout_row_dynamic(context, row_height, 1);
editor_widget_color_combov3(context, &light->color, 200, 300);
nk_layout_row_dynamic(context, row_height, 1);
nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f);
if(light->type != LT_DIR)
{
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));
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));
nk_layout_row_dynamic(context, row_height, 1);
nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 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_tree_pop(context);
}
}
/* Camera */
if(entity->type == ET_CAMERA)
{
if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED))
{
bool update = false;
struct Camera* camera = (struct Camera*)entity;
nk_layout_row_dynamic(context, row_height, 2);
nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE);
bool ortho = nk_checkbox_label(context, "", &camera->ortho);
if(ortho != camera->ortho)
{
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);
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);
if(new_zoom != camera->zoom)
{
camera->zoom = new_zoom;
update = true;
}
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);
}
}
else
{
editor->window_property_inspector = false;
}
nk_end(context);
} }

@ -9,8 +9,11 @@ struct Entity;
struct Editor struct Editor
{ {
bool renderer_settings_window; int renderer_settings_window;
bool camera_looking_around; int window_scene_heirarchy;
int window_property_inspector;
int window_debug_variables;
int camera_looking_around;
struct Entity* selected_entity; struct Entity* selected_entity;
int top_panel_height; int top_panel_height;
float camera_turn_speed; float camera_turn_speed;

@ -411,44 +411,46 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene)
} }
//Editor related rendering //Editor related rendering
editor_render(game_state->editor, active_camera); if(game_state->game_mode == GAME_MODE_EDITOR)
if(game_state->editor->selected_entity)
{ {
if(game_state->editor->selected_entity->type == ET_STATIC_MESH) editor_render(game_state->editor, active_camera);
if(game_state->editor->selected_entity)
{ {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if(game_state->editor->selected_entity->type == ET_STATIC_MESH)
shader_bind(renderer->debug_shader);
{ {
static mat4 mvp; glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &game_state->editor->selected_entity_colour); shader_bind(renderer->debug_shader);
struct Static_Mesh* mesh = (struct Static_Mesh*)game_state->editor->selected_entity; {
struct Model* model = &mesh->model; static mat4 mvp;
struct Transform* transform = &mesh->base.transform; shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &game_state->editor->selected_entity_colour);
int geometry = model->geometry_index; struct Static_Mesh* mesh = (struct Static_Mesh*)game_state->editor->selected_entity;
mat4_identity(&mvp); struct Model* model = &mesh->model;
mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); struct Transform* transform = &mesh->base.transform;
shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); int geometry = model->geometry_index;
geom_render(geometry, GDM_TRIANGLES); mat4_identity(&mvp);
} mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat);
shader_unbind(); shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); geom_render(geometry, GDM_TRIANGLES);
}
shader_unbind();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} }
else else
{ {
//For now just draw a placeholder sphere just to visually denote that the entity is selected //For now just draw a placeholder sphere just to visually denote that the entity is selected
vec3 abs_pos; vec3 abs_pos;
quat abs_rot; quat abs_rot;
transform_get_absolute_position(game_state->editor->selected_entity, &abs_pos); transform_get_absolute_position(game_state->editor->selected_entity, &abs_pos);
transform_get_absolute_rot(game_state->editor->selected_entity, &abs_rot); 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); im_sphere(1.f, abs_pos, abs_rot, game_state->editor->selected_entity_colour, GDM_TRIANGLES);
}
} }
} }
//Immediate mode geometry render //Immediate mode geometry render
im_render(active_camera); im_render(active_camera);
/* Render 2D stuff */ /* Render 2D stuff */
shader_bind(renderer->sprite_batch->shader); shader_bind(renderer->sprite_batch->shader);
{ {

@ -1,5 +1,5 @@
Todo: Todo:
- Implement proper topbar - Change all usages of bool types and nuklear causing buggy behaviour in editor code
- Specific rendering mode for editor related rendering - Specific rendering mode for editor related rendering
- Basic Editor gizmo for transformation i.e. translate/rotate/scale in world and local coordinates - Basic Editor gizmo for transformation i.e. translate/rotate/scale in world and local coordinates
- 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
@ -207,4 +207,5 @@ Done:
* Implemented showing a placeholder when an entity other than a static mesh is 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 * 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 * Implemented handling drawing other entity types that can be selected in the editor but are not static meshes
* Implemented proper topbar

Loading…
Cancel
Save