diff --git a/orgfile.org b/orgfile.org index 8da50f2..35db945 100644 --- a/orgfile.org +++ b/orgfile.org @@ -47,11 +47,14 @@ while using as few libraries as possible. - State "DONE" from "TODO" [2015-08-19 Wed 13:30] ** TODO Bounding Boxes ** TODO File extension checking for asset loading -** TODO Materials -** TODO Mesh/Model +** DONE Materials +- State "DONE" from "TODO" [2015-10-13 Tue 19:38] +** DONE Mesh/Model +- State "DONE" from "TODO" [2015-10-13 Tue 19:38] ** TODO Add modifiers to input maps to enable combinations for example, c-x, m-k etc ** DONE Heirarchical Transforms -- State "DONE" from "TODO" [2015-09-14 Mon 20:55] +** DONE Materials with textures +- State "DONE" from "TODO" [2015-10-15 Thu 21:21] ** TODO 2d drawing routines ** TODO Gui ** TODO Physics diff --git a/src/game.c b/src/game.c index 70640b1..e4b5a89 100644 --- a/src/game.c +++ b/src/game.c @@ -86,29 +86,31 @@ void scene_setup(void) struct Entity* new_ent = scene_add_new("Model_Entity", NULL); struct Transform* tran = entity_component_get(new_ent, C_TRANSFORM); vec3 position = {0, 0, -5}; + vec4 color = {1.f, 1.f, 1.f, 1.f }; transform_translate(tran, &position, TS_WORLD); - entity_component_add(new_ent, C_MODEL, "default.pamesh"); + struct Model* box_model = entity_component_add(new_ent, C_MODEL, "default.pamesh"); struct Transform* model_tran = entity_component_get(new_ent, C_TRANSFORM); vec3 scale = {1, 1, 2}; transform_scale(model_tran, &scale); struct Entity* suz = scene_add_as_child("Suzanne", NULL, new_ent); - entity_component_add(suz, C_MODEL, "suzanne.pamesh"); + struct Model* suz_model = entity_component_add(suz, C_MODEL, "suzanne.pamesh"); struct Transform* s_tran = entity_component_get(suz, C_TRANSFORM); vec3 s_pos = {3, 0, 0}; transform_translate(s_tran, &s_pos, TS_WORLD); struct Entity* ground = scene_add_new("Ground", NULL); struct Model* ground_model = entity_component_add(ground, C_MODEL, "plane.pamesh"); - vec3 color = {1.f, 0.5f, 0.1 }; - model_set_material_param(ground_model, "diffuse_color", &color); struct Transform* ground_tran = entity_component_get(ground, C_TRANSFORM); vec3 pos = {0, -3, -3}; vec3 scale_ground = {0.5f, 0.5f, 3.f}; transform_set_position(ground_tran, &pos); transform_scale(ground_tran, &scale_ground); - texture_create_from_file("test_comp.tga"); + /* Set material params */ + model_set_material_param(ground_model, "diffuse_color", &color); + model_set_material_param(suz_model, "diffuse_color", &color); + model_set_material_param(box_model, "diffuse_color", &color); } void debug(float dt) diff --git a/src/material.c b/src/material.c index 9b52897..e41bff9 100644 --- a/src/material.c +++ b/src/material.c @@ -4,6 +4,7 @@ #include "string_utils.h" #include "log.h" #include "model.h" +#include "texture.h" #include #include @@ -34,7 +35,12 @@ void material_init(void) uniform = array_grow(unshaded_mat->model_params, struct Uniform); uniform->name = str_new("diffuse_color"); uniform->type = UT_VEC4; - uniform->location = shader_get_uniform_location(unshaded_mat->shader, "diffuse_color"); + uniform->location = shader_get_uniform_location(unshaded_mat->shader, uniform->name); + + uniform = array_grow(unshaded_mat->model_params, struct Uniform); + uniform->name = str_new("diffuse_texture"); + uniform->type = UT_TEX; + uniform->location = shader_get_uniform_location(unshaded_mat->shader, uniform->name); } struct Material* material_get_all_materials(void) @@ -95,6 +101,10 @@ int material_register_model(struct Model* model, int model_index, const char* ma param->value = malloc(sizeof(mat4)); mat4_identity((mat4*)param->value); break; + case UT_TEX: + param->value = malloc(sizeof(int)); + *((int*)param->value) = texture_create_from_file("default.tga", TU_DIFFUSE); + break; } } array_push(material->registered_models, model_index, int); @@ -106,6 +116,14 @@ void material_unregister_model(struct Model* model, int model_index) { assert(model); struct Material* material = &material_list[model->material]; + /* Remove textures, if any */ + for(int i = 0; i < array_len(model->material_params); i++) + { + struct Material_Param* param = &model->material_params[i]; + struct Uniform* uniform = &material->model_params[param->uniform_index]; + if(uniform->type == UT_TEX) + texture_remove(*(int*)param->value); + } /* Remove model index from material registry*/ for(int i = 0; i < array_len(material->registered_models); i++) { @@ -169,4 +187,3 @@ void material_remove(int index) free(material->name); array_push(empty_indices, index, int); } - diff --git a/src/model.c b/src/model.c index ea868ae..32fef96 100644 --- a/src/model.c +++ b/src/model.c @@ -82,6 +82,7 @@ void model_remove(int index) /* deallocate all params */ for(int i = 0; i < array_len(model->material_params); i++) free(&model->material_params[i]); + array_free(model->material_params); array_push(empty_indices, index, int); } @@ -144,27 +145,22 @@ void model_render_all(struct Camera* camera) } } /* Render the geometry */ - geom_render(model->geometry_index); + geom_render(model->geometry_index); + + for(int k = 0; k < array_len(model->material_params); k++) + { + /* unbind textures, if any */ + struct Material_Param* param = &model->material_params[k]; + struct Uniform* uniform = &material->model_params[param->uniform_index]; + if(uniform->type == UT_TEX) + { + texture_unbind(*(int*)param->value); + renderer_check_glerror("model:render_all:unbind_texture_uniform"); + } + } } shader_unbind(); } - /* for(int i = 0; i < array_len(model_list); i++) */ - /* { */ - /* struct Model* model = &model_list[i]; */ - /* struct Entity* entity = entity_get(model->node); */ - /* struct Transform* transform = entity_component_get(entity, C_TRANSFORM); */ - - /* shader_bind(model->shader); */ - /* shader_set_uniform_int(model->shader, "sampler", (GL_TEXTURE0 + 4) - GL_TEXTURE0); */ - /* texture_bind(texture, 4); */ - /* renderer_check_glerror("model:render_all"); */ - /* mat4_mul(&mvp, &camera->view_proj_mat, &transform->trans_mat); */ - /* shader_set_uniform_mat4(model->shader, "mvp", &mvp); */ - /* shader_set_uniform_vec4(model->shader, "diffuseColor", &model->color); */ - /* geom_render(model->geometry_index); */ - /* texture_unbind(4); */ - /* shader_unbind(); */ - /* } */ } int model_set_material_param(struct Model* model, const char* name, void* value) @@ -178,6 +174,7 @@ int model_set_material_param(struct Model* model, const char* name, void* value) struct Uniform* uniform = &material->model_params[param->uniform_index]; if(strcmp(uniform->name, name) == 0) { + success = 1; switch(uniform->type) { case UT_INT: @@ -198,9 +195,15 @@ int model_set_material_param(struct Model* model, const char* name, void* value) case UT_MAT4: mat4_assign((mat4*)param->value, (mat4*)value); break; + case UT_TEX: + log_message("Not implemented yet!"); + break; + default: + log_error("model:set_material_param", "Invalid parameter type"); + success = 0; + break; } break; /* break for */ - success = 1; } } return success; diff --git a/src/shader.c b/src/shader.c index 9bd8054..8932790 100644 --- a/src/shader.c +++ b/src/shader.c @@ -5,6 +5,7 @@ #include "string_utils.h" #include "log.h" #include "renderer.h" +#include "texture.h" #include #include @@ -338,6 +339,15 @@ void shader_set_uniform(const int uniform_type, const int uniform_loc, void* val { mat4* mat = (mat4*)value; glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, &mat->mat[0]); + break; + } + case UT_TEX: + { + int texture_index = *((int*)value); + int texture_unit = texture_get_textureunit(texture_index); + glUniform1i(uniform_loc, (GL_TEXTURE0 + texture_unit) - GL_TEXTURE0); + texture_bind(texture_index); + break; } } } diff --git a/src/shader.h b/src/shader.h index d36cc53..8767053 100644 --- a/src/shader.h +++ b/src/shader.h @@ -10,7 +10,8 @@ enum Uniform_Type UT_VEC3, UT_VEC2, UT_VEC4, - UT_MAT4 + UT_MAT4, + UT_TEX }; int shader_create(const char* vert_shader_name, const char* frag_shader_name); diff --git a/src/texture.c b/src/texture.c index c4e73da..c53d2cc 100644 --- a/src/texture.c +++ b/src/texture.c @@ -17,6 +17,7 @@ struct Texture char* name; uint handle; int ref_count; + int texture_unit; }; #pragma pack(push, 1) @@ -50,10 +51,17 @@ void texture_init(void) empty_indices = array_new(int); } -int texture_create_from_file(const char* filename) +int texture_create_from_file(const char* filename, int texture_unit) { assert(filename); - int index = -1; + /* check if texture is already loaded */ + int index = texture_find(filename); + if(index >= 0) + { + texture_list[index].ref_count++; + return index; + } + /* If texture not already loaded then try to load it */ uint handle = 0; char* full_path = str_new("textures/"); full_path = str_concat(full_path, filename); @@ -81,16 +89,16 @@ int texture_create_from_file(const char* filename) { new_texture = array_grow(texture_list, struct Texture); index = array_len(texture_list) - 1; + new_texture->name = NULL; } assert(new_texture); - - log_message("\nWidth : %d\nHeight : %d\nFormat : %s", - width, height, fmt == GL_RGB ? "RGB" : "RGBA"); glGenTextures(1, &handle); - if(new_texture->name) free(new_texture->name); + if(new_texture->name) + free(new_texture->name); new_texture->name = str_new(filename); new_texture->ref_count = 1; new_texture->handle = handle; + new_texture->texture_unit = texture_unit; glBindTexture(GL_TEXTURE_2D, handle); texture_param_set(index, GL_TEXTURE_MIN_FILTER, GL_LINEAR); texture_param_set(index, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -123,7 +131,9 @@ void texture_remove(int index) { glDeleteTextures(1, &texture->handle); if(texture->name) free(texture->name); + texture->name = NULL; texture->ref_count = -1; + texture->texture_unit = -1; array_push(empty_indices, index, int); } } @@ -155,16 +165,16 @@ void texture_cleanup(void) array_free(empty_indices); } -void texture_bind(int index, int texture_unit) +void texture_bind(int index) { assert(index > -1 && index < array_len(texture_list)); - glActiveTexture(GL_TEXTURE0 + texture_unit); + glActiveTexture(GL_TEXTURE0 + texture_list[index].texture_unit); glBindTexture(GL_TEXTURE_2D, texture_list[index].handle); } -void texture_unbind(int texture_unit) +void texture_unbind(int index) { - glActiveTexture(GL_TEXTURE0 + texture_unit); + glActiveTexture(GL_TEXTURE0 + texture_list[index].texture_unit); glBindTexture(GL_TEXTURE_2D, 0); } @@ -176,20 +186,6 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt if(items_read == 1) { - /* log_message("sizeof struct : %d", sizeof(struct Tga_Header)); */ - /* log_message("%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n", */ - /* header.idlength, */ - /* header.colourmaptype, */ - /* header.datatypecode, */ - /* header.colourmaporigin, */ - /* header.colourmaplength, */ - /* header.colourmapdepth, */ - /* header.x_origin, */ - /* header.y_origin, */ - /* header.width, */ - /* header.height, */ - /* header.bitsperpixel, */ - /* header.imagedescriptor); */ if(header.datatypecode == 0) { log_error("texture:load_img", "No image data in file"); @@ -295,7 +291,7 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt } } - debug_write_tga(&header, *image_data); + //debug_write_tga(&header, *image_data); *height = header.height; *width = header.width; *fmt = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; @@ -356,3 +352,9 @@ void copy_tga_pixel(GLubyte* source, GLubyte* dest, size_t bytes_per_pixel) dest[2] = source[0]; if(bytes_per_pixel == 4) dest[3] = source[3]; } + +int texture_get_textureunit(int index) +{ + assert(index > -1 && index < array_len(texture_list)); + return texture_list[index].texture_unit; +} diff --git a/src/texture.h b/src/texture.h index c70e96b..edb1758 100644 --- a/src/texture.h +++ b/src/texture.h @@ -1,13 +1,23 @@ #ifndef texture_H #define texture_H +enum Texture_Unit +{ + TU_DIFFUSE = 0, + TU_SHADOWMAP1, + TU_SHADOWMAP2, + TU_SHADOWMAP3, + TU_SHADOWMAP4 +}; + void texture_init(void); -int texture_create_from_file(const char* filename); +int texture_create_from_file(const char* filename, int texture_unit); void texture_remove(int index); int texture_find(const char* name); void texture_cleanup(void); -void texture_bind(int index, int texture_unit); -void texture_unbind(int texture_unit); +void texture_bind(int index); +void texture_unbind(int index); void texture_param_set(int index, int parameter, int value); +int texture_get_textureunit(int index); #endif