polyadvent

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

slab.c (3979B)


      1 
      2 
      3 #include "slab.h"
      4 #include "util.h"
      5 #include <assert.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 
      9 
     10 #define defconsume(T)                           \
     11   static inline T                               \
     12   consume_##T(void **p) {                 \
     13     T *i = (T*)*p;                            \
     14     T v = *i++;                                 \
     15     *p = (void*)i;                              \
     16     return v;                                   \
     17   }
     18 
     19 defconsume(int)
     20 //defconsume(char)
     21 
     22 /* slab_vbo(const void *data) { */
     23 /*   struct slab *slab = (struct slab*)data; */
     24 /*   assert(slab->x == 3); */
     25 /*   assert(slab->y == 3); */
     26 /*   assert(slab->z == 3); */
     27 /* } */
     28 
     29 struct slab *slab_parse(struct slab *slab, void *data) {
     30   void *p = data;
     31   slab->x = consume_int(&p);
     32   slab->y = consume_int(&p);
     33   slab->z = consume_int(&p);
     34   slab->voxels = (void*)p;
     35   return slab;
     36 }
     37 
     38 int slab_size(const struct slab *slab) {
     39   return slab->x *
     40          slab->y *
     41          slab->z;
     42 }
     43 
     44 void slab_show(const struct slab *slab) {
     45   printf("slab %d %d %d\n", slab->x, slab->y, slab->z);
     46 }
     47 
     48 
     49 
     50 //    v6----- v5
     51 //   /|      /|
     52 //  v1------v0|
     53 //  | |     | |
     54 //  | |v7---|-|v4
     55 //  |/      |/
     56 //  v2------v3
     57 
     58 #define BLOCK_AIR 0xFF
     59 
     60 static const float cube_verts[] = {
     61   1, 1, 1,  -1, 1, 1,  -1,-1, 1,   1,-1, 1,    // v0-v1-v2-v3 front
     62   1, 1,-1,   1, 1, 1,   1,-1, 1,   1,-1,-1,    // v5-v0-v3-v4 right
     63  -1, 1, 1,   1, 1, 1,   1, 1,-1,  -1, 1,-1,    // v1-v0-v5-v6 top
     64  -1, 1, 1,  -1, 1,-1,  -1,-1,-1,  -1,-1, 1,    // v1-v6-v7-v2 left
     65   1,-1, 1,  -1,-1, 1,  -1,-1,-1,   1,-1,-1,    // v3-v2-v7-v4 bottom
     66  -1, 1,-1,   1, 1,-1,   1,-1,-1,  -1,-1,-1     // v4-v7-v6-v5 back
     67 };
     68 
     69 static const float cube_normals[] = {
     70   0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1, // front
     71   1, 0, 0,   1, 0, 0,   1, 0, 0,   1, 0, 0, // right
     72   0, 1, 0,   0, 1, 0,   0, 1, 0,   0, 1, 0, // top
     73  -1, 0, 0,  -1, 0, 0,  -1, 0, 0,  -1, 0, 0, // left
     74   0,-1, 0,   0,-1, 0,   0,-1, 0,   0,-1, 0, // bottom
     75   0, 0,-1,   0, 0,-1,   0, 0,-1,   0, 0,-1  // back
     76 };
     77 
     78 
     79 static const u32 cube_indices[] = {
     80    0, 1, 2,   0, 2, 3,    // front
     81    4, 5, 6,   4, 6, 7,    // right
     82    8, 9,10,   8,10,11,    // top
     83   12,13,14,  12,14,15,    // left
     84   16,17,18,  16,18,19,    // bottom
     85   20,21,22,  20,22,23
     86 };
     87 
     88 void
     89 slab_arrays(const struct slab *slab,
     90             float *verts,
     91             float *normals,
     92             u32 *indices,
     93             int *num_elements) {
     94   int x, y, z, i, j;
     95   u32 start_index = 0;
     96   int verts_ind, normals_ind, index_ind;
     97   verts_ind = 0; normals_ind = 0; index_ind = 0;
     98   int xs = slab->x;
     99   int ys = slab->y;
    100   int zs = slab->z;
    101   int cube_verts_size = ARRAY_SIZE(cube_verts);
    102   int cube_indices_size = ARRAY_SIZE(cube_indices);
    103   float n = 0.5f;
    104   u8 color = 0;
    105 
    106   printf("got here cvs(%d) %d %d %d\n", cube_verts_size, xs, ys, zs);
    107 
    108   for (x = 0; x < xs; ++x)
    109   for (y = 0; y < ys; ++y)
    110   for (z = 0; z < zs; ++z) {
    111     int yind = y * zs;
    112     int xind = x * zs * ys;
    113     color = slab->voxels[z + yind + xind];
    114 
    115     /* printf("building color(0x%x) %d %d %d vi(%d) ni(%d) ii(%d)\n", */
    116     /*        color, x, y, z, verts_ind, normals_ind, index_ind); */
    117 
    118     for (i = 0; i < cube_verts_size; i += 12) // for each face
    119     for (j = 0; j < 12; j += 3) { // for each vert
    120       int k = i + j;
    121       verts[verts_ind++] = cube_verts[k] * n + x;
    122       verts[verts_ind++] = cube_verts[k+1] * n + y;
    123       verts[verts_ind++] = cube_verts[k+2] * n + z;
    124 
    125       normals[normals_ind++] = cube_normals[k];
    126       normals[normals_ind++] = cube_normals[k+1];
    127       normals[normals_ind++] = cube_normals[k+2];
    128     }
    129 
    130     // if we have something other than air
    131     if (color != BLOCK_AIR) {
    132       for (i = 0; i < cube_indices_size; ++i) {
    133         indices[index_ind++] = cube_indices[i] + start_index;
    134       }
    135     }
    136 
    137     start_index += 24;
    138   }
    139 
    140 
    141   //assert(index_ind < 65535);
    142   printf("ind %d pos(%d) norm(%d)\n", index_ind, verts_ind, normals_ind);
    143   printf("ret slab_arrays %d\n", index_ind);
    144   *num_elements = index_ind;
    145 }