Implemented a uniform parameter that allows scaling the uvs for a particular entity and is saved/loaded along with the entity

dev
Shariq Shah 6 years ago
parent 964cbc3321
commit b8b4f13809
  1. 8
      assets/scenes/Level_1.symtres
  2. 2
      assets/shaders/blinn_phong.frag
  3. 1
      assets/shaders/commonFrag.glsl
  4. 2
      assets/shaders/unshaded.frag
  5. 9
      src/common/linmath.c
  6. 1
      src/common/linmath.h
  7. 23
      src/game/editor.c
  8. 10
      src/game/entity.c
  9. 8
      src/game/material.c
  10. 1
      src/game/material.h
  11. 1
      src/game/renderer.c
  12. 9
      todo.txt

@ -16,9 +16,9 @@ Player
{ {
type : 2 type : 2
scale : 1.000 1.000 1.000 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 active : true
position : 7.444 6.491 0.938 position : -33.936 4.392 -38.211
name : Player name : Player
camera_clear_color : 0.298 0.600 0.898 1.000 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 rotation : 0.000 0.000 0.000 1.000
position : -17.000 0.000 -20.000 position : -17.000 0.000 -20.000
filename : cube filename : cube
name : Cube name : Ground
} }
Scene_Entity_Entry Scene_Entity_Entry
@ -37,7 +37,7 @@ Scene_Entity_Entry
scale : 68.000 3.000 1.000 scale : 68.000 3.000 1.000
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
position : -18.000 3.000 -57.000 position : -18.000 3.000 -57.000
filename : cube filename : cube_uv
name : Cube name : Cube
} }

@ -109,7 +109,7 @@ vec3 calc_spot_light(in Light light)
void main() 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); vec3 light_contribution = vec3(0.0, 0.0, 0.0);
for(int i = 0; i < total_active_lights; i++) for(int i = 0; i < total_active_lights; i++)

@ -11,3 +11,4 @@ in vec3 vertex;
uniform vec3 ambient_light; uniform vec3 ambient_light;
uniform vec3 camera_pos; uniform vec3 camera_pos;
uniform vec2 uv_scale;

@ -6,5 +6,5 @@ out vec4 frag_color;
void main() 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)));
} }

@ -65,6 +65,15 @@ void vec2_mul(vec2* res, vec2* v1, vec2* v2)
res->y = v1->y * v2->y; 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) void vec3_fill(vec3* res, float x, float y, float z)
{ {
res->x = x; res->x = x;

@ -74,6 +74,7 @@ void vec2_assign(vec2* res, const vec2* val);
void vec2_mul(vec2* res, vec2* v1, vec2* v2); void vec2_mul(vec2* res, vec2* v1, vec2* v2);
float vec2_len(vec2* val); float vec2_len(vec2* val);
void vec2_norm(vec2* res, vec2* val); void vec2_norm(vec2* res, vec2* val);
int vec2_equals(vec2* v1, vec2* v2);
/* vec3 */ /* vec3 */
void vec3_fill(vec3* res, float x, float y, float z); void vec3_fill(vec3* res, float x, float y, float z);

@ -85,6 +85,15 @@ static bool editor_widget_v3(struct nk_context* context,
float step, float step,
float inc_per_pixel, float inc_per_pixel,
int row_height); 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_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); 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; 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) void editor_show_entity_in_list(struct Editor* editor, struct nk_context* context, struct Scene* scene, struct Entity* entity)
{ {
@ -2134,6 +2153,10 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor*
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); 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); nk_tree_pop(context);
} }
} }

@ -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, "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", model->material_params[MMP_SPECULAR].val_float);
hashmap_float_set(entity_data, "specular_strength", model->material_params[MMP_SPECULAR_STRENGTH].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; break;
case MAT_UNSHADED: 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_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; 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 Parser_Object* child_object = parser_object_new(parser, PO_ENTITY);
struct Entity* child_entity = entity->transform.children[i]; 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); 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); 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)) if(parser_write_objects(parser, entity_file, prefixed_filename))
log_message("Entity %s saved to %s", entity->name, 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); parser_free(parser);
fclose(entity_file); fclose(entity_file);
return true; 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, "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")) 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, "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; break;
case MAT_UNSHADED: 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"); 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"); 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); 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; break;
}; };
} }

@ -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].type = UT_FLOAT;
material->model_params[MMP_SPECULAR_STRENGTH].location = shader_get_uniform_location(material->shader, "specular_strength"); 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; break;
case MAT_UNSHADED: 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].type = UT_VEC4;
material->model_params[MMP_DIFFUSE_COL].location = shader_get_uniform_location(material->shader, "diffuse_color"); 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; break;
default: 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_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], 1.f);
variant_assign_float(&mesh->model.material_params[MMP_SPECULAR_STRENGTH], 50.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; mesh->model.material = material;
} }
break; 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_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_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; mesh->model.material = material;
} }
break; break;

@ -30,6 +30,7 @@ enum Mat_Model_Param
MMP_DIFFUSE, MMP_DIFFUSE,
MMP_SPECULAR_STRENGTH, MMP_SPECULAR_STRENGTH,
MMP_SPECULAR, MMP_SPECULAR,
MMP_UV_SCALE,
MMP_MAX MMP_MAX
}; };

@ -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_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_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_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; 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;
} }

@ -1,9 +1,12 @@
Todo: Todo:
- Re-write/Overhaul bounding volumes and ray intersection - 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 - 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 - 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 - When loading entities, show an additional optional textfield where user can enter the name they want for the entity after it is loaded
- Add editor undo for transformation operations - Add editor undo for transformation operations
- Decide how to handle scale when checking sphere-ray intersection - Decide how to handle scale when checking sphere-ray intersection
@ -388,3 +391,5 @@ Done:
* Change the increments in the editor from 5 to 1 * 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 * 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 * 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
Loading…
Cancel
Save