added simple materials

dev
Shariq Shah 10 years ago
parent 77b93bc480
commit 1bc7fc4e9e
  1. 4
      orgfile.org
  2. 7
      src/game.c
  3. 9
      src/linmath.h
  4. 172
      src/material.c
  5. 39
      src/material.h
  6. 160
      src/model.c
  7. 7
      src/model.h
  8. 41
      src/shader.c
  9. 25
      src/shader.h

@ -39,12 +39,14 @@ while using as few libraries as possible.
** DONE Entity ** DONE Entity
- State "DONE" from "TODO" [2015-09-15 Tue 12:17] - State "DONE" from "TODO" [2015-09-15 Tue 12:17]
** TODO Positive and negative values for input_maps and returning corresponding values when they are true ** TODO Positive and negative values for input_maps and returning corresponding values when they are true
** TODO Textures ** DONE Textures
- State "DONE" from "TODO" [2015-10-09 Fri 18:47]
** DONE Camera ** DONE Camera
- State "DONE" from "TODO" [2015-08-19 Wed 13:30] - State "DONE" from "TODO" [2015-08-19 Wed 13:30]
** DONE Test render ** DONE Test render
- State "DONE" from "TODO" [2015-08-19 Wed 13:30] - State "DONE" from "TODO" [2015-08-19 Wed 13:30]
** TODO Bounding Boxes ** TODO Bounding Boxes
** TODO File extension checking for asset loading
** TODO Materials ** TODO Materials
** TODO Mesh/Model ** TODO Mesh/Model
** TODO Add modifiers to input maps to enable combinations for example, c-x, m-k etc ** TODO Add modifiers to input maps to enable combinations for example, c-x, m-k etc

@ -19,6 +19,7 @@
#include "scene.h" #include "scene.h"
#include "utils.h" #include "utils.h"
#include "texture.h" #include "texture.h"
#include "material.h"
void run(void); void run(void);
void update(float dt); void update(float dt);
@ -41,6 +42,7 @@ void game_init(void)
transform_init(); transform_init();
camera_init(); camera_init();
geom_init(); geom_init();
material_init();
model_init(); model_init();
entity_init(); entity_init();
scene_init(); scene_init();
@ -74,7 +76,6 @@ void scene_setup(void)
input_map_create("Turn_Up", turn_up_keys, 1); input_map_create("Turn_Up", turn_up_keys, 1);
input_map_create("Turn_Down", turn_down_keys, 1); input_map_create("Turn_Down", turn_down_keys, 1);
shader_create("unshaded_textured.vert", "unshaded_textured.frag");
struct Entity* player = scene_add_new("player", "None"); struct Entity* player = scene_add_new("player", "None");
player_node = player->node; player_node = player->node;
vec3 viewer_pos = {0, 0, 10}; vec3 viewer_pos = {0, 0, 10};
@ -99,7 +100,8 @@ void scene_setup(void)
struct Entity* ground = scene_add_new("Ground", NULL); struct Entity* ground = scene_add_new("Ground", NULL);
struct Model* ground_model = entity_component_add(ground, C_MODEL, "plane.pamesh"); struct Model* ground_model = entity_component_add(ground, C_MODEL, "plane.pamesh");
ground_model->color.x = 1.f; 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); struct Transform* ground_tran = entity_component_get(ground, C_TRANSFORM);
vec3 pos = {0, -3, -3}; vec3 pos = {0, -3, -3};
vec3 scale_ground = {0.5f, 0.5f, 3.f}; vec3 scale_ground = {0.5f, 0.5f, 3.f};
@ -262,6 +264,7 @@ void game_cleanup(void)
scene_cleanup(); scene_cleanup();
entity_cleanup(); entity_cleanup();
model_cleanup(); model_cleanup();
material_cleanup();
geom_cleanup(); geom_cleanup();
transform_cleanup(); transform_cleanup();
camera_cleanup(); camera_cleanup();

@ -13,6 +13,13 @@ typedef kmMat3 mat3;
typedef kmMat4 mat4; typedef kmMat4 mat4;
typedef kmQuaternion quat; typedef kmQuaternion quat;
/* vec2 */
#define vec2_fill kmVec2Fill
#define vec2_add kmVec2Add
#define vec2_assign kmVec2Assign
#define vec2_norm kmVec2Normalize
#define vec2_mul kmVec2Mul
/* vec3 */ /* vec3 */
#define vec3_fill kmVec3Fill #define vec3_fill kmVec3Fill
#define vec3_add kmVec3Add #define vec3_add kmVec3Add
@ -52,6 +59,8 @@ typedef kmQuaternion quat;
#define mat4_rot_x kmMat4RotationX #define mat4_rot_x kmMat4RotationX
#define mat4_rot_y kmMat4RotationY #define mat4_rot_y kmMat4RotationY
#define mat4_rot_z kmMat4RotationZ #define mat4_rot_z kmMat4RotationZ
#define mat4_assign kmMat4Assign
#define mat4_assign_mat3 kmMat4AssignMat3
/* quat */ /* quat */
#define quat_identity kmQuaternionIdentity #define quat_identity kmQuaternionIdentity

@ -0,0 +1,172 @@
#include "material.h"
#include "array.h"
#include "shader.h"
#include "string_utils.h"
#include "log.h"
#include "model.h"
#include <string.h>
#include <stdlib.h>
static struct Material* material_list;
static int* empty_indices;
void material_init(void)
{
material_list = array_new(struct Material);
empty_indices = array_new(int);
/* TODO: implement reading material definitions from files */
/* Simple unshaded material */
struct Material* unshaded_mat = array_grow(material_list, struct Material);
unshaded_mat->name = str_new("Unshaded");
unshaded_mat->shader = shader_create("unshaded.vert", "unshaded.frag");
unshaded_mat->registered_models = array_new(int);
unshaded_mat->model_params = array_new(struct Uniform);
unshaded_mat->pipeline_params = array_new(struct Uniform);
unshaded_mat->active = 1;
struct Uniform* uniform = array_grow(unshaded_mat->pipeline_params, struct Uniform);
uniform->name = str_new("mvp");
uniform->type = UT_MAT4;
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_color");
uniform->type = UT_VEC4;
uniform->location = shader_get_uniform_location(unshaded_mat->shader, "diffuse_color");
}
struct Material* material_get_all_materials(void)
{
return material_list;
}
void material_cleanup(void)
{
for(int i = 0; i < array_len(material_list); i++)
material_remove(i);
array_free(empty_indices);
}
int material_register_model(struct Model* model, int model_index, const char* material_name)
{
assert(material_name && model);
int success = 0;
int index = material_get_index(material_name);
if(index < -1)
{
log_error("material:register_model", "Material '%s' not found", material_name);
return success;
}
struct Material* material = &material_list[index];
model->material = index;
model->material_params = array_new(struct Material_Param);
for(int i = 0; i < array_len(material->model_params); i++)
{
/* set up parameters */
struct Uniform* uniform = &material->model_params[i];
struct Material_Param* param = array_grow(model->material_params, struct Material_Param);
param->uniform_index = i;
switch(uniform->type)
{
case UT_INT:
param->value = malloc(sizeof(int));
*((int*)param->value) = -1;
break;
case UT_FLOAT:
param->value = malloc(sizeof(float));
*((float*)param->value) = -1.f;
break;
case UT_VEC2:
param->value = malloc(sizeof(vec2));
vec2_fill((vec2*)param->value, 0.f, 0.f);
break;
case UT_VEC3:
param->value = malloc(sizeof(vec3));
vec3_fill((vec3*)param->value, 0.f, 0.f, 0.f);
break;
case UT_VEC4:
param->value = malloc(sizeof(vec4));
vec4_fill((vec4*)param->value, 0.f, 0.f, 0.f, 0.f);
break;
case UT_MAT4:
param->value = malloc(sizeof(mat4));
mat4_identity((mat4*)param->value);
break;
}
}
array_push(material->registered_models, model_index, int);
success = 1;
return success;
}
void material_unregister_model(struct Model* model, int model_index)
{
assert(model);
struct Material* material = &material_list[model->material];
/* Remove model index from material registry*/
for(int i = 0; i < array_len(material->registered_models); i++)
{
if(material->registered_models[i] == model_index)
{
array_remove_at(material->registered_models, i);
break;
}
}
}
struct Material* material_find(const char* material_name)
{
struct Material* material = NULL;
int index = material_get_index(material_name);
if(index > -1) material = &material_list[index];
return material;
}
int material_get_index(const char* material_name)
{
int index = -1;
for(int i = 0; i < array_len(material_list); i++)
{
if(!material_list[i].name) continue;
if(strcmp(material_name, material_list[i].name) == 0)
{
index = i;
break;
}
}
return index;
}
struct Material* material_get(int index)
{
struct Material* material = NULL;
if(index > -1 && index < array_len(material_list))
material = &material_list[index];
return material;
}
void material_remove(int index)
{
assert(index > -1 && index < array_len(material_list));
struct Material* material = &material_list[index];
if(!material->active)
return;
material->active = 0;
array_free(material->registered_models);
for(int i = 0; i < array_len(material->model_params); i++)
free(material->model_params[i].name);
array_free(material->model_params);
for(int i = 0; i < array_len(material->pipeline_params); i++)
free(material->pipeline_params[i].name);
array_free(material->pipeline_params);
log_message("Removed material '%s'", material->name);
free(material->name);
array_push(empty_indices, index, int);
}

@ -0,0 +1,39 @@
#ifndef material_H
#define material_H
struct Model;
struct Uniform
{
int location;
int type;
char* name;
};
struct Material_Param
{
int uniform_index; /* Index of the corresponding uniform in the material's model_params */
void* value; /* Actual value of the uniform */
};
struct Material
{
char* name;
int shader;
int* registered_models;
int active;
struct Uniform* model_params; /* uniforms related to models */
struct Uniform* pipeline_params; /* general uniforms like matrices etc */
};
struct Material* material_get_all_materials(void);
struct Material* material_find(const char* material_name);
struct Material* material_get(int index);
int material_get_index(const char* material_name);
void material_init(void);
void material_cleanup(void);
int material_register_model(struct Model* model, int model_index, const char* material_name);
void material_unregister_model(struct Model* model, int model_index);
void material_remove(int index);
#endif

@ -8,11 +8,14 @@
#include "transform.h" #include "transform.h"
#include "texture.h" #include "texture.h"
#include "renderer.h" #include "renderer.h"
#include "material.h"
#include "GL/glew.h" #include "GL/glew.h"
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
#include <assert.h> #include <assert.h>
#include <string.h>
#include <stdlib.h>
static struct Model* model_list; static struct Model* model_list;
static int* empty_indices; static int* empty_indices;
@ -53,8 +56,12 @@ int model_create(int node, const char* geo_name)
} }
new_model->node = node; new_model->node = node;
new_model->geometry_index = geo_index; new_model->geometry_index = geo_index;
new_model->shader = 0; /* Temporary, for test run only till materials are added */ if(!material_register_model(new_model, index, "Unshaded"))
vec4_fill(&new_model->color, 0.7f, 0.7f, 0.5f, 1.f); {
log_error("model:create", "Unable to register model with Unshaded material, component not added");
model_remove(index);
index = -1;
}
} }
else else
{ {
@ -71,7 +78,11 @@ void model_remove(int index)
model->node = -1; model->node = -1;
geom_remove(model->geometry_index); geom_remove(model->geometry_index);
model->geometry_index = -1; model->geometry_index = -1;
model->shader = -1; material_unregister_model(model, 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); array_push(empty_indices, index, int);
} }
else else
@ -93,24 +104,143 @@ void model_cleanup(void)
void model_render_all(struct Camera* camera) void model_render_all(struct Camera* camera)
{ {
int texture = texture_find("test_comp.tga"); static mat4 mvp;
mat4 mvp; struct Material* material_list = material_get_all_materials();
for(int i = 0; i < array_len(model_list); i++) for(int i = 0; i < array_len(material_list); i++)
{
/* for each material, get all the registered models and render them */
struct Material* material = &material_list[i];
if(!material->active)
continue;
shader_bind(material->shader);
renderer_check_glerror("model:render_all:shader_bind");
for(int j = 0; j < array_len(material->registered_models); j++)
{ {
struct Model* model = &model_list[i]; /* for each registered model, set up uniforms and render */
struct Model* model = &model_list[material->registered_models[j]];
struct Entity* entity = entity_get(model->node); struct Entity* entity = entity_get(model->node);
struct Transform* transform = entity_component_get(entity, C_TRANSFORM); struct Transform* transform = entity_component_get(entity, C_TRANSFORM);
mat4_identity(&mvp); for(int k = 0; k < array_len(model->material_params); k++)
{
/* set material params for the model */
struct Material_Param* param = &model->material_params[k];
struct Uniform* uniform = &material->model_params[param->uniform_index];
shader_set_uniform(uniform->type, uniform->location, param->value);
renderer_check_glerror("model:render_all:material_param");
}
shader_bind(model->shader); for(int k = 0; k < array_len(material->pipeline_params); k++)
shader_set_uniform_int(model->shader, "sampler", (GL_TEXTURE0 + 4) - GL_TEXTURE0); {
texture_bind(texture, 4); /* TODO: change this into something better */
renderer_check_glerror("model:render_all"); /* Set pipeline uniforms */
struct Uniform* uniform = &material->pipeline_params[k];
if(strcmp(uniform->name, "mvp") == 0)
{
mat4_identity(&mvp);
mat4_mul(&mvp, &camera->view_proj_mat, &transform->trans_mat); mat4_mul(&mvp, &camera->view_proj_mat, &transform->trans_mat);
shader_set_uniform_mat4(model->shader, "mvp", &mvp); shader_set_uniform(uniform->type, uniform->location, &mvp);
shader_set_uniform_vec4(model->shader, "diffuseColor", &model->color); renderer_check_glerror("model:render_all:material_pipeline");
}
}
/* Render the geometry */
geom_render(model->geometry_index); geom_render(model->geometry_index);
texture_unbind(4); }
shader_unbind(); 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)
{
assert(model && name && value);
int success = 0;
struct Material* material = material_get(model->material);
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(strcmp(uniform->name, name) == 0)
{
switch(uniform->type)
{
case UT_INT:
*((int*)param->value) = *((int*)value);
break;
case UT_FLOAT:
*((float*)param->value) = *((float*)value);
break;
case UT_VEC2:
vec2_assign((vec2*)param->value, (vec2*)value);
break;
case UT_VEC3:
vec3_assign((vec3*)param->value, (vec3*)value);
break;
case UT_VEC4:
vec4_assign((vec4*)param->value, (vec4*)value);
break;
case UT_MAT4:
mat4_assign((mat4*)param->value, (mat4*)value);
break;
}
break; /* break for */
success = 1;
}
}
return success;
}
int model_get_material_param(struct Model* model, const char* name, void* value_out)
{
assert(model && name && value_out);
int success = 0;
struct Material* material = material_get(model->material);
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(strcmp(uniform->name, name) == 0)
{
switch(uniform->type)
{
case UT_INT:
*((int*)value_out) = *((int*)param->value);
break;
case UT_FLOAT:
*((float*)value_out) = *((float*)param->value);
break;
case UT_VEC2:
vec2_assign((vec2*)value_out, (vec2*)param->value);
break;
case UT_VEC3:
vec3_assign((vec3*)value_out, (vec3*)param->value);
break;
case UT_VEC4:
vec4_assign((vec4*)value_out, (vec4*)param->value);
break;
case UT_MAT4:
mat4_assign((mat4*)value_out, (mat4*)param->value);
break;
}
break; /* break for */
success = 1;
}
}
return success;
} }

@ -4,13 +4,14 @@
#include "linmath.h" #include "linmath.h"
struct Camera; struct Camera;
struct Material_Param;
struct Model struct Model
{ {
int node; int node;
int geometry_index; int geometry_index;
int shader; /* Temporary, replace with material */ int material;
vec4 color; struct Material_Param* material_params;
}; };
struct Model* model_get(int index); struct Model* model_get(int index);
@ -19,5 +20,7 @@ int model_create(int node, const char* geo_name);
void model_remove(int index); void model_remove(int index);
void model_cleanup(void); void model_cleanup(void);
void model_render_all(struct Camera* camera); void model_render_all(struct Camera* camera);
int model_set_material_param(struct Model* model, const char* name, void* value);
int model_get_material_param(struct Model* model, const char* name, void* value_out);
#endif #endif

@ -300,3 +300,44 @@ void shader_cleanup(void)
array_free(shader_list); array_free(shader_list);
array_free(empty_indices); array_free(empty_indices);
} }
void shader_set_uniform(const int uniform_type, const int uniform_loc, void* value)
{
assert(value);
switch(uniform_type)
{
case UT_INT:
{
glUniform1i(uniform_loc, *((int*)value));
break;
}
case UT_FLOAT:
{
glUniform1f(uniform_loc, *((float*)value));
break;
}
case UT_VEC2:
{
vec2* vector = (vec2*)value;
glUniform2fv(uniform_loc, 1, &vector->x);
break;
}
case UT_VEC3:
{
vec3* vector = (vec3*)value;
glUniform3fv(uniform_loc, 1, &vector->x);
break;
}
case UT_VEC4:
{
vec4* vector = (vec4*)value;
glUniform4fv(uniform_loc, 1, &vector->x);
break;
}
case UT_MAT4:
{
mat4* mat = (mat4*)value;
glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, &mat->mat[0]);
}
}
}

@ -3,18 +3,29 @@
#include "linmath.h" #include "linmath.h"
enum Uniform_Type
{
UT_FLOAT = 0,
UT_INT,
UT_VEC3,
UT_VEC2,
UT_VEC4,
UT_MAT4
};
int shader_create(const char* vert_shader_name, const char* frag_shader_name); int shader_create(const char* vert_shader_name, const char* frag_shader_name);
void shader_init(void); void shader_init(void);
void shader_bind(const int shader_index); void shader_bind(const int shader_index);
void shader_remove(const int shader_index); void shader_remove(const int shader_index);
void shader_unbind(void); void shader_unbind(void);
void shader_set_uniform_int(const int shaderIndex, const char* name, const int value); void shader_set_uniform_int(const int shader_index, const char* name, const int value);
void shader_set_uniform_float(const int shaderIndex, const char* name, const float value); void shader_set_uniform_float(const int shader_index, const char* name, const float value);
void shader_set_uniform_vec2(const int shaderIndex, const char* name, const vec2* value); void shader_set_uniform_vec2(const int shader_index, const char* name, const vec2* value);
void shader_set_uniform_vec3(const int shaderIndex, const char* name, const vec3* value); void shader_set_uniform_vec3(const int shader_index, const char* name, const vec3* value);
void shader_set_uniform_vec4(const int shaderIndex, const char* name, const vec4* value); void shader_set_uniform_vec4(const int shader_index, const char* name, const vec4* value);
void shader_set_uniform_mat4(const int shaderIndex, const char* name, const mat4* value); void shader_set_uniform_mat4(const int shader_index, const char* name, const mat4* value);
void shader_set_uniform(const int uniform_type, const int uniform_loc, void* value);
void shader_cleanup(void); void shader_cleanup(void);
int shader_uniform_location_get(const int shader_index, const char* name); int shader_get_uniform_location(const int shader_index, const char* name);
#endif #endif

Loading…
Cancel
Save