summaryrefslogtreecommitdiff
path: root/gfx/src/core/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/src/core/buffer.c')
-rw-r--r--gfx/src/core/buffer.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/gfx/src/core/buffer.c b/gfx/src/core/buffer.c
new file mode 100644
index 0000000..3b7e4bc
--- /dev/null
+++ b/gfx/src/core/buffer.c
@@ -0,0 +1,85 @@
1#include "buffer.h"
2
3#include <gfx/core.h>
4#include <gfx_assert.h>
5
6#include <math/vec2.h>
7#include <math/vec3.h>
8#include <math/vec4.h>
9
10static size_t get_buffer_size_bytes(
11 BufferType type, const BufferDataDesc* desc) {
12 return desc->count * gfx_get_buffer_type_size_bytes(type);
13}
14
15static GLenum get_buffer_usage(BufferUsage usage) {
16 switch (usage) {
17 case BufferStatic:
18 return GL_STATIC_DRAW;
19 case BufferDynamic:
20 return GL_DYNAMIC_DRAW;
21 }
22 FAIL("Unhandled buffer usage");
23 return GL_STATIC_DRAW;
24}
25
26size_t gfx_get_buffer_type_size_bytes(BufferType type) {
27 switch (type) {
28 case BufferUntyped:
29 return 1;
30 case Buffer2d:
31 return sizeof(vec2);
32 case Buffer3d:
33 return sizeof(vec3);
34 case Buffer4d:
35 return sizeof(vec4);
36 case BufferFloat:
37 return sizeof(float);
38 case BufferU8:
39 return sizeof(uint8_t);
40 case BufferU16:
41 return sizeof(uint16_t);
42 }
43 FAIL("Unhandled buffer type");
44 return 0;
45}
46
47bool gfx_init_buffer(Buffer* buffer, const BufferDesc* desc) {
48 assert(buffer);
49
50 buffer->type = desc->type;
51 buffer->usage = desc->usage;
52 buffer->size_bytes = get_buffer_size_bytes(desc->type, &desc->data);
53 const GLenum usage = get_buffer_usage(desc->usage);
54
55 glGenBuffers(1, &buffer->vbo);
56 glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo);
57 glBufferData(GL_ARRAY_BUFFER, buffer->size_bytes, desc->data.data, usage);
58 glBindBuffer(GL_ARRAY_BUFFER, 0);
59 ASSERT_GL;
60
61 return true;
62}
63
64void gfx_del_buffer(Buffer* buffer) {
65 assert(buffer);
66 if (buffer->vbo) {
67 glDeleteBuffers(1, &buffer->vbo);
68 buffer->vbo = 0;
69 }
70}
71
72void gfx_update_buffer(Buffer* buffer, const BufferDataDesc* desc) {
73 assert(buffer);
74 assert(desc);
75 // OpenGL allows updating static buffers, but it is not optimal for
76 // performance, so we enforce data in static buffers remain static.
77 assert(buffer->usage == BufferDynamic);
78
79 const size_t update_size_bytes = get_buffer_size_bytes(buffer->type, desc);
80 assert(update_size_bytes <= buffer->size_bytes);
81
82 glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo);
83 glBufferSubData(GL_ARRAY_BUFFER, 0, update_size_bytes, desc->data);
84 glBindBuffer(GL_ARRAY_BUFFER, 0);
85}