polyadvent

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

vbo.c (4356B)


      1 
      2 #include "vbo.h"
      3 #include "util.h"
      4 #include "debug.h"
      5 #include <assert.h>
      6 #include "gl.h"
      7 
      8 gpu_addr
      9 make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size) {
     10   gpu_addr buffer;
     11   check_gl();
     12   glGenBuffers(1, &buffer);
     13   check_gl();
     14 
     15   glBindBuffer(target, buffer);
     16   check_gl();
     17   assert(buffer_size > 0);
     18 
     19   /* debug("buffer data %d\n", buffer_size); */
     20   glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
     21   check_gl();
     22 
     23   return buffer;
     24 }
     25 
     26 
     27 static struct vbo*
     28 make_vertex_buffer(struct vbo *vbo, const void *data,
     29                    GLenum type,
     30                    GLenum component_type,
     31                    struct element_size element_size,
     32                    struct num_elements num_elements,
     33                    struct components components)
     34 {
     35     vbo->components = components.components;
     36     vbo->handle = make_buffer(type,
     37                               data,
     38                               num_elements.num_elements *
     39                               element_size.element_size *
     40                               components.components);
     41     vbo->type = type;
     42     vbo->component_type = component_type;
     43     return vbo;
     44 }
     45 
     46 struct vbo*
     47 make_index_buffer(struct vbo *vbo, const void *data,
     48                   struct num_elements num_elements)
     49 {
     50     vbo->handle = make_buffer(GL_ELEMENT_ARRAY_BUFFER,
     51                               data,
     52                               num_elements.num_elements * sizeof(u32));
     53     vbo->type = GL_ELEMENT_ARRAY_BUFFER;
     54     vbo->component_type = GL_INT;
     55     return vbo;
     56 }
     57 
     58 struct vbo* make_float_vertex_buffer(struct vbo *vbo, const void *data,
     59                                      struct num_elements num_elements,
     60                                      struct components components)
     61 {
     62     return make_vertex_buffer(vbo,
     63                               data,
     64                               GL_ARRAY_BUFFER,
     65                               GL_FLOAT,
     66                               mk_element_size(sizeof(GLfloat)),
     67                               num_elements,
     68                               components);
     69 }
     70 
     71 
     72 struct vbo* make_int_vertex_buffer(struct vbo *vbo, const u32 *data,
     73                                    struct num_elements num_elements,
     74                                    struct components components)
     75 {
     76     return make_vertex_buffer(vbo,
     77                               data,
     78                               GL_ARRAY_BUFFER,
     79                               GL_INT,
     80                               mk_element_size(sizeof(u32)),
     81                               num_elements,
     82                               components);
     83 }
     84 
     85 
     86 struct vbo * make_uv_buffer(struct vbo *vbo, const void *data,
     87                             struct num_elements num_elements,
     88                             struct components components)
     89 {
     90     return make_vertex_buffer(vbo,
     91                               data,
     92                               GL_ARRAY_BUFFER,
     93                               GL_FLOAT,
     94                               mk_element_size(sizeof(float)),
     95                               num_elements,
     96                               components);
     97 }
     98 
     99 
    100 static void bind_ibo(struct vbo *vbo)
    101 {
    102     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle);
    103 }
    104 
    105 struct vbo* init_vbo(struct vbo *vbo) {
    106     vbo->type = 0;
    107     vbo->handle = 0;
    108     vbo->components = 0;
    109     return vbo;
    110 }
    111 
    112 static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot, GLenum type) {
    113   glEnableVertexAttribArray(slot);
    114   check_gl();
    115   glBindBuffer(vbo->type, vbo->handle);
    116   check_gl();
    117 
    118   // should use bind_ibo instead...
    119   assert(vbo->type != GL_ELEMENT_ARRAY_BUFFER);
    120 
    121   if (vbo->component_type == GL_INT) {
    122       glVertexAttribIPointer(slot,
    123                              vbo->components,
    124                              type,
    125                              0, // stride
    126                              (void*)0);
    127   }
    128   else {
    129       glVertexAttribPointer(slot,              // attribute
    130                             vbo->components,   // size
    131                             type,          // type
    132                             GL_FALSE,          // normalized?
    133                             0,   // stride
    134                             (void*)0           // array buffer offset
    135                             );
    136   }
    137 }
    138 
    139 void bind_vbo(struct vbo *vbo, gpu_addr slot, GLenum type) {
    140     if (vbo->type == GL_ELEMENT_ARRAY_BUFFER)
    141         return bind_ibo(vbo);
    142     bind_vbo_internal(vbo, slot, type);
    143 }