polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

skybox.c (4221B)


      1 
      2 #include "skybox.h"
      3 #include "util.h"
      4 #include "texture.h"
      5 
      6 static GLfloat skybox_vertices[] = {
      7   1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,    // v0-v1-v2-v3 top
      8   1.0, 1.0,-1.0,   1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,    // v5-v0-v3-v4 right
      9   -1.0, 1.0, 1.0,   1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,   // v1-v0-v5-v6 front
     10   -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,   // v1-v6-v7-v2 left
     11   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,  -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,    // v3-v2-v7-v4 back
     12   -1.0, 1.0,-1.0,   1.0, 1.0,-1.0,   1.0,-1.0,-1.0,  -1.0,-1.0,-1.0     // v4-v7-v6-v5 bottom
     13 };
     14 
     15 
     16 static GLfloat skybox_uvs[] = {
     17   1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,
     18   1.0, 1.0,-1.0,   1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,
     19   -1.0, 1.0, 1.0,   1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,
     20   -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,
     21   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,  -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,
     22   -1.0, 1.0,-1.0,   1.0, 1.0,-1.0,   1.0,-1.0,-1.0,  -1.0,-1.0,-1.0
     23 };
     24 
     25 
     26 static u32 skybox_indices[] = {
     27   0, 1, 2,   0, 2, 3,    // top     (+z)
     28   4, 5, 6,   4, 6, 7,    // right   (+x)
     29   8, 9,10,   8, 10,11,   // front (+y)
     30   12,13,14,  12,14,15,   // left    (-x)
     31   16,17,18,  16,18,19,   // back    (-y)
     32   20,21,22,  20,22,23    // bottom  (-z)
     33 };
     34 
     35 
     36 #define SKY_LENS(field, typ) { #field, offsetof(struct skybox, field), DATA_ID_##typ }
     37 static struct lens skybox_lenses[] = {
     38 	SKY_LENS(mvp, MAT4P),
     39 };
     40 #undef SKY_LENS
     41 
     42 static struct structure_binding skybox_bindings[] = {
     43     { skybox_lenses, ARRAY_SIZE(skybox_lenses) } 
     44 };
     45 
     46 void create_skybox(struct skybox *skybox, struct gpu_program *program) {
     47     struct shader vertex, frag;
     48     struct shader *shaders[] = {&vertex, &frag};
     49     int ok;
     50     (void)ok;
     51 
     52     node_init(&skybox->node);
     53     init_id(&skybox->model_id);
     54 
     55     skybox->program = program;
     56 
     57     struct make_geometry mkgeom;
     58     init_make_geometry(&mkgeom);
     59 
     60     mkgeom.vertices = skybox_vertices;
     61     mkgeom.indices = skybox_indices;
     62     /* geom->tex_coords = skybox_uvs; */
     63 
     64     /* geom->num_uv_components = 3; */
     65     mkgeom.num_verts = ARRAY_SIZE(skybox_vertices);
     66     mkgeom.num_indices = ARRAY_SIZE(skybox_indices);
     67 
     68     struct model *model = new_model(&skybox->model_id, "skybox"); assert(model);
     69     struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
     70 
     71     model->name = "skybox";
     72     make_buffer_geometry(&mkgeom, geom);
     73 
     74     static const char *faces[6] = {
     75       CUBEMAP("hw_sahara/sahara_rt_flip.tga"),
     76       CUBEMAP("hw_sahara/sahara_lf_flip.tga"),
     77       CUBEMAP("hw_sahara/sahara_ft_flip.tga"),
     78       CUBEMAP("hw_sahara/sahara_bk.tga"),
     79       CUBEMAP("hw_sahara/sahara_up_flip.tga"),
     80       CUBEMAP("hw_sahara/sahara_dn_flip.tga"),
     81     };
     82 
     83 
     84     /* static const char *faces[6] = { */
     85     /*   CUBEMAP("ame_siege/siege_rt_flip.tga"), */
     86     /*   CUBEMAP("ame_siege/siege_lf_flip.tga"), */
     87     /*   CUBEMAP("ame_siege/siege_ft_flip.tga"), */
     88     /*   CUBEMAP("ame_siege/siege_bk.tga"), */
     89     /*   CUBEMAP("ame_siege/siege_up_flip.tga"), */
     90     /*   CUBEMAP("ame_siege/siege_dn_flip.tga"), */
     91     /* }; */
     92 
     93     model->texture = create_cubemap(faces);
     94 
     95     make_shader(GL_VERTEX_SHADER, SHADER("skybox.v.glsl"), &vertex);
     96     check_gl();
     97     make_shader(GL_FRAGMENT_SHADER, SHADER("skybox.f.glsl"), &frag);
     98     check_gl();
     99 
    100     ok = make_program("skybox", &vertex, &frag, skybox->program,
    101 		    skybox_bindings, ARRAY_SIZE(skybox_bindings));
    102     assert(ok);
    103     check_gl();
    104 }
    105 
    106 
    107 void render_skybox(struct skybox *skybox, mat4 *camera) {
    108 
    109     struct model *model = get_model(&skybox->model_id); assert(model);
    110     struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
    111     void *structures[] = { skybox };
    112 
    113     skybox->mvp = camera;
    114 
    115     glDepthFunc(GL_LEQUAL);
    116     glDepthMask(GL_FALSE);
    117     check_gl();
    118 
    119     glUseProgram(skybox->program->handle);
    120     check_gl();
    121 
    122     bind_uniforms(skybox->program, structures, ARRAY_SIZE(structures));
    123 
    124     glBindTexture(GL_TEXTURE_CUBE_MAP, model->texture);
    125     check_gl();
    126 
    127     render_geometry(geom, skybox->program);
    128     check_gl();
    129 
    130     glDepthMask(GL_TRUE);
    131     check_gl();
    132     glDepthFunc(GL_LESS);
    133 }