]> git.localhorst.tv Git - blank.git/blob - src/graphics/mesh.cpp
save a little bandwidth
[blank.git] / src / graphics / mesh.cpp
1 #include "BlockMesh.hpp"
2 #include "EntityMesh.hpp"
3 #include "PrimitiveMesh.hpp"
4 #include "SkyBoxMesh.hpp"
5 #include "SpriteMesh.hpp"
6
7 #include "../geometry/primitive.hpp"
8
9 #include <algorithm>
10 #include <iostream>
11
12
13 namespace blank {
14
15 void EntityMesh::Update(const Buffer &buf) noexcept {
16 #ifndef NDEBUG
17         if (buf.tex_coords.size() < buf.vertices.size()) {
18                 std::cerr << "EntityMesh: not enough tex coords!" << std::endl;
19         }
20         if (buf.hsl_mods.size() < buf.vertices.size()) {
21                 std::cerr << "BlockMesh: not enough HSL modifiers!" << std::endl;
22         }
23         if (buf.rgb_mods.size() < buf.vertices.size()) {
24                 std::cerr << "BlockMesh: not enough RGB modifiers!" << std::endl;
25         }
26         if (buf.normals.size() < buf.vertices.size()) {
27                 std::cerr << "EntityMesh: not enough normals!" << std::endl;
28         }
29 #endif
30
31         vao.Bind();
32         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
33         vao.PushAttribute(ATTRIB_TEXCOORD, buf.tex_coords);
34         vao.PushAttribute(ATTRIB_HSL, buf.hsl_mods, true);
35         vao.PushAttribute(ATTRIB_RGB, buf.rgb_mods, true);
36         vao.PushAttribute(ATTRIB_NORMAL, buf.normals);
37         vao.PushIndices(ATTRIB_INDEX, buf.indices);
38 }
39
40
41 void EntityMesh::Draw() const noexcept {
42         vao.DrawTriangleElements();
43 }
44
45
46 void BlockMesh::Update(const Buffer &buf) noexcept {
47 #ifndef NDEBUG
48         if (buf.tex_coords.size() < buf.vertices.size()) {
49                 std::cerr << "BlockMesh: not enough tex coords!" << std::endl;
50         }
51         if (buf.hsl_mods.size() < buf.vertices.size()) {
52                 std::cerr << "BlockMesh: not enough HSL modifiers!" << std::endl;
53         }
54         if (buf.rgb_mods.size() < buf.vertices.size()) {
55                 std::cerr << "BlockMesh: not enough RGB modifiers!" << std::endl;
56         }
57         if (buf.lights.size() < buf.vertices.size()) {
58                 std::cerr << "BlockMesh: not enough lights!" << std::endl;
59         }
60 #endif
61
62         vao.Bind();
63         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
64         vao.PushAttribute(ATTRIB_TEXCOORD, buf.tex_coords);
65         vao.PushAttribute(ATTRIB_HSL, buf.hsl_mods, true);
66         vao.PushAttribute(ATTRIB_RGB, buf.rgb_mods, true);
67         vao.PushAttribute(ATTRIB_LIGHT, buf.lights);
68         vao.PushIndices(ATTRIB_INDEX, buf.indices);
69 }
70
71
72 void BlockMesh::Draw() const noexcept {
73         vao.DrawTriangleElements();
74 }
75
76
77 void PrimitiveMesh::Buffer::FillRect(
78         float w, float h,
79         const Color &color,
80         const glm::vec2 &pivot
81 ) {
82         Clear();
83         Reserve(4, 6);
84
85         vertices.emplace_back( -pivot.x,  -pivot.y, 0.0f);
86         vertices.emplace_back(w-pivot.x,  -pivot.y, 0.0f);
87         vertices.emplace_back( -pivot.x, h-pivot.y, 0.0f);
88         vertices.emplace_back(w-pivot.x, h-pivot.y, 0.0f);
89
90         colors.resize(4, color);
91
92         indices.assign({ 0, 2, 1, 1, 2, 3 });
93 }
94
95 void PrimitiveMesh::Buffer::OutlineBox(const AABB &box, const Color &color) {
96         Clear();
97         Reserve(8, 24);
98
99         vertices.emplace_back(box.min.x, box.min.y, box.min.z);
100         vertices.emplace_back(box.min.x, box.min.y, box.max.z);
101         vertices.emplace_back(box.min.x, box.max.y, box.min.z);
102         vertices.emplace_back(box.min.x, box.max.y, box.max.z);
103         vertices.emplace_back(box.max.x, box.min.y, box.min.z);
104         vertices.emplace_back(box.max.x, box.min.y, box.max.z);
105         vertices.emplace_back(box.max.x, box.max.y, box.min.z);
106         vertices.emplace_back(box.max.x, box.max.y, box.max.z);
107
108         colors.resize(8, color);
109
110         indices.assign({
111                 0, 1, 1, 3, 3, 2, 2, 0, // left
112                 4, 5, 5, 7, 7, 6, 6, 4, // right
113                 0, 4, 1, 5, 3, 7, 2, 6, // others
114         });
115 }
116
117
118 void PrimitiveMesh::Update(const Buffer &buf) noexcept {
119 #ifndef NDEBUG
120         if (buf.colors.size() < buf.vertices.size()) {
121                 std::cerr << "PrimitiveMesh: not enough colors!" << std::endl;
122         }
123 #endif
124
125         vao.Bind();
126         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
127         vao.PushAttribute(ATTRIB_COLOR, buf.colors, true);
128         vao.PushIndices(ATTRIB_INDEX, buf.indices);
129 }
130
131
132 void PrimitiveMesh::DrawLines() noexcept {
133         glEnable(GL_LINE_SMOOTH);
134         glLineWidth(2.0f);
135         vao.DrawLineElements();
136 }
137
138 void PrimitiveMesh::DrawTriangles() noexcept {
139         vao.DrawTriangleElements();
140 }
141
142
143 void SkyBoxMesh::LoadUnitBox() {
144         Buffer buffer;
145         buffer.vertices = {
146                 {  1.0f,  1.0f,  1.0f },
147                 {  1.0f,  1.0f, -1.0f },
148                 {  1.0f, -1.0f,  1.0f },
149                 {  1.0f, -1.0f, -1.0f },
150                 { -1.0f,  1.0f,  1.0f },
151                 { -1.0f,  1.0f, -1.0f },
152                 { -1.0f, -1.0f,  1.0f },
153                 { -1.0f, -1.0f, -1.0f },
154         };
155         buffer.indices = {
156                 5, 7, 3,  3, 1, 5,
157                 6, 7, 5,  5, 4, 6,
158                 3, 2, 0,  0, 1, 3,
159                 6, 4, 0,  0, 2, 6,
160                 5, 1, 0,  0, 4, 5,
161                 7, 6, 3,  3, 6, 2,
162         };
163         Update(buffer);
164 }
165
166 void SkyBoxMesh::Update(const Buffer &buf) noexcept {
167         vao.Bind();
168         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
169         vao.PushIndices(ATTRIB_INDEX, buf.indices);
170 }
171
172 void SkyBoxMesh::Draw() const noexcept {
173         vao.DrawTriangleElements();
174 }
175
176
177 void SpriteMesh::Buffer::LoadRect(
178         float w, float h,
179         const glm::vec2 &pivot,
180         const glm::vec2 &tex_begin,
181         const glm::vec2 &tex_end
182 ) {
183         Clear();
184         Reserve(4, 6);
185
186         vertices.emplace_back( -pivot.x,  -pivot.y, 0.0f);
187         vertices.emplace_back(w-pivot.x,  -pivot.y, 0.0f);
188         vertices.emplace_back( -pivot.x, h-pivot.y, 0.0f);
189         vertices.emplace_back(w-pivot.x, h-pivot.y, 0.0f);
190
191         coords.emplace_back(tex_begin.x, tex_begin.y);
192         coords.emplace_back(tex_end.x,   tex_begin.y);
193         coords.emplace_back(tex_begin.x, tex_end.y);
194         coords.emplace_back(tex_end.x,   tex_end.y);
195
196         indices.assign({ 0, 2, 1, 1, 2, 3 });
197 }
198
199
200 void SpriteMesh::Update(const Buffer &buf) noexcept {
201 #ifndef NDEBUG
202         if (buf.coords.size() < buf.vertices.size()) {
203                 std::cerr << "SpriteMesh: not enough coords!" << std::endl;
204         }
205 #endif
206
207         vao.Bind();
208         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
209         vao.PushAttribute(ATTRIB_TEXCOORD, buf.coords);
210         vao.PushIndices(ATTRIB_INDEX, buf.indices);
211 }
212
213
214 void SpriteMesh::Draw() noexcept {
215         vao.DrawTriangleElements();
216 }
217
218 }