engine

game engine on C
git clone git://git.evenfri.pw/engine.git
Log | Files | Refs | README

scene.c (3108B)


      1 #include <string.h>
      2 #include "engine.h"
      3 
      4 void scene_init(scene_t *w) {
      5   array_init(&w->objects, sizeof(game_obj_t*));
      6 }
      7 
      8 void scene_end(scene_t *w) {
      9   for (size_t i = 0; i < w->objects.count; i++) {
     10     game_obj_t *obj = *(game_obj_t**)array_pop(&w->objects, i);
     11     for (size_t j = 0; j < obj->components.count; j++) {
     12       component_t *c = array_pop(&obj->components, j);
     13       free(c->data);
     14     }
     15     array_free(&obj->components);
     16     free(obj);
     17   }
     18   array_free(&w->objects);
     19 }
     20 
     21 game_obj_t *scene_add_object(scene_t *w) {
     22   game_obj_t *obj = calloc(1, sizeof(game_obj_t));
     23   if (!obj) {
     24     fprintf(stderr, "err: failed to allocate game_obj_t\n");
     25     exit(EXIT_FAILURE);
     26   }
     27   array_init(&obj->components, sizeof(component_t));
     28   obj->active = 1;
     29   *(game_obj_t**)array_push(&w->objects) = obj;
     30   return obj;
     31 }
     32 
     33 /* generic component api */
     34 void *game_obj_add_component(game_obj_t *obj, uint32_t type_id, size_t size) {
     35   /* replace existing component if present */
     36   for (size_t i = 0; i < obj->components.count; i++) {
     37     component_t *c = array_pop(&obj->components, i);
     38     if (c->type_id == type_id) {
     39       free(c->data);
     40       c->size = size;
     41       c->data = calloc(1, size);
     42       return c->data;
     43     }
     44   }
     45   component_t *c = array_push(&obj->components);
     46   c->type_id = type_id;
     47   c->size = size;
     48   c->data = calloc(1, size);
     49   return c->data;
     50 }
     51 
     52 void *game_obj_get_component(game_obj_t *obj, uint32_t type_id) {
     53   for (size_t i = 0; i < obj->components.count; i++) {
     54     component_t *c = array_pop(&obj->components, i);
     55     if (c->type_id == type_id) return c->data;
     56   }
     57   return NULL;
     58 }
     59 
     60 /* typed helpers */
     61 transform_t *game_obj_add_transform(game_obj_t *obj) {
     62   transform_t *t = game_obj_add_component(obj, COMP_TRANSFORM, sizeof(transform_t));
     63   t->scl = vec3_make(1.0f, 1.0f, 1.0f);
     64   return t;
     65 }
     66 
     67 camera_comp_t *game_obj_add_camera(game_obj_t *obj) {
     68   camera_comp_t *c = game_obj_add_component(obj, COMP_CAMERA, 
     69       sizeof(camera_comp_t));
     70   c->fov = 60.0f;
     71   c->near_plane = 0.1f;
     72   c->far_plane = 100.0f;
     73   return c;
     74 }
     75 
     76 mesh_comp_t *game_obj_add_mesh(game_obj_t *obj, Mesh_t *mesh, unsigned int texture) {
     77   mesh_comp_t *mc = game_obj_add_component(obj, COMP_MESH, sizeof(mesh_comp_t));
     78   mc->mesh = mesh;
     79   mc->texture = texture;
     80   return mc;
     81 }
     82 
     83 /* render system */
     84 void scene_render(scene_t *w, unsigned int shader_program) {
     85   int u_model = glGetUniformLocation(shader_program, "model");
     86   for (size_t i = 0; i < w->objects.count; i++) {
     87     game_obj_t *obj = *(game_obj_t**)array_pop(&w->objects, i);
     88     if (!obj->active) continue;
     89 
     90     transform_t *t  = game_obj_get_component(obj, COMP_TRANSFORM);
     91     mesh_comp_t *mc = game_obj_get_component(obj, COMP_MESH);
     92     if (!t || !mc) continue;
     93 
     94     mat4 model = mat4_translate(t->pos.x, t->pos.y, t->pos.z);
     95     glUniformMatrix4fv(u_model, 1, GL_FALSE, model.m);
     96 
     97     glActiveTexture(GL_TEXTURE0);
     98     glBindTexture(GL_TEXTURE_2D, mc->texture);
     99     mesh_draw(mc->mesh);
    100   }
    101 }
    102 
    103 void game_obj_activate_camera(game_obj_t *obj) {
    104   camera_comp_t *c = game_obj_get_component(obj, COMP_CAMERA);
    105   if (c) camera_set_game(obj, c);
    106 }