]> git.localhorst.tv Git - gong.git/blob - src/graphics/mesh.cpp
code, assets, and other stuff stolen from blank
[gong.git] / src / graphics / mesh.cpp
1 #include "PrimitiveMesh.hpp"
2 #include "SkyBoxMesh.hpp"
3 #include "SpriteMesh.hpp"
4
5 #include "../geometry/primitive.hpp"
6
7 #include <algorithm>
8 #include <iostream>
9
10
11 namespace gong {
12 namespace graphics {
13
14 void PrimitiveMesh::Buffer::FillRect(
15         float w, float h,
16         const Color &color,
17         const glm::vec2 &pivot
18 ) {
19         Clear();
20         Reserve(4, 6);
21
22         vertices.emplace_back( -pivot.x,  -pivot.y, 0.0f);
23         vertices.emplace_back(w-pivot.x,  -pivot.y, 0.0f);
24         vertices.emplace_back( -pivot.x, h-pivot.y, 0.0f);
25         vertices.emplace_back(w-pivot.x, h-pivot.y, 0.0f);
26
27         colors.resize(4, color);
28
29         indices.assign({ 0, 2, 1, 1, 2, 3 });
30 }
31
32 void PrimitiveMesh::Buffer::OutlineBox(const geometry::AABB &box, const Color &color) {
33         Clear();
34         Reserve(8, 24);
35
36         vertices.emplace_back(box.min.x, box.min.y, box.min.z);
37         vertices.emplace_back(box.min.x, box.min.y, box.max.z);
38         vertices.emplace_back(box.min.x, box.max.y, box.min.z);
39         vertices.emplace_back(box.min.x, box.max.y, box.max.z);
40         vertices.emplace_back(box.max.x, box.min.y, box.min.z);
41         vertices.emplace_back(box.max.x, box.min.y, box.max.z);
42         vertices.emplace_back(box.max.x, box.max.y, box.min.z);
43         vertices.emplace_back(box.max.x, box.max.y, box.max.z);
44
45         colors.resize(8, color);
46
47         indices.assign({
48                 0, 1, 1, 3, 3, 2, 2, 0, // left
49                 4, 5, 5, 7, 7, 6, 6, 4, // right
50                 0, 4, 1, 5, 3, 7, 2, 6, // others
51         });
52 }
53
54
55 void PrimitiveMesh::Update(const Buffer &buf) noexcept {
56 #ifndef NDEBUG
57         if (buf.colors.size() < buf.vertices.size()) {
58                 std::cerr << "PrimitiveMesh: not enough colors!" << std::endl;
59         }
60 #endif
61
62         vao.Bind();
63         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
64         vao.PushAttribute(ATTRIB_COLOR, buf.colors, true);
65         vao.PushIndices(ATTRIB_INDEX, buf.indices);
66 }
67
68
69 void PrimitiveMesh::DrawLines() const noexcept {
70         glEnable(GL_LINE_SMOOTH);
71         glLineWidth(2.0f);
72         vao.DrawLineElements();
73 }
74
75
76 void SkyBoxMesh::LoadUnitBox() {
77         Buffer buffer;
78         buffer.vertices = {
79                 {  1.0f,  1.0f,  1.0f },
80                 {  1.0f,  1.0f, -1.0f },
81                 {  1.0f, -1.0f,  1.0f },
82                 {  1.0f, -1.0f, -1.0f },
83                 { -1.0f,  1.0f,  1.0f },
84                 { -1.0f,  1.0f, -1.0f },
85                 { -1.0f, -1.0f,  1.0f },
86                 { -1.0f, -1.0f, -1.0f },
87         };
88         buffer.indices = {
89                 5, 7, 3,  3, 1, 5,
90                 6, 7, 5,  5, 4, 6,
91                 3, 2, 0,  0, 1, 3,
92                 6, 4, 0,  0, 2, 6,
93                 5, 1, 0,  0, 4, 5,
94                 7, 6, 3,  3, 6, 2,
95         };
96         Update(buffer);
97 }
98
99 void SkyBoxMesh::Update(const Buffer &buf) noexcept {
100         vao.Bind();
101         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
102         vao.PushIndices(ATTRIB_INDEX, buf.indices);
103 }
104
105
106 void SpriteMesh::Buffer::LoadRect(
107         float w, float h,
108         const glm::vec2 &pivot,
109         const glm::vec2 &tex_begin,
110         const glm::vec2 &tex_end
111 ) {
112         Clear();
113         Reserve(4, 6);
114
115         vertices.emplace_back( -pivot.x,  -pivot.y, 0.0f);
116         vertices.emplace_back(w-pivot.x,  -pivot.y, 0.0f);
117         vertices.emplace_back( -pivot.x, h-pivot.y, 0.0f);
118         vertices.emplace_back(w-pivot.x, h-pivot.y, 0.0f);
119
120         coords.emplace_back(tex_begin.x, tex_begin.y);
121         coords.emplace_back(tex_end.x,   tex_begin.y);
122         coords.emplace_back(tex_begin.x, tex_end.y);
123         coords.emplace_back(tex_end.x,   tex_end.y);
124
125         indices.assign({ 0, 2, 1, 1, 2, 3 });
126 }
127
128
129 void SpriteMesh::Update(const Buffer &buf) noexcept {
130 #ifndef NDEBUG
131         if (buf.coords.size() < buf.vertices.size()) {
132                 std::cerr << "SpriteMesh: not enough coords!" << std::endl;
133         }
134 #endif
135
136         vao.Bind();
137         vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
138         vao.PushAttribute(ATTRIB_TEXCOORD, buf.coords);
139         vao.PushIndices(ATTRIB_INDEX, buf.indices);
140 }
141
142 }
143 }