parent
bc46f57091
commit
1b649feadc
@ -0,0 +1,98 @@ |
|||||||
|
#include "camera.h" |
||||||
|
#include "entity.h" |
||||||
|
#include "transform.h" |
||||||
|
#include "array.h" |
||||||
|
|
||||||
|
static struct Camera* camera_list; |
||||||
|
static int* empty_indices; |
||||||
|
|
||||||
|
struct Camera* camera_get(int index) |
||||||
|
{ |
||||||
|
struct Camera* camera = NULL; |
||||||
|
if(index > -1 && index < array_len(camera_list)) |
||||||
|
camera = &camera_list[index]; |
||||||
|
|
||||||
|
return camera; |
||||||
|
} |
||||||
|
|
||||||
|
void camera_init(void) |
||||||
|
{ |
||||||
|
camera_list = array_new(struct Camera); |
||||||
|
empty_indices = array_new(int); |
||||||
|
} |
||||||
|
|
||||||
|
void camera_remove(int index) |
||||||
|
{ |
||||||
|
if(index > -1 && index < array_len(camera_list)) |
||||||
|
{ |
||||||
|
camera_list->node = -1; |
||||||
|
array_push(empty_indices, index, int); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void camera_cleanup(void) |
||||||
|
{ |
||||||
|
array_free(camera_list); |
||||||
|
array_free(empty_indices); |
||||||
|
} |
||||||
|
|
||||||
|
int camera_create(int node, int width, int height) |
||||||
|
{ |
||||||
|
int index = -1; |
||||||
|
struct Camera* new_camera = NULL; |
||||||
|
if(array_len(empty_indices) > 0) |
||||||
|
{ |
||||||
|
index = *array_get_last(empty_indices, int); |
||||||
|
new_camera = &camera_list[index]; |
||||||
|
array_pop(empty_indices); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
new_camera = array_grow(camera_list, struct Camera); |
||||||
|
index = array_len(camera_list) - 1; |
||||||
|
} |
||||||
|
|
||||||
|
new_camera->node = node; |
||||||
|
new_camera->farz = 1000.f; |
||||||
|
new_camera->nearz = 0.1f; |
||||||
|
new_camera->fov = TO_RADIANS(60.f); |
||||||
|
new_camera->aspect_ratio = ((float)width / (float)height) <= 0.f ? (4.f / 3.f) : ((float)width / (float)height); |
||||||
|
new_camera->ortho = 0; |
||||||
|
camera_update_view(new_camera); |
||||||
|
camera_update_proj(new_camera); |
||||||
|
|
||||||
|
return index; |
||||||
|
} |
||||||
|
|
||||||
|
void camera_update_view_proj(struct Camera* camera) |
||||||
|
{ |
||||||
|
mat4_mul(camera->view_proj_mat, camera->proj_mat, camera->view_mat); |
||||||
|
} |
||||||
|
|
||||||
|
void camera_update_view(struct Camera* camera) |
||||||
|
{ |
||||||
|
struct Entity* entity = entity_get(camera->node); |
||||||
|
struct Transform* transform = entity_component_get(entity, C_TRANSFORM); |
||||||
|
vec3 lookat = {0.f}, up = {0.f}; |
||||||
|
transform_get_lookat(transform, lookat); |
||||||
|
transform_get_up(transform, up); |
||||||
|
mat4_look_at(camera->view_mat, transform->position, lookat, up); |
||||||
|
camera_update_view_proj(camera); |
||||||
|
} |
||||||
|
|
||||||
|
void camera_update_proj(struct Camera* camera) |
||||||
|
{ |
||||||
|
if(!camera->ortho) |
||||||
|
{ |
||||||
|
mat4_perspective(camera->proj_mat, |
||||||
|
camera->fov, |
||||||
|
camera->aspect_ratio, |
||||||
|
camera->nearz, |
||||||
|
camera->farz); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
mat4_ortho(camera->proj_mat, -1, 1, -1, 1, camera->nearz, camera->farz); |
||||||
|
} |
||||||
|
camera_update_view_proj(camera); |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
#ifndef camera_H |
||||||
|
#define camera_H |
||||||
|
|
||||||
|
#include "linmath.h" |
||||||
|
|
||||||
|
struct Camera |
||||||
|
{ |
||||||
|
int node; |
||||||
|
mat4 proj_mat; |
||||||
|
mat4 view_mat; |
||||||
|
mat4 view_proj_mat; |
||||||
|
float fov; |
||||||
|
float aspect_ratio; |
||||||
|
float nearz; |
||||||
|
float farz; |
||||||
|
int ortho; |
||||||
|
}; |
||||||
|
|
||||||
|
struct Camera* camera_get(int index); |
||||||
|
void camera_init(void); |
||||||
|
void camera_cleanup(void); |
||||||
|
void camera_remove(int index); |
||||||
|
int camera_create(int node, int width, int height); |
||||||
|
void camera_update_view_proj(struct Camera* camera); |
||||||
|
void camera_update_view(struct Camera* camera); |
||||||
|
void camera_update_proj(struct Camera* camera); |
||||||
|
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,107 @@ |
|||||||
|
#include "model.h" |
||||||
|
#include "array.h" |
||||||
|
#include "log.h" |
||||||
|
#include "geometry.h" |
||||||
|
#include "camera.h" |
||||||
|
#include "entity.h" |
||||||
|
#include "shader.h" |
||||||
|
#include "transform.h" |
||||||
|
|
||||||
|
#include <assert.h> |
||||||
|
|
||||||
|
static struct Model* model_list; |
||||||
|
static int* empty_indices; |
||||||
|
|
||||||
|
struct Model* model_get(int index) |
||||||
|
{ |
||||||
|
struct Model* model = NULL; |
||||||
|
if(index > -1 && index < array_len(model_list)) |
||||||
|
model = &model_list[index]; |
||||||
|
else |
||||||
|
log_error("model:get", "Invalid index"); |
||||||
|
return model; |
||||||
|
} |
||||||
|
|
||||||
|
void model_init(void) |
||||||
|
{ |
||||||
|
model_list = array_new(struct Model); |
||||||
|
empty_indices = array_new(int); |
||||||
|
} |
||||||
|
|
||||||
|
int model_create(int node, const char* geo_name) |
||||||
|
{ |
||||||
|
assert(geo_name); |
||||||
|
int geo_index = geom_create(geo_name); |
||||||
|
int index = -1; |
||||||
|
struct Model* new_model = NULL; |
||||||
|
if(geo_index > -1) |
||||||
|
{ |
||||||
|
if(array_len(empty_indices) > 0) |
||||||
|
{ |
||||||
|
index = *array_get_last(empty_indices, int); |
||||||
|
array_pop(empty_indices); |
||||||
|
new_model = &model_list[index]; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
new_model = array_grow(model_list, struct Model); |
||||||
|
index = array_len(model_list) - 1; |
||||||
|
} |
||||||
|
new_model->node = node; |
||||||
|
new_model->geometry_index = geo_index; |
||||||
|
new_model->shader = 0; /* Temporary, for test run only till materials are added */ |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
log_error("model:create", "Geometry '%s' not found.", geo_name); |
||||||
|
} |
||||||
|
return index; |
||||||
|
} |
||||||
|
|
||||||
|
void model_remove(int index) |
||||||
|
{ |
||||||
|
if(index > -1 && index < array_len(model_list)) |
||||||
|
{ |
||||||
|
struct Model* model = &model_list[index]; |
||||||
|
model->node = -1; |
||||||
|
geom_remove(model->geometry_index); |
||||||
|
model->geometry_index = -1; |
||||||
|
model->shader = -1; |
||||||
|
array_push(empty_indices, index, int); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
log_error("model:remove", "Invalid index"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void model_cleanup(void) |
||||||
|
{ |
||||||
|
for(int i = 0; i < array_len(model_list); i++) |
||||||
|
{ |
||||||
|
if(model_list[i].node != -1) |
||||||
|
model_remove(i); |
||||||
|
} |
||||||
|
array_free(model_list); |
||||||
|
array_free(empty_indices); |
||||||
|
} |
||||||
|
|
||||||
|
void model_render_all(struct Camera* camera) |
||||||
|
{ |
||||||
|
mat4 mvp; |
||||||
|
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); |
||||||
|
mat4_identity(mvp); |
||||||
|
|
||||||
|
shader_bind(model->shader); |
||||||
|
mat4_mul(mvp, camera->view_proj_mat, transform->trans_mat); |
||||||
|
shader_set_uniform_mat4(model->shader, "mvp", mvp); |
||||||
|
vec4 color = {1, 0, 0, 1}; |
||||||
|
shader_set_uniform_vec4(model->shader, "color", color); |
||||||
|
geom_render(model->geometry_index); |
||||||
|
shader_unbind(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
#ifndef model_H |
||||||
|
#define model_H |
||||||
|
|
||||||
|
struct Camera; |
||||||
|
|
||||||
|
struct Model |
||||||
|
{ |
||||||
|
int node; |
||||||
|
int geometry_index; |
||||||
|
int shader; /* Temporary, replace with material */ |
||||||
|
}; |
||||||
|
|
||||||
|
struct Model* model_get(int index); |
||||||
|
void model_init(void); |
||||||
|
int model_create(int node, const char* geo_name); |
||||||
|
void model_remove(int index); |
||||||
|
void model_cleanup(void); |
||||||
|
void model_render_all(struct Camera* camera); |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue