summaryrefslogtreecommitdiff
path: root/assets/vertex.glsl
blob: f4c3fdef50d10153fcb0330024d770b778a16711 (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
#version 330 core

layout (location = 0) in vec3 quad;

layout (std140) uniform Matrices {
	mat4 proj;
	mat4 view;
};

// world chunk position
const int CHUNK_SIZE = 16;
uniform ivec3 chunk_position;

const int MAX_FACES = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;
layout (std140) uniform Face {
	// normaly a uint but std140 layout
	// requires 16-byte alignment
	uvec4 face_data[MAX_FACES / 4];
};

flat out uvec2 pass_data;

uint get_half(int index)
{
	int arr_index = index / 4;
	int vec_index = index % 4;
	return face_data[arr_index][vec_index];
}

uvec2 get_data(int index)
{
	uint lower = get_half(index * 2);
	uint upper = get_half(index * 2 + 1);
	return uvec2(lower, upper);
}

vec3 get_quad(uint face, uint width, uint height)
{
	vec3 squad = quad;
	squad.x *= width;
	squad.y *= height;

	switch(face) {
		case 0u: // PX
			return squad.yzx + vec3(1, 0, 0);
		case 1u: // NX
			return squad.yxz;
		case 2u: // PY
			return squad.xyz + vec3(0, 1, 0);
		case 3u: // NY
			return squad.zyx;
		case 4u: // PZ
			return squad.zxy + vec3(0, 0, 1);
		case 5u: // NZ
			return squad.xzy;
	}
	// should not happen
	return vec3(0);
}

void main(void)
{
	// get face data
	uvec2 data = get_data(gl_InstanceID);
	uint x = (data.x >> 0) & 31u;
	uint y = (data.x >> 5) & 31u;
	uint z = (data.x >> 10) & 31u;
	uint width = (data.x >> 15) & 31u;
	uint height = (data.x >> 20) & 31u;
	uint face = (data.x >> 25) & 7u;

	// get quad verts
	vec3 quad = get_quad(face, width, height);

	// get position
	vec3 position = vec3(x, y, z);
	position += chunk_position * CHUNK_SIZE;
	position += quad;

	// draw
	gl_Position = proj * view * vec4(position, 1.0);
	pass_data = data;
}