/
tesselator.c
109 lines (87 loc) · 3.49 KB
/
tesselator.c
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
/*
Copyright (c) 2017-2020 ByteBit
This file is part of BetterSpades.
BetterSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
BetterSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BetterSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "tesselator.h"
void tesselator_create(struct tesselator* t, enum tesselator_type type) {
t->quad_count = 0;
t->quad_space = 128;
t->vertices = NULL;
t->colors = NULL;
t->type = type;
if(t->type == TESSELATE_QUADS) {
t->vertices = malloc(t->quad_space * sizeof(int16_t) * 3 * 4);
CHECK_ALLOCATION_ERROR(t->vertices)
t->colors = malloc(t->quad_space * sizeof(uint32_t) * 4);
CHECK_ALLOCATION_ERROR(t->colors)
}
if(t->type == TESSELATE_TRIANGLES) {
t->vertices = malloc(t->quad_space * sizeof(int16_t) * 3 * 6);
CHECK_ALLOCATION_ERROR(t->vertices)
t->colors = malloc(t->quad_space * sizeof(uint32_t) * 6);
CHECK_ALLOCATION_ERROR(t->colors)
}
}
void tesselator_free(struct tesselator* t) {
if(t->vertices)
free(t->vertices);
if(t->colors)
free(t->colors);
}
void tesselator_glx(struct tesselator* t, struct glx_displaylist* x) {
if(t->type == TESSELATE_QUADS) {
glx_displaylist_update(x, t->quad_count * 4, GLX_DISPLAYLIST_NORMAL, t->colors, t->vertices, NULL);
}
if(t->type == TESSELATE_TRIANGLES) {
glx_displaylist_update(x, t->quad_count * 6, GLX_DISPLAYLIST_NORMAL, t->colors, t->vertices, NULL);
}
}
void tesselator_set_color(struct tesselator* t, uint32_t color) {
t->color = color;
}
void tesselator_add(struct tesselator* t, int16_t* coords, uint32_t* colors) {
if(t->quad_count >= t->quad_space) {
t->quad_space *= 2;
if(t->type == TESSELATE_QUADS) {
t->vertices = realloc(t->vertices, t->quad_space * sizeof(int16_t) * 3 * 4);
CHECK_ALLOCATION_ERROR(t->vertices)
t->colors = realloc(t->colors, t->quad_space * sizeof(uint32_t) * 4);
CHECK_ALLOCATION_ERROR(t->colors)
}
if(t->type == TESSELATE_TRIANGLES) {
t->vertices = realloc(t->vertices, t->quad_space * sizeof(int16_t) * 3 * 6);
CHECK_ALLOCATION_ERROR(t->vertices)
t->colors = realloc(t->colors, t->quad_space * sizeof(uint32_t) * 6);
CHECK_ALLOCATION_ERROR(t->colors)
}
}
if(t->type == TESSELATE_QUADS) {
memcpy(t->vertices + t->quad_count * 3 * 4, coords, sizeof(int16_t) * 3 * 4);
memcpy(t->colors + t->quad_count * 4, colors, sizeof(uint32_t) * 4);
}
if(t->type == TESSELATE_TRIANGLES) {
memcpy(t->vertices + t->quad_count * 3 * 6 + 3 * 0, coords, sizeof(int16_t) * 3 * 3);
memcpy(t->vertices + t->quad_count * 3 * 6 + 3 * 3, coords + 3 * 0, sizeof(int16_t) * 3);
memcpy(t->vertices + t->quad_count * 3 * 6 + 3 * 4, coords + 3 * 2, sizeof(int16_t) * 3 * 2);
memcpy(t->colors + t->quad_count * 6, colors, sizeof(uint32_t) * 3);
t->colors[t->quad_count * 6 + 3] = colors[0];
memcpy(t->colors + t->quad_count * 6 + 4, colors + 2, sizeof(uint32_t) * 2);
}
t->quad_count++;
}
void tesselator_add_simple(struct tesselator* t, int16_t* coords) {
tesselator_add(t, coords, (uint32_t[]) {t->color, t->color, t->color, t->color});
}