6#include <brenta/renderer/mesh.hpp>
7#include <brenta/renderer/opengl/shader.hpp>
8#include <brenta/logger.hpp>
12using namespace brenta;
14Mesh::Mesh(
const Config& conf)
18 this->vertices = conf.vertices;
19 this->indices = conf.indices;
20 this->textures = tenno::move(conf.textures);
32 EVENT(Logger::Event::Lifetime,
"mesh: deleted {}", this->
id);
38 if (this->vertices.size() == 0 || this->indices.size() == 0)
44 this->vbo.init(Buffer::Target::Array);
47 this->vbo.copy_data(&this->vertices[0],
48 this->vertices.size() *
sizeof(Vertex),
49 Buffer::DataUsage::StaticDraw);
51 this->vao.link_buffer(this->vbo, 0, 3, Gl::Type::Float, Gl::False,
52 sizeof(Vertex), (
void *) 0);
53 this->vao.link_buffer(this->vbo, 1, 3, Gl::Type::Float, Gl::False,
55 (
void *) offsetof(Vertex, normal));
56 this->vao.link_buffer(this->vbo, 2, 2, Gl::Type::Float, Gl::False,
58 (
void *) offsetof(Vertex, tex_coords));
60 this->ebo.init(Buffer::Target::ElementArray);
62 this->ebo.copy_data(&this->indices[0],
63 this->indices.size() *
sizeof(
unsigned int),
64 Buffer::DataUsage::StaticDraw);
69 EVENT(Logger::Event::Lifetime,
"mesh: created {}", this->
id);
73void Mesh::draw()
const
75 if (this->vao.get_id() == 0)
77 ERROR(
"Mesh::draw: not initialized");
81 unsigned int diffuseNr = 1;
82 unsigned int specularNr = 1;
83 for (
unsigned int i = 0; i < this->textures.size(); i++)
85 Texture::active_texture(i);
89 auto type = textures[i]->get_type();
92 case Texture::Type::Diffuse:
93 name =
"texture_diffuse";
94 number = std::to_string(diffuseNr++);
96 case Texture::Type::Specular:
97 name =
"texture_specular";
98 number = std::to_string(specularNr++);
100 case Texture::Type::None:
109 glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
112 Shader::set_int(prog, (
"material." + name + number).c_str(), i);
116 Texture::active_texture(0);
120 Gl::draw_elements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
123 Texture::active_texture(0);
131Mesh::Builder &Mesh::Builder::vertices(tenno::vector<Vertex> &&vertices)
133 this->conf.vertices = vertices;
137Mesh::Builder &Mesh::Builder::indices(tenno::vector<unsigned int> &&indices)
139 this->conf.indices = indices;
143Mesh::Builder &Mesh::Builder::texture(tenno::shared_ptr<Texture> texture)
145 this->conf.textures.push_back(texture);
151 tenno::shared_ptr<Texture> shared = tenno::make_shared<Texture>(tenno::move(texture));
152 this->conf.textures.push_back(tenno::move(shared));
156Mesh::Builder &Mesh::Builder::textures(tenno::vector<tenno::shared_ptr<Texture>> textures)
158 for (
auto t : textures)
159 this->conf.textures.push_back(t);
164 #define PI 3.14159265358979323846f
171 case Mesh::Shape::Triangle:
172 this->conf.vertices = {
173 { {-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f} },
174 { { 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f} },
175 { { 0.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.5f, 1.0f} }};
176 this->conf.indices = {0, 1 , 2};
178 case Mesh::Shape::Square:
179 this->conf.vertices = {
180 { {-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f} },
181 { { 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f} },
182 { { 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f} },
183 { {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f} }};
184 this->conf.indices = {0, 1 , 2, 0, 2, 3};
186 case Mesh::Shape::Circle: {
187 const int num_vertices = 50;
188 const float delta = PI * 2 / num_vertices;
191 this->conf.vertices = {{
192 {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.5f, 0.5f}
195 for (
int i = 0; i <= num_vertices; ++i)
197 float angle = delta * i;
198 float x = std::cos(angle);
199 float y = std::sin(angle);
200 float tex_x = (x + 1) * 0.5f;
201 float tex_y = (y + 1) * 0.5f;
202 this->conf.vertices.push_back({
203 {x, y, 0.0f}, {1.0f, 1.0f, 1.0f}, {tex_x, tex_y}
207 for (
int i = 1; i <= num_vertices; ++i)
209 this->conf.indices.push_back(0);
210 this->conf.indices.push_back(i-1);
211 this->conf.indices.push_back(i);
213 this->conf.indices.push_back(0);
214 this->conf.indices.push_back(num_vertices);
215 this->conf.indices.push_back(1);
220 case Mesh::Shape::Pyramid:
222 this->conf.vertices = {
224 { {-1,-1,-1}, {0,-1,0}, {0,0} },
225 { { 1,-1,-1}, {0,-1,0}, {1,0} },
226 { { 1,-1, 1}, {0,-1,0}, {1,1} },
227 { {-1,-1, 1}, {0,-1,0}, {0,1} },
229 { {-1,-1,-1}, {0,0,0}, {0,0} },
230 { { 0, 1, 0}, {0,0,0}, {0.5,1} },
231 { { 1,-1,-1}, {0,0,0}, {1,0} },
233 { { 1,-1,-1}, {0,0,0}, {0,0} },
234 { { 0, 1, 0}, {0,0,0}, {0.5,1} },
235 { { 1,-1, 1}, {0,0,0}, {1,0} },
237 { { 1,-1, 1}, {0,0,0}, {0,0} },
238 { { 0, 1, 0}, {0,0,0}, {0.5,1} },
239 { {-1,-1, 1}, {0,0,0}, {1,0} },
241 { {-1,-1, 1}, {0,0,0}, {0,0} },
242 { { 0, 1, 0}, {0,0,0}, {0.5,1} },
243 { {-1,-1,-1}, {0,0,0}, {1,0} }
246 this->conf.indices = {
259 case Mesh::Shape::Cube:
261 this->conf.vertices = {
263 { {-1,-1, 1}, {0, 0, 1}, {0, 0} },
264 { { 1,-1, 1}, {0, 0, 1}, {1, 0} },
265 { { 1, 1, 1}, {0, 0, 1}, {1, 1} },
266 { {-1, 1, 1}, {0, 0, 1}, {0, 1} },
268 { { 1,-1,-1}, {0, 0, -1}, {0, 0} },
269 { {-1,-1,-1}, {0, 0, -1}, {1, 0} },
270 { {-1, 1,-1}, {0, 0, -1}, {1, 1} },
271 { { 1, 1,-1}, {0, 0, -1}, {0, 1} },
273 { {-1,-1,-1}, {-1, 0, 0}, {0, 0} },
274 { {-1,-1, 1}, {-1, 0, 0}, {1, 0} },
275 { {-1, 1, 1}, {-1, 0, 0}, {1, 1} },
276 { {-1, 1,-1}, {-1, 0, 0}, {0, 1} },
278 { {1,-1, 1}, {1, 0, 0}, {0, 0} },
279 { {1,-1,-1}, {1, 0, 0}, {1, 0} },
280 { {1, 1,-1}, {1, 0, 0}, {1, 1} },
281 { {1, 1, 1}, {1, 0, 0}, {0, 1} },
283 { {-1,1, 1}, {0, 1, 0}, {0, 0} },
284 { { 1,1, 1}, {0, 1, 0}, {1, 0} },
285 { { 1,1,-1}, {0, 1, 0}, {1, 1} },
286 { {-1,1,-1}, {0, 1, 0}, {0, 1} },
288 { {-1,-1,-1}, {0, -1, 0}, {0, 0} },
289 { { 1,-1,-1}, {0, -1, 0}, {1, 0} },
290 { { 1,-1, 1}, {0, -1, 0}, {1, 1} },
291 { {-1,-1, 1}, {0, -1, 0}, {0, 1} }
294 this->conf.indices = {
305 case Mesh::Shape::Sphere:
307 const int stacks = 20;
308 const int sectors = 20;
310 for (
int i = 0; i <= stacks; ++i)
312 float stack_angle = PI/2 - i * PI / stacks;
313 float xy = cos(stack_angle);
314 float z = sin(stack_angle);
316 for (
int j = 0; j <= sectors; ++j)
318 float sector_angle = j * 2 * PI / sectors;
320 float x = xy * cos(sector_angle);
321 float y = xy * sin(sector_angle);
323 float u = (float)j / sectors;
324 float v = (float)i / stacks;
326 this->conf.vertices.push_back({
334 for (
int i = 0; i < stacks; ++i)
336 int k1 = i * (sectors + 1);
337 int k2 = k1 + sectors + 1;
339 for (
int j = 0; j < sectors; ++j, ++k1, ++k2)
341 this->conf.indices.push_back(k1);
342 this->conf.indices.push_back(k2);
343 this->conf.indices.push_back(k1 + 1);
345 this->conf.indices.push_back(k1 + 1);
346 this->conf.indices.push_back(k2);
347 this->conf.indices.push_back(k2 + 1);
360Mesh Mesh::Builder::build()
362 return Mesh(this->conf);