Added camera and model. Made several modifications and fixes throughout the code

dev
Shariq Shah 10 years ago
parent bc46f57091
commit 1b649feadc
  1. 8
      orgfile.org
  2. 98
      src/camera.c
  3. 29
      src/camera.h
  4. 14
      src/components.h
  5. 125
      src/entity.c
  6. 5
      src/entity.h
  7. 2
      src/file_io.c
  8. 49
      src/game.c
  9. 42
      src/geometry.c
  10. 3
      src/geometry.h
  11. 172
      src/input.c
  12. 185
      src/linmath.h
  13. 107
      src/model.c
  14. 20
      src/model.h
  15. 5
      src/renderer.c
  16. 26
      src/shader.c
  17. 19
      src/transform.c
  18. 1
      src/transform.h
  19. 2
      src/window_system.c

@ -34,10 +34,14 @@ while using as few libraries as possible.
- State "DONE" from "TODO" [2015-07-27 Mon 11:54]
** DONE Investigate about Exit() and at_exit() functions and whether to use them or not.
- State "DONE" from "TODO" [2015-08-02 Sun 19:09]
** TODO Fix readme markdown
** TODO Framebuffer and resolution independent rendering
** TODO Entity
** TODO Positive and negative values for input_maps and returning corresponding values when they are true
** TODO Camera
** TODO Test render
** DONE Camera
- State "DONE" from "TODO" [2015-08-19 Wed 13:30]
** DONE Test render
- State "DONE" from "TODO" [2015-08-19 Wed 13:30]
** TODO Bounding Boxes
** TODO Materials
** TODO Mesh/Model

@ -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

@ -10,4 +10,18 @@ enum Component
MAX_COMPONENTS
};
inline static const char* comp_to_str(enum Component component)
{
const char* str = 0;
switch(component)
{
case C_TRANSFORM : str = "TRANSFORM"; break;
case C_MODEL : str = "MODEL"; break;
case C_CAMERA : str = "CAMERA"; break;
case C_RIGIDBODY : str = "RIGIDBODY"; break;
case MAX_COMPONENTS : str = "MAX_COMPONENTS"; break;
}
return str;
}
#endif

@ -3,15 +3,17 @@
#include "log.h"
#include "string_utils.h"
#include "transform.h"
#include "camera.h"
#include "model.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
static struct Entity* entity_list;
static int* empty_indices;
void entity_init(void)
{
entity_list = array_new(struct Entity);
@ -33,20 +35,15 @@ void entity_remove(int index)
for(int i = 0; i < MAX_COMPONENTS; i++)
{
switch((enum Component)i)
if(i == C_TRANSFORM)
{
case C_TRANSFORM: transform_remove(entity->components[i]); break;
case C_MODEL:
break;
case C_RIGIDBODY:
break;
case C_CAMERA:
break;
default:
/* Only called for MAX_COMPONENTS, do nothing */
break;
transform_remove(entity->components[i]);
entity->components[i] = -1;
}
else
{
entity_component_remove(entity, i);
}
entity->components[i] = -1;
}
entity->node = -1;
free(entity->name);
@ -79,6 +76,8 @@ struct Entity* entity_create(const char* name, const char* tag)
new_entity->name = name ? str_new(name) : str_new("DEFAULT_NAME");
new_entity->tag = tag ? str_new(tag) : str_new("DEFAULT_TAG");
new_entity->node = index;
for(int i = 0; i < MAX_COMPONENTS; i++)
new_entity->components[i] = -1;
new_entity->components[C_TRANSFORM] = transform_create(new_entity->node);
return new_entity;
@ -111,67 +110,117 @@ struct Entity* entity_find(const char* name)
}
return entity;
}
int entity_component_remove(struct Entity* entity, enum Component component)
{
int success = 1;
assert(entity);
switch(component)
int comp_index = entity->components[component];
switch(component)
{
case C_TRANSFORM:
log_error("entity:remove", "Cannot remove Tranform component");
success = 0;
break;
case C_MODEL:
break;
case C_TRANSFORM: log_error("entity:remove_component", "Cannot remove TRANSFORM"); break;
case C_MODEL: if(comp_index != -1) model_remove(comp_index); break;
case C_CAMERA: if(comp_index != -1) camera_remove(comp_index); break;
case C_RIGIDBODY:
break;
case C_CAMERA:
break;
default:
log_error("entity:component_remove", "Invalid component type");
/* Only called for MAX_COMPONENTS, do nothing */
break;
}
entity->components[component] = -1;
if(success) entity->components[component] = -1;
return success;
}
void* entity_component_get(struct Entity* entity, enum Component component)
{
void* comp_obj = NULL;
assert(entity);
switch(component)
int comp_index = entity->components[component];
if(comp_index != -1)
{
case C_TRANSFORM: comp_obj = transform_get(entity->components[C_TRANSFORM]); break;
case C_MODEL:
break;
case C_RIGIDBODY:
break;
case C_CAMERA:
break;
default:
log_error("entity:component_get", "Invalid component type");
break;
switch(component)
{
case C_TRANSFORM: comp_obj = transform_get(comp_index); break;
case C_MODEL: comp_obj = model_get(comp_index); break;
case C_CAMERA: comp_obj = camera_get(comp_index); break;
case C_RIGIDBODY:
break;
default: log_error("entity:component_get", "Invalid component type"); break;
}
}
else
{
log_error("entity:component_get", "Entity '%s' does not have component %s",
entity->name,
comp_to_str(component));
}
return comp_obj;
}
void* entity_component_add(struct Entity* entity, enum Component component)
void* entity_component_add(struct Entity* entity, enum Component component, ...)
{
void* new_comp = NULL;
assert(entity);
va_list args;
va_start(args, component);
int new_comp_index = -1;
switch(component)
{
case C_TRANSFORM:
log_error("entity:add_component", "Entity already has Transform component");
case C_MODEL:
break;
case C_RIGIDBODY:
break;
{
const char* filename = va_arg(args, const char*);
new_comp_index = model_create(entity->node, filename);
new_comp = model_get(new_comp_index);
}
break;
case C_CAMERA:
{
int width = va_arg(args, int);
int height = va_arg(args, int);
new_comp_index = camera_create(entity->node, width, height);
new_comp = camera_get(new_comp_index);
}
break;
case C_RIGIDBODY:
break;
default:
log_error("entity:component_add", "Invalid component type");
break;
}
if(new_comp_index == -1)
{
log_error("entity:component_add", "%s component not added to %s",
comp_to_str(component),
entity->name);
}
else
{
entity->components[component] = new_comp_index;
log_message("%s component added to %s", comp_to_str(component), entity->name);
}
va_end(args);
return new_comp;
}
int entity_has_component(struct Entity* entity, enum Component component)
{
int has_comp = 0;
if(entity->components[component] != -1)
has_comp = 1;
return has_comp;
}
void entity_sync_components(struct Entity* entity)
{
if(entity_has_component(entity, C_CAMERA))
{
struct Camera* camera = entity_component_get(entity, C_CAMERA);
camera_update_view(camera);
}
}

@ -20,7 +20,8 @@ struct Entity* entity_get(int index);
struct Entity* entity_find(const char* name);
int entity_component_remove(struct Entity* entity, enum Component component);
void* entity_component_get(struct Entity* entity, enum Component component);
void* entity_component_add(struct Entity* entity, enum Component component);
void* entity_component_add(struct Entity* entity, enum Component component, ...);
int entity_has_component(struct Entity* entity, enum Component component);
void entity_sync_components(struct Entity* entity);
#endif

@ -70,6 +70,6 @@ FILE* io_file_open(const char* path, const char* mode)
char* relative_path = str_new(base_assets_path);
relative_path = str_concat(relative_path, path);
FILE* file = fopen(relative_path, mode);
if(!file) log_error("io:file", "Fialed to open file '%s'", relative_path);
if(!file) log_error("io:file", "Failed to open file '%s'", relative_path);
return file;
}

@ -15,6 +15,7 @@
#include "array.h"
#include "transform.h"
#include "camera.h"
#include "model.h"
void run(void);
void update(float dt);
@ -22,6 +23,7 @@ void render(void);
void debug(float dt);
struct Entity* entity = NULL;
struct Camera* active_camera = NULL;
void game_init(void)
{
@ -35,19 +37,26 @@ void game_init(void)
camera_init();
entity_init();
geom_init();
model_init();
int keys[2] = {'W', GLFW_KEY_UP};
int keys2[2] = {'S', GLFW_KEY_DOWN};
int keys3[1] = {'J'};
int keys4[1] = {'K'};
input_map_create("MoveUp", keys, 2);
input_map_create("MoveDown", keys2, 2);
input_map_create("Test", keys3, 1);
input_map_create("Test2", keys4, 1);
int up_keys[2] = {'W', GLFW_KEY_UP};
int down_keys[2] = {'S', GLFW_KEY_DOWN};
int left_keys[2] = {'A', GLFW_KEY_LEFT};
int right_keys[2] = {'D', GLFW_KEY_RIGHT};
input_map_create("Move_Up", up_keys, 2);
input_map_create("Move_Down", down_keys, 2);
input_map_create("Move_Left", left_keys, 2);
input_map_create("Move_Right", right_keys, 2);
int shader = shader_create("phong.vert", "phong.frag");
int shader = shader_create("unshaded.vert", "unshaded.frag");
entity = entity_create("Test", "None");
active_camera = entity_component_add(entity, C_CAMERA, 800, 600);
struct Entity* new_ent = entity_create("Model_Entity", NULL);
struct Transform* tran = entity_component_get(new_ent, C_TRANSFORM);
vec3 position = {0, 0, -5};
transform_translate(tran, position, TS_WORLD);
struct Model* model = entity_component_add(new_ent, C_MODEL, "default.pamesh");
run();
}
@ -55,10 +64,22 @@ void game_init(void)
void debug(float dt)
{
struct Transform* transform = entity_component_get(entity, C_TRANSFORM);
vec3 offset = {0, 5, 0};
float speed = 5.f;
vec3 offset = {0, 0, 0};
if(input_map_state_get("Move_Up", GLFW_PRESS)) offset[2] -= speed;
if(input_map_state_get("Move_Down", GLFW_PRESS)) offset[2] += speed;
if(input_map_state_get("Move_Left", GLFW_PRESS)) offset[0] -= speed;
if(input_map_state_get("Move_Right", GLFW_PRESS)) offset[0] += speed;
vec3_scale(offset, offset, dt);
transform_translate(transform, offset, TS_WORLD);
log_message("Position : %.3f, %.3f, %.3f", transform->position[0], transform->position[1], transform->position[2]);
if(offset[0] != 0 || offset[2] != 0)
{
transform_translate(transform, offset, TS_WORLD);
log_message("Position : %.3f, %.3f, %.3f",
transform->position[0],
transform->position[1],
transform->position[2]);
}
}
void run(void)
@ -83,8 +104,7 @@ void update(float dt)
if(input_key_state_get(GLFW_KEY_ESCAPE, GLFW_PRESS))
window_set_should_close(1);
if(input_map_state_get("MoveUp", GLFW_PRESS))
debug(dt);
debug(dt);
}
void render(void)
@ -95,6 +115,7 @@ void render(void)
void game_cleanup(void)
{
entity_cleanup();
model_cleanup();
geom_cleanup();
transform_cleanup();
camera_cleanup();

@ -25,7 +25,7 @@ struct Geometry
uint normal_vbo;
uint color_vbo;
uint index_vbo;
uint ref_count;
int ref_count;
vec3* vertices;
vec3* vertex_colors;
vec3* normals;
@ -73,7 +73,6 @@ int geom_create(const char* name)
{
/* add new geometry object or overwrite existing one */
struct Geometry* new_geo = NULL;
int index = -1;
int empty_len = array_len(empty_indices);
if(empty_len > 0)
{
@ -112,13 +111,20 @@ void geom_remove(int index)
if(index >= 0 && index < array_len(geometry_list))
{
struct Geometry* geometry = &geometry_list[index];
array_free(geometry->indices);
array_free(geometry->vertices);
array_free(geometry->uvs);
array_free(geometry->normals);
array_free(geometry->vertex_colors);
free(geometry->filename);
array_push(empty_indices, index, int);
if(geometry->ref_count >= 0)
{
geometry->ref_count--;
if(geometry->ref_count < 0)
{
array_free(geometry->indices);
array_free(geometry->vertices);
array_free(geometry->uvs);
array_free(geometry->normals);
array_free(geometry->vertex_colors);
free(geometry->filename);
array_push(empty_indices, index, int);
}
}
}
}
@ -161,15 +167,21 @@ int load_from_file(struct Geometry* geometry, const char* filename)
// Indices
geometry->indices = array_new_cap(uint, indices_count);
fread(geometry->indices, INDEX_SIZE, indices_count, file);
array_match_len_cap(geometry->indices);
// Vertices
geometry->vertices = array_new_cap(vec3, vertices_count);
fread(geometry->vertices, VEC3_SIZE, vertices_count, file);
array_match_len_cap(geometry->vertices);
// Normals
geometry->normals = array_new_cap(vec3, normals_count);
fread(geometry->normals, VEC3_SIZE, normals_count, file);
array_match_len_cap(geometry->normals);
// Uvs
geometry->uvs = array_new_cap(vec2, uvs_count);
fread(geometry->uvs, VEC2_SIZE, uvs_count, file);
array_match_len_cap(geometry->uvs);
geometry->vertex_colors = array_new(vec3);
}
fclose(file);
geometry->filename = str_new(filename);
@ -251,3 +263,15 @@ void create_vao(struct Geometry* geometry)
}
glBindVertexArray(0);
}
void geom_render(int index)
{
struct Geometry* geo = &geometry_list[index];
glBindVertexArray(geo->vao);
if(geo->draw_indexed)
glDrawElements(GL_TRIANGLES, array_len(geo->indices), GL_UNSIGNED_INT, (void*)0);
else
glDrawArrays(GL_TRIANGLES, 0, array_len(geo->vertices));
glBindVertexArray(0);
}

@ -2,9 +2,10 @@
#define geometry_H
void geom_init(void);
int geom_ceate(const char* name);
int geom_create(const char* name);
int geom_find(const char* filename);
void geom_remove(int index);
void geom_cleanup(void);
void geom_render(int index);
#endif

@ -22,6 +22,7 @@ static void input_on_key(GLFWwindow* window, int key, int scancode, int action,
static void input_on_mousebutton(GLFWwindow* window, int button, int action, int mods);
static void input_on_cursor_move(GLFWwindow* window, double xpos, double ypos);
static int map_find(const char* name);
static const char* get_key_name(int key);
static struct Input_Map* input_map_list;
@ -30,6 +31,7 @@ void input_init(GLFWwindow* window)
glfwSetMouseButtonCallback(window, input_on_mousebutton);
glfwSetKeyCallback(window, input_on_key);
glfwSetCursorPosCallback(window, input_on_cursor_move);
//glfwSetInputMode(window, GLFW_STICKY_KEYS, 1);
input_map_list = array_new(struct Input_Map);
}
@ -63,7 +65,7 @@ static void input_on_key(GLFWwindow* window, int key, int scancode, int action,
struct Input_Map* map = &input_map_list[i];
for(int j = 0; j < array_len(map->keys); j++)
{
if(map->keys[i] == key)
if(map->keys[j] == key)
{
map->state = action;
break;
@ -103,21 +105,52 @@ int input_map_state_get(const char* map_name, int state)
break;
}
}
return state == current_state ? 1 : 0;
if(state == GLFW_PRESS)
{
if(current_state == GLFW_PRESS || current_state == GLFW_REPEAT)
return 1;
else
return 0;
}
else
{
return state == current_state ? 1 : 0;
}
}
int input_key_state_get(int key, int state_type)
{
GLFWwindow* window = window_get_active();
int current_state = glfwGetKey(window, key);
return current_state == state_type ? 1 : 0;
if(state_type == GLFW_PRESS)
{
if(current_state == GLFW_PRESS || current_state == GLFW_REPEAT)
return 1;
else
return 0;
}
else
{
return state_type == current_state ? 1 : 0;
}
}
int input_mousebutton_state_get(int button, int state_type)
{
GLFWwindow* window = window_get_active();
int current_state = glfwGetMouseButton(window, button);
return current_state == state_type ? 1 : 0;
if(state_type == GLFW_PRESS)
{
if(current_state == GLFW_PRESS || current_state == GLFW_REPEAT)
return 1;
else
return 0;
}
else
{
return state_type == current_state ? 1 : 0;
}
}
void input_map_create(const char* name, int* keys, size_t num_keys)
@ -206,3 +239,134 @@ static int map_find(const char* name)
}
return index;
}
static const char* get_key_name(int key)
{
switch (key)
{
// Printable keys
case GLFW_KEY_A: return "A";
case GLFW_KEY_B: return "B";
case GLFW_KEY_C: return "C";
case GLFW_KEY_D: return "D";
case GLFW_KEY_E: return "E";
case GLFW_KEY_F: return "F";
case GLFW_KEY_G: return "G";
case GLFW_KEY_H: return "H";
case GLFW_KEY_I: return "I";
case GLFW_KEY_J: return "J";
case GLFW_KEY_K: return "K";
case GLFW_KEY_L: return "L";
case GLFW_KEY_M: return "M";
case GLFW_KEY_N: return "N";
case GLFW_KEY_O: return "O";
case GLFW_KEY_P: return "P";
case GLFW_KEY_Q: return "Q";
case GLFW_KEY_R: return "R";
case GLFW_KEY_S: return "S";
case GLFW_KEY_T: return "T";
case GLFW_KEY_U: return "U";
case GLFW_KEY_V: return "V";
case GLFW_KEY_W: return "W";
case GLFW_KEY_X: return "X";
case GLFW_KEY_Y: return "Y";
case GLFW_KEY_Z: return "Z";
case GLFW_KEY_1: return "1";
case GLFW_KEY_2: return "2";
case GLFW_KEY_3: return "3";
case GLFW_KEY_4: return "4";
case GLFW_KEY_5: return "5";
case GLFW_KEY_6: return "6";
case GLFW_KEY_7: return "7";
case GLFW_KEY_8: return "8";
case GLFW_KEY_9: return "9";
case GLFW_KEY_0: return "0";
case GLFW_KEY_SPACE: return "SPACE";
case GLFW_KEY_MINUS: return "MINUS";
case GLFW_KEY_EQUAL: return "EQUAL";
case GLFW_KEY_LEFT_BRACKET: return "LEFT BRACKET";
case GLFW_KEY_RIGHT_BRACKET: return "RIGHT BRACKET";
case GLFW_KEY_BACKSLASH: return "BACKSLASH";
case GLFW_KEY_SEMICOLON: return "SEMICOLON";
case GLFW_KEY_APOSTROPHE: return "APOSTROPHE";
case GLFW_KEY_GRAVE_ACCENT: return "GRAVE ACCENT";
case GLFW_KEY_COMMA: return "COMMA";
case GLFW_KEY_PERIOD: return "PERIOD";
case GLFW_KEY_SLASH: return "SLASH";
case GLFW_KEY_WORLD_1: return "WORLD 1";
case GLFW_KEY_WORLD_2: return "WORLD 2";
// Function keys
case GLFW_KEY_ESCAPE: return "ESCAPE";
case GLFW_KEY_F1: return "F1";
case GLFW_KEY_F2: return "F2";
case GLFW_KEY_F3: return "F3";
case GLFW_KEY_F4: return "F4";
case GLFW_KEY_F5: return "F5";
case GLFW_KEY_F6: return "F6";
case GLFW_KEY_F7: return "F7";
case GLFW_KEY_F8: return "F8";
case GLFW_KEY_F9: return "F9";
case GLFW_KEY_F10: return "F10";
case GLFW_KEY_F11: return "F11";
case GLFW_KEY_F12: return "F12";
case GLFW_KEY_F13: return "F13";
case GLFW_KEY_F14: return "F14";
case GLFW_KEY_F15: return "F15";
case GLFW_KEY_F16: return "F16";
case GLFW_KEY_F17: return "F17";
case GLFW_KEY_F18: return "F18";
case GLFW_KEY_F19: return "F19";
case GLFW_KEY_F20: return "F20";
case GLFW_KEY_F21: return "F21";
case GLFW_KEY_F22: return "F22";
case GLFW_KEY_F23: return "F23";
case GLFW_KEY_F24: return "F24";
case GLFW_KEY_F25: return "F25";
case GLFW_KEY_UP: return "UP";
case GLFW_KEY_DOWN: return "DOWN";
case GLFW_KEY_LEFT: return "LEFT";
case GLFW_KEY_RIGHT: return "RIGHT";
case GLFW_KEY_LEFT_SHIFT: return "LEFT SHIFT";
case GLFW_KEY_RIGHT_SHIFT: return "RIGHT SHIFT";
case GLFW_KEY_LEFT_CONTROL: return "LEFT CONTROL";
case GLFW_KEY_RIGHT_CONTROL: return "RIGHT CONTROL";
case GLFW_KEY_LEFT_ALT: return "LEFT ALT";
case GLFW_KEY_RIGHT_ALT: return "RIGHT ALT";
case GLFW_KEY_TAB: return "TAB";
case GLFW_KEY_ENTER: return "ENTER";
case GLFW_KEY_BACKSPACE: return "BACKSPACE";
case GLFW_KEY_INSERT: return "INSERT";
case GLFW_KEY_DELETE: return "DELETE";
case GLFW_KEY_PAGE_UP: return "PAGE UP";
case GLFW_KEY_PAGE_DOWN: return "PAGE DOWN";
case GLFW_KEY_HOME: return "HOME";
case GLFW_KEY_END: return "END";
case GLFW_KEY_KP_0: return "KEYPAD 0";
case GLFW_KEY_KP_1: return "KEYPAD 1";
case GLFW_KEY_KP_2: return "KEYPAD 2";
case GLFW_KEY_KP_3: return "KEYPAD 3";
case GLFW_KEY_KP_4: return "KEYPAD 4";
case GLFW_KEY_KP_5: return "KEYPAD 5";
case GLFW_KEY_KP_6: return "KEYPAD 6";
case GLFW_KEY_KP_7: return "KEYPAD 7";
case GLFW_KEY_KP_8: return "KEYPAD 8";
case GLFW_KEY_KP_9: return "KEYPAD 9";
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY";
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
case GLFW_KEY_KP_EQUAL: return "KEYPAD EQUAL";
case GLFW_KEY_KP_ENTER: return "KEYPAD ENTER";
case GLFW_KEY_PRINT_SCREEN: return "PRINT SCREEN";
case GLFW_KEY_NUM_LOCK: return "NUM LOCK";
case GLFW_KEY_CAPS_LOCK: return "CAPS LOCK";
case GLFW_KEY_SCROLL_LOCK: return "SCROLL LOCK";
case GLFW_KEY_PAUSE: return "PAUSE";
case GLFW_KEY_LEFT_SUPER: return "LEFT SUPER";
case GLFW_KEY_RIGHT_SUPER: return "RIGHT SUPER";
case GLFW_KEY_MENU: return "MENU";
default: return "UNKNOWN";
}
}

@ -1,10 +1,13 @@
#ifndef linmath_H
#define linmath_H
#ifndef LINMATH_H
#define LINMATH_H
/* Credit : https://github.com/datenwolf/linmath.h */
#include <math.h>
#define M_PI 3.14159265358979323846
#define TO_RADIANS(degrees) ((degrees * M_PI) / 180.0)
#define LINMATH_H_DEFINE_VEC(n) \
typedef float vec##n[n]; \
static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
@ -56,7 +59,7 @@ static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
{
float p = 2.f*vec3_mul_inner(v, n);
float p = 2.f*vec3_mul_inner(v, n);
int i;
for(i=0;i<3;++i)
r[i] = v[i] - p*n[i];
@ -72,14 +75,13 @@ static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
static inline void vec4_reflect(vec4 r, vec4 v, vec4 n)
{
float p = 2.f*vec4_mul_inner(v, n);
float p = 2.f*vec4_mul_inner(v, n);
int i;
for(i=0;i<4;++i)
r[i] = v[i] - p*n[i];
}
typedef vec4 mat4[4];
static inline void mat4_identity(mat4 M)
{
int i, j;
@ -87,7 +89,6 @@ static inline void mat4_identity(mat4 M)
for(j=0; j<4; ++j)
M[i][j] = i==j ? 1.f : 0.f;
}
static inline void mat4_dup(mat4 M, mat4 N)
{
int i, j;
@ -95,21 +96,18 @@ static inline void mat4_dup(mat4 M, mat4 N)
for(j=0; j<4; ++j)
M[i][j] = N[i][j];
}
static inline void mat4_row(vec4 r, mat4 M, int i)
{
int k;
for(k=0; k<4; ++k)
r[k] = M[k][i];
}
static inline void mat4_col(vec4 r, mat4 M, int i)
{
int k;
for(k=0; k<4; ++k)
r[k] = M[i][k];
}
static inline void mat4_transpose(mat4 M, mat4 N)
{
int i, j;
@ -117,28 +115,24 @@ static inline void mat4_transpose(mat4 M, mat4 N)
for(i=0; i<4; ++i)
M[i][j] = N[j][i];
}
static inline void mat4_add(mat4 M, mat4 a, mat4 b)
{
int i;
for(i=0; i<4; ++i)
vec4_add(M[i], a[i], b[i]);
}
static inline void mat4_sub(mat4 M, mat4 a, mat4 b)
{
int i;
for(i=0; i<4; ++i)
vec4_sub(M[i], a[i], b[i]);
}
static inline void mat4_scale(mat4 M, mat4 a, float k)
{
int i;
for(i=0; i<4; ++i)
vec4_scale(M[i], a[i], k);
}
static inline void mat4_scale_aniso(mat4 M, mat4 a, float x, float y, float z)
{
int i;
@ -149,19 +143,17 @@ static inline void mat4_scale_aniso(mat4 M, mat4 a, float x, float y, float z)
M[3][i] = a[3][i];
}
}
static inline void mat4_mul(mat4 M, mat4 a, mat4 b)
{
mat4 temp;
int k, r, c;
for(c=0; c<4; ++c) for(r=0; r<4; ++r) {
temp[c][r] = 0.f;
for(k=0; k<4; ++k)
temp[c][r] += a[k][r] * b[c][k];
}
temp[c][r] = 0.f;
for(k=0; k<4; ++k)
temp[c][r] += a[k][r] * b[c][k];
}
mat4_dup(M, temp);
}
static inline void mat4_mul_vec4(vec4 r, mat4 M, vec4 v)
{
int i, j;
@ -171,7 +163,6 @@ static inline void mat4_mul_vec4(vec4 r, mat4 M, vec4 v)
r[j] += M[i][j] * v[i];
}
}
static inline void mat4_translate(mat4 T, float x, float y, float z)
{
mat4_identity(T);
@ -179,7 +170,6 @@ static inline void mat4_translate(mat4 T, float x, float y, float z)
T[3][1] = y;
T[3][2] = z;
}
static inline void mat4_translate_in_place(mat4 M, float x, float y, float z)
{
vec4 t = {x, y, z, 0};
@ -190,82 +180,82 @@ static inline void mat4_translate_in_place(mat4 M, float x, float y, float z)
M[3][i] += vec4_mul_inner(r, t);
}
}
static inline void mat4_from_vec3_mul_outer(mat4 M, vec3 a, vec3 b)
{
int i, j;
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
}
static inline void mat4_rotate(mat4 R, mat4 M, float x, float y, float z, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
vec3 u = {x, y, z};
if(vec3_len(u) > 1e-4) {
vec3_norm(u, u);
mat4 T;
mat4_from_vec3_mul_outer(T, u, u);
mat4 S = {
{ 0, u[2], -u[1], 0},
{-u[2], 0, u[0], 0},
{ u[1], -u[0], 0, 0},
{ 0, 0, 0, 0}
{ 0, u[2], -u[1], 0},
{-u[2], 0, u[0], 0},
{ u[1], -u[0], 0, 0},
{ 0, 0, 0, 0}
};
mat4_scale(S, S, s);
mat4 C;
mat4_identity(C);
mat4_sub(C, C, T);
mat4_scale(C, C, c);
mat4_add(T, T, C);
mat4_add(T, T, S);
T[3][3] = 1.;
mat4_mul(R, M, T);
} else {
mat4_dup(R, M);
}
}
static inline void mat4_rotate_X(mat4 Q, mat4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4 R = {
{1.f, 0.f, 0.f, 0.f},
{0.f, c, s, 0.f},
{0.f, -s, c, 0.f},
{0.f, c, s, 0.f},
{0.f, -s, c, 0.f},
{0.f, 0.f, 0.f, 1.f}
};
mat4_mul(Q, M, R);
}
static inline void mat4_rotate_Y(mat4 Q, mat4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4 R = {
{ c, 0.f, s, 0.f},
{ c, 0.f, s, 0.f},
{ 0.f, 1.f, 0.f, 0.f},
{ -s, 0.f, c, 0.f},
{ -s, 0.f, c, 0.f},
{ 0.f, 0.f, 0.f, 1.f}
};
mat4_mul(Q, M, R);
}
static inline void mat4_rotate_Z(mat4 Q, mat4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4 R = {
{ c, s, 0.f, 0.f},
{ -s, c, 0.f, 0.f},
{ c, s, 0.f, 0.f},
{ -s, c, 0.f, 0.f},
{ 0.f, 0.f, 1.f, 0.f},
{ 0.f, 0.f, 0.f, 1.f}
};
mat4_mul(Q, M, R);
}
static inline void mat4_invert(mat4 T, mat4 M)
{
float s[6];
@ -276,46 +266,55 @@ static inline void mat4_invert(mat4 T, mat4 M)
s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2];
s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3];
s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3];
c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1];
c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2];
c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3];
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
/* Assumes it is invertible */
/* Assumes it is invertible */
float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
}
static inline void mat4_orthonormalize(mat4 R, mat4 M)
{
mat4_dup(R, M);
float s = 1.;
vec3 h;
vec3_norm(R[2], R[2]);
s = vec3_mul_inner(R[1], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[1], R[1], h);
vec3_norm(R[2], R[2]);
s = vec3_mul_inner(R[1], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[1], R[1], h);
vec3_norm(R[1], R[1]);
s = vec3_mul_inner(R[0], R[1]);
vec3_scale(h, R[1], s);
vec3_sub(R[0], R[0], h);
@ -326,109 +325,120 @@ static inline void mat4_frustum(mat4 M, float l, float r, float b, float t, floa
{
M[0][0] = 2.f*n/(r-l);
M[0][1] = M[0][2] = M[0][3] = 0.f;
M[1][1] = 2.*n/(t-b);
M[1][0] = M[1][2] = M[1][3] = 0.f;
M[2][0] = (r+l)/(r-l);
M[2][1] = (t+b)/(t-b);
M[2][2] = -(f+n)/(f-n);
M[2][3] = -1.f;
M[3][2] = -2.f*(f*n)/(f-n);
M[3][0] = M[3][1] = M[3][3] = 0.f;
}
static inline void mat4_ortho(mat4 M, float l, float r, float b, float t, float n, float f)
{
M[0][0] = 2.f/(r-l);
M[0][1] = M[0][2] = M[0][3] = 0.f;
M[1][1] = 2.f/(t-b);
M[1][0] = M[1][2] = M[1][3] = 0.f;
M[2][2] = -2.f/(f-n);
M[2][0] = M[2][1] = M[2][3] = 0.f;
M[3][0] = -(r+l)/(r-l);
M[3][1] = -(t+b)/(t-b);
M[3][2] = -(f+n)/(f-n);
M[3][3] = 1.f;
}
static inline void mat4_perspective(mat4 m, float y_fov, float aspect, float n, float f)
{
/* NOTE: Degrees are an unhandy unit to work with.
* linmath.h uses radians for everything! */
/* NOTE: Degrees are an unhandy unit to work with.
* linmath.h uses radians for everything! */
float const a = 1.f / tan(y_fov / 2.f);
m[0][0] = a / aspect;
m[0][1] = 0.f;
m[0][2] = 0.f;
m[0][3] = 0.f;
m[1][0] = 0.f;
m[1][1] = a;
m[1][2] = 0.f;
m[1][3] = 0.f;
m[2][0] = 0.f;
m[2][1] = 0.f;
m[2][2] = -((f + n) / (f - n));
m[2][3] = -1.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = -((2.f * f * n) / (f - n));
m[3][3] = 0.f;
}
static inline void mat4_look_at(mat4 m, vec3 eye, vec3 center, vec3 up)
{
/* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */
/* of the algorithm. We implement it in a straightforward way: */
/* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */
/* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */
/* of the algorithm. We implement it in a straightforward way: */
/* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */
vec3 f;
vec3_sub(f, center, eye);
vec3_norm(f, f);
vec3 s;
vec3_mul_cross(s, f, up);
vec3_norm(s, s);
vec3 t;
vec3_mul_cross(t, s, f);
m[0][0] = s[0];
m[0][1] = t[0];
m[0][0] = s[0];
m[0][1] = t[0];
m[0][2] = -f[0];
m[0][3] = 0.f;
m[1][0] = s[1];
m[1][1] = t[1];
m[0][3] = 0.f;
m[1][0] = s[1];
m[1][1] = t[1];
m[1][2] = -f[1];
m[1][3] = 0.f;
m[2][0] = s[2];
m[2][1] = t[2];
m[1][3] = 0.f;
m[2][0] = s[2];
m[2][1] = t[2];
m[2][2] = -f[2];
m[2][3] = 0.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = 0.f;
m[3][3] = 1.f;
m[2][3] = 0.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = 0.f;
m[3][3] = 1.f;
mat4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
}
typedef float quat[4];
static inline void quat_identity(quat q)
{
q[0] = q[1] = q[2] = 0.f;
q[3] = 1.f;
}
static inline void quat_add(quat r, quat a, quat b)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] + b[i];
}
static inline void quat_sub(quat r, quat a, quat b)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] - b[i];
}
static inline void quat_mul(quat r, quat p, quat q)
{
vec3 w;
@ -439,14 +449,12 @@ static inline void quat_mul(quat r, quat p, quat q)
vec3_add(r, r, w);
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
}
static inline void quat_scale(quat r, quat v, float s)
{
int i;
for(i=0; i<4; ++i)
r[i] = v[i] * s;
}
static inline float quat_inner_product(quat a, quat b)
{
float p = 0.f;
@ -455,7 +463,6 @@ static inline float quat_inner_product(quat a, quat b)
p += b[i]*a[i];
return p;
}
static inline void quat_conj(quat r, quat q)
{
int i;
@ -463,7 +470,6 @@ static inline void quat_conj(quat r, quat q)
r[i] = -q[i];
r[3] = q[3];
}
static inline void quat_rotate(quat r, float angle, vec3 axis) {
vec3 v;
vec3_scale(v, axis, sinf(angle / 2));
@ -472,18 +478,26 @@ static inline void quat_rotate(quat r, float angle, vec3 axis) {
r[i] = v[i];
r[3] = cosf(angle / 2);
}
#define quat_norm vec4_norm
static inline void quat_mul_vec3(vec3 r, quat q, vec3 v)
{
quat v_ = {v[0], v[1], v[2], 0.f};
quat_conj(r, q);
quat_norm(r, r);
quat_mul(r, v_, r);
quat_mul(r, q, r);
}
/*
* Method by Fabian 'ryg' Giessen (of Farbrausch)
t = 2 * cross(q.xyz, v)
v' = v + q.w * t + cross(q.xyz, t)
*/
vec3 t = {q[0], q[1], q[2]};
vec3 u = {q[0], q[1], q[2]};
vec3_mul_cross(t, t, v);
vec3_scale(t, t, 2);
vec3_mul_cross(u, u, t);
vec3_scale(t, t, q[3]);
vec3_add(r, v, t);
vec3_add(r, r, u);
}
static inline void mat4_from_quat(mat4 M, quat q)
{
float a = q[3];
@ -494,39 +508,45 @@ static inline void mat4_from_quat(mat4 M, quat q)
float b2 = b*b;
float c2 = c*c;
float d2 = d*d;
M[0][0] = a2 + b2 - c2 - d2;
M[0][1] = 2.f*(b*c + a*d);
M[0][2] = 2.f*(b*d - a*c);
M[0][3] = 0.f;
M[1][0] = 2*(b*c - a*d);
M[1][1] = a2 - b2 + c2 - d2;
M[1][2] = 2.f*(c*d + a*b);
M[1][3] = 0.f;
M[2][0] = 2.f*(b*d + a*c);
M[2][1] = 2.f*(c*d - a*b);
M[2][2] = a2 - b2 - c2 + d2;
M[2][3] = 0.f;
M[3][0] = M[3][1] = M[3][2] = 0.f;
M[3][3] = 1.f;
}
static inline void mat4o_mul_quat(mat4 R, mat4 M, quat q)
{
/* XXX: The way this is written only works for othogonal matrices. */
/* XXX: The way this is written only works for othogonal matrices. */
/* TODO: Take care of non-orthogonal case. */
quat_mul_vec3(R[0], q, M[0]);
quat_mul_vec3(R[1], q, M[1]);
quat_mul_vec3(R[2], q, M[2]);
R[3][0] = R[3][1] = R[3][2] = 0.f;
R[3][3] = 1.f;
}
static inline void quat_from_mat4(quat q, mat4 M)
{
float r=0.f;
int i;
int perm[] = { 0, 1, 2, 0, 1 };
int *p = perm;
for(i = 0; i<3; i++) {
float m = M[i][i];
if( m < r )
@ -534,12 +554,15 @@ static inline void quat_from_mat4(quat q, mat4 M)
m = r;
p = &perm[i];
}
r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
if(r < 1e-6) {
q[0] = 1.f;
q[1] = q[2] = q[3] = 0.f;
return;
}
q[0] = r/2.f;
q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r);
q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r);

@ -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

@ -2,6 +2,8 @@
#include "GLFW/glfw3.h"
#include "log.h"
#include "camera.h"
#include "model.h"
void on_framebuffer_size_change(GLFWwindow* window, int width, int height);
@ -14,6 +16,9 @@ void renderer_init(GLFWwindow* window)
void renderer_draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Hard coded version */
struct Camera* camera = camera_get(0);
model_render_all(camera);
}
void renderer_cleanup(void)

@ -235,7 +235,7 @@ void shader_unbind(void)
glUseProgram(0);
}
int get_uniform_location(const int shader_index, const char* name)
int shader_get_uniform_location(const int shader_index, const char* name)
{
GLint handle = glGetUniformLocation(shader_list[shader_index].program, name);
if(handle == -1)
@ -244,44 +244,44 @@ int get_uniform_location(const int shader_index, const char* name)
return handle;
}
void set_uniform_int(const int shader_index, const char* name, const int value)
void shader_set_uniform_int(const int shader_index, const char* name, const int value)
{
GLint location = get_uniform_location(shader_index, name);
GLint location = shader_get_uniform_location(shader_index, name);
if(location >= 0)
glUniform1i(location, value);
}
void set_uniform_float(const int shader_index, const char* name, const float value)
void shader_set_uniform_float(const int shader_index, const char* name, const float value)
{
GLint location = get_uniform_location(shader_index, name);
GLint location = shader_get_uniform_location(shader_index, name);
if(location >= 0)
glUniform1f(location, value);
}
void set_uniform_vec2(const int shader_index, const char* name, const vec2 value)
void shader_set_uniform_vec2(const int shader_index, const char* name, const vec2 value)
{
GLint location = get_uniform_location(shader_index, name);
GLint location = shader_get_uniform_location(shader_index, name);
if(location >= 0)
glUniform2fv(location, 1, value);
}
void set_uniform_vec3(const int shader_index, const char* name, const vec3 value)
void shader_set_uniform_vec3(const int shader_index, const char* name, const vec3 value)
{
GLint location = get_uniform_location(shader_index, name);
GLint location = shader_get_uniform_location(shader_index, name);
if(location >= 0)
glUniform3fv(location, 1, value);
}
void set_uniform_vec4(const int shader_index, const char* name, const vec4 value)
void shader_set_uniform_vec4(const int shader_index, const char* name, const vec4 value)
{
GLint location = get_uniform_location(shader_index, name);
GLint location = shader_get_uniform_location(shader_index, name);
if(location >= 0)
glUniform4fv(location, 1, value);
}
void setUniformMat4(const int shader_index, const char* name, const mat4 value)
void shader_set_uniform_mat4(const int shader_index, const char* name, const mat4 value)
{
GLint location = get_uniform_location(shader_index, name);
GLint location = shader_get_uniform_location(shader_index, name);
if(location >= 0)
glUniformMatrix4fv(location, 1, GL_FALSE, *value);
}

@ -1,9 +1,10 @@
#include "transform.h"
#include "array.h"
#include "entity.h"
#include <assert.h>
struct Transform* transform_list;
int* empty_indices;
static struct Transform* transform_list;
static int* empty_indices;
void transform_init(void)
{
@ -75,10 +76,16 @@ void transform_scale(struct Transform* transform, vec3 scale)
void transform_get_forward(struct Transform* transform, vec3 res)
{
res[0] = 0; res[1] = 0; res[2] = 1;
res[0] = 0; res[1] = 0; res[2] = -1;
quat_mul_vec3(res, transform->rotation, res);
}
void transform_get_lookat(struct Transform* transform, vec3 res)
{
transform_get_forward(transform, res);
vec3_add(res, transform->position, res);
}
void transform_get_up(struct Transform* transform, vec3 res)
{
res[0] = 0; res[1] = 1; res[2] = 0;
@ -95,12 +102,18 @@ void transform_get_right(struct Transform* transform, vec3 res)
void transform_update_transmat(struct Transform* transform)
{
mat4 scale, rot, tran;
mat4_identity(scale);
mat4_identity(rot);
mat4_identity(tran);
mat4_identity(transform->trans_mat);
mat4_scale_aniso(scale, scale, transform->scale[0], transform->scale[1], transform->scale[2]);
mat4_from_quat(rot, transform->rotation);
mat4_translate(tran, transform->position[0], transform->position[1], transform->position[2]);
mat4_mul(transform->trans_mat, transform->trans_mat, scale);
mat4_mul(transform->trans_mat, transform->trans_mat, rot);
mat4_mul(transform->trans_mat, transform->trans_mat, tran);
struct Entity* entity = entity_get(transform->node);
entity_sync_components(entity);
}
struct Transform* transform_get(int index)

@ -26,6 +26,7 @@ void transform_rotate(struct Transform* transform,
enum Transform_Space space);
void transform_scale(struct Transform* transform, vec3 scale);
void transform_get_forward(struct Transform* transform, vec3 res);
void transform_get_lookat(struct Transform* transform, vec3 res);
void transform_get_up(struct Transform* transform, vec3 res);
void transform_get_right(struct Transform* transform, vec3 res);
void transform_update_transmat(struct Transform* transform);

@ -29,7 +29,7 @@ int window_init(const char* title, int width, int height)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_FOCUSED, GL_TRUE);
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
active_window = glfwCreateWindow(width, height, title, NULL, NULL);
if(!active_window)
{

Loading…
Cancel
Save