Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
Mesh.cpp
Go to the documentation of this file.
1#include "render/Mesh.h"
2#include "graphics/GraphicsAPI.h"
3#include "Engine.h"
4
5namespace eng
6{
7 Mesh::Mesh(const VertexLayout& layout, const std::vector<float>& vertices, const std::vector<uint32_t>& indices)
8 {
9 m_vertexLayout = layout;
10
11 auto& graphicsAPI = Engine::GetInstance().GetGraphicsAPI();
12
13 m_VBO = graphicsAPI.CreateVertexBuffer(vertices);
14 m_EBO = graphicsAPI.CreateIndexBuffer(indices);
15
16 glGenVertexArrays(1, &m_VAO);
17 glBindVertexArray(m_VAO);
18
19 glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
20
21 for (auto& element : m_vertexLayout.elements)
22 {
23 glVertexAttribPointer(element.index, element.size, element.type, GL_FALSE,
24 m_vertexLayout.stride, (void*)(uintptr_t)element.offset);
25 glEnableVertexAttribArray(element.index);
26 }
27
28 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
29
30 glBindVertexArray(0);
31 glBindBuffer(GL_ARRAY_BUFFER, 0);
32 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
33
34 m_vertexCout = (vertices.size() * sizeof(float)) / m_vertexLayout.stride;
35 m_indexCount = indices.size();
36 }
37
38 Mesh::Mesh(const VertexLayout& layout, const std::vector<float>& vertices)
39 {
40 m_vertexLayout = layout;
41
42 auto& graphicsAPI = Engine::GetInstance().GetGraphicsAPI();
43
44 m_VBO = graphicsAPI.CreateVertexBuffer(vertices);
45
46 glGenVertexArrays(1, &m_VAO);
47 glBindVertexArray(m_VAO);
48
49 glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
50
51 for (auto& element : m_vertexLayout.elements)
52 {
53 glVertexAttribPointer(element.index, element.size, element.type, GL_FALSE,
54 m_vertexLayout.stride, (void*)(uintptr_t)element.offset);
55 glEnableVertexAttribArray(element.index);
56 }
57
58 glBindVertexArray(0);
59 glBindBuffer(GL_ARRAY_BUFFER, 0);
60
61 m_vertexCout = (vertices.size() * sizeof(float)) / m_vertexLayout.stride;
62 }
63
65 {
66 glBindVertexArray(m_VAO);
67 }
68
70 {
71 glBindVertexArray(0);
72 }
73
75 {
76 if (m_indexCount > 0)
77 {
78 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_indexCount), GL_UNSIGNED_INT, 0);
79 }
80 else
81 {
82 glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(m_vertexCout));
83 }
84 }
85
86 std::shared_ptr<Mesh> Mesh::CreateBox(const glm::vec3& extents)
87 {
88 const glm::vec3 half = extents * 0.5f;
89 std::vector<float> vertices =
90 {
91 // Front face
92 half.x, half.y, half.z, 1.0f, 0.0f, 0.0f, extents.x, extents.y, 0.0f, 0.0f, 1.0f,
93 -half.x, half.y, half.z, 0.0f, 1.0f, 0.0f, 0.0f, extents.y, 0.0f, 0.0f, 1.0f,
94 -half.x, -half.y, half.z, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
95 half.x, -half.y, half.z, 1.0f, 1.0f, 0.0f, extents.x, 0.0f, 0.0f, 0.0f, 1.0f,
96
97 // Top face
98 half.x, half.y, -half.z, 1.0f, 0.0f, 0.0f, extents.x, extents.z, 0.0f, 1.0f, 0.0f,
99 -half.x, half.y, -half.z, 0.0f, 1.0f, 0.0f, 0.0f, extents.z, 0.0f, 1.0f, 0.0f,
100 -half.x, half.y, half.z, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
101 half.x, half.y, half.z, 1.0f, 1.0f, 0.0f, extents.x, 0.0f, 0.0f, 1.0f, 0.0f,
102
103 // Right face
104 half.x, half.y, -half.z, 1.0f, 0.0f, 0.0f, extents.z, extents.y, 1.0f, 0.0f, 0.0f,
105 half.x, half.y, half.z, 0.0f, 1.0f, 0.0f, 0.0f, extents.y, 1.0f, 0.0f, 0.0f,
106 half.x, -half.y, half.z, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
107 half.x, -half.y, -half.z, 1.0f, 1.0f, 0.0f, extents.z, 0.0f, 1.0f, 0.0f, 0.0f,
108
109 // Left face
110 -half.x, half.y, half.z, 1.0f, 0.0f, 0.0f, extents.z, extents.y, -1.0f, 0.0f, 0.0f,
111 -half.x, half.y, -half.z, 0.0f, 1.0f, 0.0f, 0.0f, extents.y, -1.0f, 0.0f, 0.0f,
112 -half.x, -half.y, -half.z, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
113 -half.x, -half.y, half.z, 1.0f, 1.0f, 0.0f, extents.z, 0.0f, -1.0f, 0.0f, 0.0f,
114
115 // Bottom face
116 half.x, -half.y, half.z, 1.0f, 0.0f, 0.0f, extents.x, extents.z, 0.0f, -1.0f, 0.0f,
117 -half.x, -half.y, half.z, 0.0f, 1.0f, 0.0f, 0.0f, extents.z, 0.0f, -1.0f, 0.0f,
118 -half.x, -half.y, -half.z, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
119 half.x, -half.y, -half.z, 1.0f, 1.0f, 0.0f, extents.x, 0.0f, 0.0f, -1.0f, 0.0f,
120
121 // Back face
122 -half.x, half.y, -half.z, 1.0f, 0.0f, 0.0f, extents.x, extents.y, 0.0f, 0.0f, -1.0f,
123 half.x, half.y, -half.z, 0.0f, 1.0f, 0.0f, 0.0f, extents.y, 0.0f, 0.0f, -1.0f,
124 half.x, -half.y, -half.z, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
125 -half.x, -half.y, -half.z, 1.0f, 1.0f, 0.0f, extents.x, 0.0f, 0.0f, 0.0f, -1.0f
126 };
127
128 std::vector<unsigned int> indices =
129 {
130 // front face
131 0, 1, 2,
132 0, 2, 3,
133 // top face
134 4, 5, 6,
135 4, 6, 7,
136 // right face
137 8, 9, 10,
138 8, 10, 11,
139 // left face
140 12, 13, 14,
141 12, 14, 15,
142 // bottom face
143 16, 17, 18,
144 16, 18, 19,
145 // back face
146 20, 21, 22,
147 20, 22, 23
148 };
149
150 eng::VertexLayout vertexLayout;
151
152 // Postion
153 vertexLayout.elements.push_back({
155 3,
156 GL_FLOAT,
157 0
158 });
159 // Color
160 vertexLayout.elements.push_back({
162 3,
163 GL_FLOAT,
164 sizeof(float) * 3
165 });
166 // UV
167 vertexLayout.elements.push_back({
169 2,
170 GL_FLOAT,
171 sizeof(float) * 6
172 });
173 // Normal
174 vertexLayout.elements.push_back({
176 3,
177 GL_FLOAT,
178 sizeof(float) * 8
179 });
180 vertexLayout.stride = sizeof(float) * 11;
181
182 auto result = std::make_shared<eng::Mesh>(vertexLayout, vertices, indices);
183
184 return result;
185 }
186
187 std::shared_ptr<Mesh> Mesh::CreateSphere(float radius, int sectors, int stacks)
188 {
189 const float PI = 3.14159265358979323846f;
190
191 std::vector<float> vertices((stacks + 1) * (sectors + 1) * 8);
192 for (int i = 0; i <= stacks; ++i)
193 {
194 float stackAngle = PI / 2.0f - static_cast<float>(i) * (PI / static_cast<float>(stacks)); // From -π/2 to π/2
195 float xy = radius * cosf(stackAngle); // x-y plane radius at this stack
196 float z = radius * sinf(stackAngle); // z coordinate
197
198 for (int j = 0; j <= sectors; ++j) {
199 float sectorAngle = static_cast<float>(j) * (2.0f * PI / static_cast<float>(sectors)); // From 0 to 2π
200
201 float x = xy * cosf(sectorAngle);
202 float y = xy * sinf(sectorAngle);
203
204 size_t vertexStart = (i * (sectors + 1) + j) * 8;
205 // Position
206 vertices[vertexStart] = x;
207 vertices[vertexStart + 1] = y;
208 vertices[vertexStart + 2] = z;
209
210 // Normal (normalized position vector)
211 float length = sqrtf(x * x + y * y + z * z);
212 vertices[vertexStart + 3] = x / length;
213 vertices[vertexStart + 4] = y / length;
214 vertices[vertexStart + 5] = z / length;
215
216 // UV coordinates
217 vertices[vertexStart + 6] = static_cast<float>(j) / static_cast<float>(sectors);
218 vertices[vertexStart + 7] = static_cast<float>(i) / static_cast<float>(stacks);
219 }
220 }
221
222 // Generate indices
223 std::vector<unsigned int> indices;
224 for (int i = 0; i < stacks; ++i)
225 {
226 int k1 = i * (sectors + 1);
227 int k2 = k1 + sectors + 1;
228
229 for (int j = 0; j < sectors; ++j, ++k1, ++k2)
230 {
231 if (i != 0)
232 {
233 indices.push_back(k1);
234 indices.push_back(k2);
235 indices.push_back(k1 + 1);
236 }
237
238 if (i != (stacks - 1))
239 {
240 indices.push_back(k1 + 1);
241 indices.push_back(k2);
242 indices.push_back(k2 + 1);
243 }
244 }
245 }
246
247 eng::VertexLayout vertexLayout;
248
249 // Postion
250 vertexLayout.elements.push_back({
252 3,
253 GL_FLOAT,
254 0
255 });
256 // Normal
257 vertexLayout.elements.push_back({
259 3,
260 GL_FLOAT,
261 sizeof(float) * 3
262 });
263 // UV
264 vertexLayout.elements.push_back({
266 2,
267 GL_FLOAT,
268 sizeof(float) * 6
269 });
270 vertexLayout.stride = sizeof(float) * 8;
271
272 auto result = std::make_shared<eng::Mesh>(vertexLayout, vertices, indices);
273
274 return result;
275 }
276
277 std::shared_ptr<Mesh> Mesh::CreatePlane()
278 {
279 std::vector<float> vertices =
280 {
281 1.0f, 1.0f,
282 0.0f, 1.0f,
283 0.0f, 0.0f,
284 1.0f, 0.0f
285 };
286
287 std::vector<uint32_t> indices =
288 {
289 0, 1, 2,
290 0, 2, 3
291 };
292
293 eng::VertexLayout vertexLayout;
294
295 // Position
296 vertexLayout.elements.push_back({
298 2,
299 GL_FLOAT,
300 0
301 });
302 vertexLayout.stride = sizeof(float) * 2;
303
304 auto result = std::make_shared<eng::Mesh>(vertexLayout, vertices, indices);
305
306 return result;
307 }
308}
int GLsizei
Definition GLForward.h:14
GraphicsAPI & GetGraphicsAPI()
Definition Engine.cpp:195
static Engine & GetInstance()
Definition Engine.cpp:50
void Unbind()
Definition Mesh.cpp:69
void Draw()
Definition Mesh.cpp:74
Mesh(const VertexLayout &layout, const std::vector< float > &vertices, const std::vector< uint32_t > &indices)
Definition Mesh.cpp:7
static std::shared_ptr< Mesh > CreatePlane()
Definition Mesh.cpp:277
static std::shared_ptr< Mesh > CreateBox(const glm::vec3 &extents=glm::vec3(1.0f))
Definition Mesh.cpp:86
static std::shared_ptr< Mesh > CreateSphere(float radius, int sectors, int stacks)
Definition Mesh.cpp:187
void Bind()
Definition Mesh.cpp:64
static constexpr int NormalIndex
static constexpr int ColorIndex
static constexpr int UVIndex
static constexpr int PositionIndex
std::vector< VertexElement > elements