diff --git a/assets/scenes/Level_1.symtres b/assets/scenes/Level_1.symtres index c9d0130..04af975 100755 --- a/assets/scenes/Level_1.symtres +++ b/assets/scenes/Level_1.symtres @@ -16,9 +16,9 @@ Player { type : 2 scale : 1.000 1.000 1.000 - rotation : 0.000 -0.197 0.000 0.981 + rotation : 0.000 -0.616 0.000 0.789 active : true - position : 7.444 6.491 0.938 + position : -33.936 4.392 -38.211 name : Player camera_clear_color : 0.298 0.600 0.898 1.000 } @@ -29,7 +29,7 @@ Scene_Entity_Entry rotation : 0.000 0.000 0.000 1.000 position : -17.000 0.000 -20.000 filename : cube - name : Cube + name : Ground } Scene_Entity_Entry @@ -37,7 +37,7 @@ Scene_Entity_Entry scale : 68.000 3.000 1.000 rotation : 0.000 0.000 0.000 1.000 position : -18.000 3.000 -57.000 - filename : cube + filename : cube_uv name : Cube } diff --git a/assets/shaders/blinn_phong.frag b/assets/shaders/blinn_phong.frag index 9c52702..e5ddd46 100755 --- a/assets/shaders/blinn_phong.frag +++ b/assets/shaders/blinn_phong.frag @@ -109,7 +109,7 @@ vec3 calc_spot_light(in Light light) void main() { - vec4 albedo_color = diffuse_color * texture(diffuse_texture, uv); + vec4 albedo_color = diffuse_color * texture(diffuse_texture, vec2(uv.x * uv_scale.x, uv.y * uv_scale.y)); vec3 light_contribution = vec3(0.0, 0.0, 0.0); for(int i = 0; i < total_active_lights; i++) diff --git a/assets/shaders/commonFrag.glsl b/assets/shaders/commonFrag.glsl index 76c8fa4..250a4ce 100755 --- a/assets/shaders/commonFrag.glsl +++ b/assets/shaders/commonFrag.glsl @@ -11,3 +11,4 @@ in vec3 vertex; uniform vec3 ambient_light; uniform vec3 camera_pos; +uniform vec2 uv_scale; diff --git a/assets/shaders/unshaded.frag b/assets/shaders/unshaded.frag index 12b1241..b6c1849 100755 --- a/assets/shaders/unshaded.frag +++ b/assets/shaders/unshaded.frag @@ -6,5 +6,5 @@ out vec4 frag_color; void main() { - frag_color = apply_fog(diffuse_color * texture(diffuse_texture, uv)); + frag_color = apply_fog(diffuse_color * texture(diffuse_texture, vec2(uv.x * uv_scale.x, uv.y * uv_scale.y))); } diff --git a/src/common/linmath.c b/src/common/linmath.c index c440c61..dcfe751 100755 --- a/src/common/linmath.c +++ b/src/common/linmath.c @@ -65,6 +65,15 @@ void vec2_mul(vec2* res, vec2* v1, vec2* v2) res->y = v1->y * v2->y; } +int vec2_equals(vec2* v1, vec2* v2) +{ + if((v1->x < (v2->x + EPSILON) && v1->x >(v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y >(v2->y - EPSILON))) + return 1; + + return 0; +} + void vec3_fill(vec3* res, float x, float y, float z) { res->x = x; diff --git a/src/common/linmath.h b/src/common/linmath.h index 47403c4..dda489f 100755 --- a/src/common/linmath.h +++ b/src/common/linmath.h @@ -74,6 +74,7 @@ void vec2_assign(vec2* res, const vec2* val); void vec2_mul(vec2* res, vec2* v1, vec2* v2); float vec2_len(vec2* val); void vec2_norm(vec2* res, vec2* val); +int vec2_equals(vec2* v1, vec2* v2); /* vec3 */ void vec3_fill(vec3* res, float x, float y, float z); diff --git a/src/game/editor.c b/src/game/editor.c index c0f1b65..2dc1d49 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -85,6 +85,15 @@ static bool editor_widget_v3(struct nk_context* context, float step, float inc_per_pixel, int row_height); +static bool editor_widget_v2(struct nk_context* context, + vec2* value, + const char* name_x, + const char* name_y, + float min, + float max, + float step, + float inc_per_pixel, + int row_height); static void editor_window_scene_hierarchy(struct nk_context* context, struct Editor* editor, struct Game_State* game_state); static void editor_window_property_inspector(struct nk_context* context, struct Editor* editor, struct Game_State* game_state); @@ -1591,6 +1600,16 @@ bool editor_widget_v3(struct nk_context* context, vec3* value, const char* name_ return changed; } +bool editor_widget_v2(struct nk_context* context, vec2* value, const char* name_x, const char* name_y, float min, float max, float step, float inc_per_pixel, int row_height) +{ + bool changed = false; + vec2 val_copy = {0.f, 0.f}; + vec2_assign(&val_copy, value); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_x, min, &value->x, max, step, inc_per_pixel); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_y, min, &value->y, max, step, inc_per_pixel); + if(!vec2_equals(&val_copy, value)) changed = true; + return changed; +} void editor_show_entity_in_list(struct Editor* editor, struct nk_context* context, struct Scene* scene, struct Entity* entity) { @@ -2133,6 +2152,10 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor* nk_layout_row_dynamic(context, row_height, 1); mesh->model.material_params[MMP_SPECULAR_STRENGTH].val_float = nk_propertyf(context, "Specular Strength", 0.f, mesh->model.material_params[MMP_SPECULAR_STRENGTH].val_float, 100.f, 0.5f, 0.1f); } + + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "UV Scale", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_CENTERED); + editor_widget_v2(context, &mesh->model.material_params[MMP_UV_SCALE].val_vec2, "U", "V", 0.f, FLT_MAX, 0.1f, 0.1f, row_height); nk_tree_pop(context); } diff --git a/src/game/entity.c b/src/game/entity.c index dd13156..8e43b56 100755 --- a/src/game/entity.c +++ b/src/game/entity.c @@ -170,10 +170,12 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object, bool writ hashmap_float_set(entity_data, "diffuse", model->material_params[MMP_DIFFUSE].val_float); hashmap_float_set(entity_data, "specular", model->material_params[MMP_SPECULAR].val_float); hashmap_float_set(entity_data, "specular_strength", model->material_params[MMP_SPECULAR_STRENGTH].val_float); + hashmap_vec2_set(entity_data, "uv_scale", &model->material_params[MMP_UV_SCALE].val_vec2); break; case MAT_UNSHADED: - hashmap_vec3_set(entity_data, "diffuse_color", &mesh->model.material_params[MMP_DIFFUSE_COL].val_vec3); + hashmap_vec3_set(entity_data, "diffuse_color", &model->material_params[MMP_DIFFUSE_COL].val_vec3); hashmap_str_set(entity_data, "diffuse_texture", model->material_params[MMP_DIFFUSE_TEX].val_int == -1 ? "default.tga" : texture_get_name(model->material_params[MMP_DIFFUSE_TEX].val_int)); + hashmap_vec2_set(entity_data, "uv_scale", &model->material_params[MMP_UV_SCALE].val_vec2); break; }; @@ -243,7 +245,7 @@ bool entity_save(struct Entity* entity, const char* filename, int directory_type { struct Parser_Object* child_object = parser_object_new(parser, PO_ENTITY); struct Entity* child_entity = entity->transform.children[i]; - if (!entity_write(child_entity, child_object, true)) + if(!entity_write(child_entity, child_object, true)) { log_error("entity:save", "Failed to write child entity : %s for parent entity : %s to file : %s", entity->name, child_entity->name, prefixed_filename); parser_free(parser); @@ -255,6 +257,8 @@ bool entity_save(struct Entity* entity, const char* filename, int directory_type if(parser_write_objects(parser, entity_file, prefixed_filename)) log_message("Entity %s saved to %s", entity->name, prefixed_filename); + //Update the entity's archetype index to the one we just saved + entity->archetype_index = scene_entity_archetype_add(game_state_get()->scene, filename); parser_free(parser); fclose(entity_file); return true; @@ -427,6 +431,7 @@ struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_e if(hashmap_value_exists(object->data, "diffuse")) model->material_params[MMP_DIFFUSE].val_float = hashmap_float_get(object->data, "diffuse"); if(hashmap_value_exists(object->data, "specular")) model->material_params[MMP_SPECULAR].val_float = hashmap_float_get(object->data, "specular"); if(hashmap_value_exists(object->data, "specular_strength")) model->material_params[MMP_SPECULAR_STRENGTH].val_float = hashmap_float_get(object->data, "specular_strength"); + if(hashmap_value_exists(object->data, "uv_scale")) model->material_params[MMP_UV_SCALE].val_vec2 = hashmap_vec2_get(object->data, "uv_scale"); break; case MAT_UNSHADED: if(hashmap_value_exists(object->data, "diffuse_color")) model->material_params[MMP_DIFFUSE_COL].val_vec4 = hashmap_vec4_get(object->data, "diffuse_color"); @@ -435,6 +440,7 @@ struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_e const char* texture_name = hashmap_str_get(object->data, "diffuse_texture"); model->material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file(texture_name, TU_DIFFUSE); } + if(hashmap_value_exists(object->data, "uv_scale")) model->material_params[MMP_UV_SCALE].val_vec2 = hashmap_vec2_get(object->data, "uv_scale"); break; }; } diff --git a/src/game/material.c b/src/game/material.c index f0295c8..bc86ca4 100755 --- a/src/game/material.c +++ b/src/game/material.c @@ -63,6 +63,9 @@ bool material_init(struct Material* material, int material_type) material->model_params[MMP_SPECULAR_STRENGTH].type = UT_FLOAT; material->model_params[MMP_SPECULAR_STRENGTH].location = shader_get_uniform_location(material->shader, "specular_strength"); + + material->model_params[MMP_UV_SCALE].type = UT_VEC2; + material->model_params[MMP_UV_SCALE].location = shader_get_uniform_location(material->shader, "uv_scale"); } break; case MAT_UNSHADED: @@ -82,6 +85,9 @@ bool material_init(struct Material* material, int material_type) material->model_params[MMP_DIFFUSE_COL].type = UT_VEC4; material->model_params[MMP_DIFFUSE_COL].location = shader_get_uniform_location(material->shader, "diffuse_color"); + + material->model_params[MMP_UV_SCALE].type = UT_VEC2; + material->model_params[MMP_UV_SCALE].location = shader_get_uniform_location(material->shader, "uv_scale"); }; break; default: @@ -150,6 +156,7 @@ bool material_register_static_mesh(struct Material* material, struct Static_Mesh variant_assign_int(&mesh->model.material_params[MMP_DIFFUSE_TEX], texture_create_from_file("default.tga", TU_DIFFUSE)); variant_assign_float(&mesh->model.material_params[MMP_SPECULAR], 1.f); variant_assign_float(&mesh->model.material_params[MMP_SPECULAR_STRENGTH], 50.f); + variant_assign_vec2f(&mesh->model.material_params[MMP_UV_SCALE], 1.f, 1.f); mesh->model.material = material; } break; @@ -157,6 +164,7 @@ bool material_register_static_mesh(struct Material* material, struct Static_Mesh { variant_assign_vec4f(&mesh->model.material_params[MMP_DIFFUSE_COL], 1.f, 0.f, 1.f, 1.f); variant_assign_int(&mesh->model.material_params[MMP_DIFFUSE_TEX], texture_create_from_file("default.tga", TU_DIFFUSE)); + variant_assign_vec2f(&mesh->model.material_params[MMP_UV_SCALE], 1.f, 1.f); mesh->model.material = material; } break; diff --git a/src/game/material.h b/src/game/material.h index c41944b..1099e88 100755 --- a/src/game/material.h +++ b/src/game/material.h @@ -30,6 +30,7 @@ enum Mat_Model_Param MMP_DIFFUSE, MMP_SPECULAR_STRENGTH, MMP_SPECULAR, + MMP_UV_SCALE, MMP_MAX }; diff --git a/src/game/renderer.c b/src/game/renderer.c index 69a8dc2..20f0947 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -278,6 +278,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene) { case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break; case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break; + case VT_VEC2: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec2)); break; case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break; case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break; } diff --git a/todo.txt b/todo.txt index 4208fa8..ce001de 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,12 @@ Todo: - Re-write/Overhaul bounding volumes and ray intersection - - Add uv tiling parameter to materials that can be serialized along with entities - Reduce the opacity of wireframe around selected entity in editor - - Write player camera clear colour when saving scene - Allow picking and selecting other entity types in editor i.e. the ones that don't have meshes + ? Save transformation information when saving entity archetypes + ? When saving a scene entity entry, save the changed properties as well, that way when the scene is loaded, we load the base properties from archetype and the ones we changed per entry are saved when we saved the entity + this will prevent us from having needless amount of entities with only minor changes from one another + ? Split up material declarations into their own separate files. Materials have a base material like Blinn or Unshaded and in the file we save an instance with modified properties. + when we are assigning materials to entites, we assign the instance of a particular material to them. - When loading entities, show an additional optional textfield where user can enter the name they want for the entity after it is loaded - Add editor undo for transformation operations - Decide how to handle scale when checking sphere-ray intersection @@ -387,4 +390,6 @@ Done: * Associate each scene with a file so that when C-s is pressed the scene is automatically saved to that file * Change the increments in the editor from 5 to 1 * Separate entity types in entity hierarchy view by the entity type or use a tree view to show parent/child relation or use different colours for different entity types - * Show archetype name in property inspector for selected entity \ No newline at end of file + * Show archetype name in property inspector for selected entity + * Write player camera clear colour when saving scene + * Add uv tiling parameter to materials that can be serialized along with entities \ No newline at end of file