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 }