summaryrefslogtreecommitdiff
path: root/src/mesh.c
blob: 2c3d040cb8ab2554564c41d638fb3c84a02093e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <GL/glew.h>

#include "gl.h"

void mesh_init(Mesh *mesh, u32 vertex_count)
{
	glGenVertexArrays(1, &mesh->vao);
	mesh->vbos_count = 0;
	mesh->vertex_count = vertex_count;
	mesh->ebo = 0;
	glBindVertexArray(mesh->vao);
}

static void mesh_store(Mesh *mesh, void *data, u32 len, u32 dimensions, GLenum type)
{
	GLuint vbo;
	GLint index = mesh->vbos_count;
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, len * dimensions, data, GL_STATIC_DRAW);
	glEnableVertexAttribArray(index);
	if (type == GL_FLOAT)
		glVertexAttribPointer(index, dimensions, type, GL_FALSE, 0, 0);
	else
		glVertexAttribIPointer(index, dimensions, type, 0, 0);
	mesh->vbos[mesh->vbos_count++] = vbo;
}

void mesh_store_float(Mesh *mesh, float *data, u32 count, u32 dimensions)
{
	mesh_store(mesh, data, count * sizeof(float), dimensions, GL_FLOAT);
}

void mesh_store_i32(Mesh *mesh, i32 *data, u32 count, u32 dimensions)
{
	mesh_store(mesh, data, count * sizeof(i32), dimensions, GL_INT);
}

void mesh_store_u8(Mesh *mesh, u8 *data, u32 count, u32 dimensions)
{
	mesh_store(mesh, data, count * sizeof(u8), dimensions, GL_UNSIGNED_BYTE);
}

void mesh_store_u32(Mesh *mesh, u32 *data, u32 count, u32 dimensions)
{
	mesh_store(mesh, data, count * sizeof(u32), dimensions, GL_UNSIGNED_INT);
}

void mesh_store_indicies(Mesh *mesh, u16 *data, u32 count)
{
	GLuint ebo;
	u32 len;
	len = count * sizeof(u16);
	glGenBuffers(1, &ebo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, len, data, GL_STATIC_DRAW);
	mesh->ebo = ebo;
}

void mesh_finish(void)
{
	glBindVertexArray(0);
}

void mesh_bind(Mesh *mesh)
{
	glBindVertexArray(mesh->vao);
	for (int i = 0; i < mesh->vbos_count; i++)
		glEnableVertexAttribArray(i);
}

void mesh_unbind(Mesh *mesh)
{
	for (int i = 0; i < mesh->vbos_count; i++)
		glDisableVertexAttribArray(i);
	glBindVertexArray(0);
}

void mesh_draw(Mesh *mesh)
{
	if (mesh->ebo)
		glDrawElements(GL_TRIANGLES, mesh->vertex_count, GL_UNSIGNED_SHORT, NULL);
	else
		glDrawArrays(GL_TRIANGLES, 0, mesh->vertex_count);
}

void mesh_draw_instanced(Mesh *mesh, u32 count)
{
	if (mesh->ebo)
		glDrawElementsInstanced(GL_TRIANGLES, mesh->vertex_count, GL_UNSIGNED_SHORT, NULL,
								count);
	else
		glDrawArraysInstanced(GL_TRIANGLES, 0, mesh->vertex_count, count);
}

void mesh_free(Mesh *mesh)
{
	glDeleteBuffers(mesh->vbos_count, mesh->vbos);
	glDeleteVertexArrays(1, &mesh->vao);
	if (mesh->ebo)
		glDeleteBuffers(1, &mesh->ebo);
}

void uniform_init(Uniform *uniform, u32 len)
{
	uniform->len = len;
	glGenBuffers(1, &uniform->id);
	glBindBuffer(GL_UNIFORM_BUFFER, uniform->id);
	glBufferData(GL_UNIFORM_BUFFER, len, NULL, GL_DYNAMIC_DRAW);
	glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

void uniform_store(Uniform *uniform, u32 offset, u32 len, void *data)
{
	glBindBuffer(GL_UNIFORM_BUFFER, uniform->id);
	glBufferSubData(GL_UNIFORM_BUFFER, offset, len, data);
	glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

void uniform_bind(Uniform *uniform, u32 binding)
{
	glBindBufferBase(GL_UNIFORM_BUFFER, binding, uniform->id);
}

void uniform_unbind(u32 binding)
{
	glBindBufferBase(GL_UNIFORM_BUFFER, binding, 0);
}

void uniform_free(Uniform *uniform)
{
	glDeleteBuffers(1, &uniform->id);
}