mirror of
https://github.com/Relintai/sfw.git
synced 2025-01-09 21:19:36 +01:00
188 lines
4.6 KiB
C++
188 lines
4.6 KiB
C++
#include "mesh.h"
|
|
|
|
#include "shader.h"
|
|
|
|
void Mesh::add_vertex2(float x, float y) {
|
|
vertices.push_back(x);
|
|
vertices.push_back(y);
|
|
}
|
|
void Mesh::add_vertex3(float x, float y, float z) {
|
|
vertices.push_back(x);
|
|
vertices.push_back(y);
|
|
vertices.push_back(z);
|
|
}
|
|
|
|
void Mesh::add_normal(float x, float y, float z) {
|
|
normals.push_back(x);
|
|
normals.push_back(y);
|
|
normals.push_back(z);
|
|
}
|
|
void Mesh::add_color(float r, float g, float b, float a) {
|
|
colors.push_back(r);
|
|
colors.push_back(g);
|
|
colors.push_back(b);
|
|
colors.push_back(a);
|
|
}
|
|
|
|
void Mesh::add_uv(float u, float v) {
|
|
uvs.push_back(u);
|
|
uvs.push_back(v);
|
|
}
|
|
|
|
void Mesh::add_index(uint32_t index) {
|
|
indices.push_back(index);
|
|
}
|
|
void Mesh::add_triangle(uint32_t i1, uint32_t i2, uint32_t i3) {
|
|
indices.push_back(i1);
|
|
indices.push_back(i2);
|
|
indices.push_back(i3);
|
|
}
|
|
|
|
void Mesh::clear() {
|
|
vertices.clear();
|
|
normals.clear();
|
|
colors.clear();
|
|
uvs.clear();
|
|
indices.clear();
|
|
}
|
|
|
|
void Mesh::upload() {
|
|
if (vertices.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
if (!VBO) {
|
|
glGenBuffers(1, &VBO);
|
|
}
|
|
|
|
vertices_vbo_size = sizeof(float) * vertices.size();
|
|
normals_vbo_size = sizeof(float) * normals.size();
|
|
colors_vbo_size = sizeof(float) * colors.size();
|
|
uvs_vbo_size = sizeof(float) * uvs.size();
|
|
indices_vbo_size = sizeof(float) * indices.size();
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
glBufferData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size + colors_vbo_size + uvs_vbo_size, NULL, GL_STATIC_DRAW);
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_vbo_size, &vertices[0]);
|
|
|
|
if (normals_vbo_size > 0) {
|
|
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size, normals_vbo_size, &normals[0]);
|
|
}
|
|
|
|
if (colors_vbo_size > 0) {
|
|
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size, colors_vbo_size, &colors[0]);
|
|
}
|
|
|
|
if (uvs_vbo_size > 0) {
|
|
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size + colors_vbo_size, uvs_vbo_size, &uvs[0]);
|
|
}
|
|
|
|
if (indices_vbo_size > 0) {
|
|
if (!IBO) {
|
|
glGenBuffers(1, &IBO);
|
|
}
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_vbo_size, &indices[0], GL_STATIC_DRAW);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
}
|
|
void Mesh::destroy() {
|
|
if (VBO) {
|
|
glDeleteBuffers(1, &VBO);
|
|
VBO = 0;
|
|
}
|
|
|
|
if (IBO) {
|
|
glDeleteBuffers(1, &IBO);
|
|
IBO = 0;
|
|
}
|
|
}
|
|
void Mesh::render() {
|
|
if (vertices.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
if (!Shader::current_shader) {
|
|
return;
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
|
|
glVertexAttribPointer(Shader::ATTRIBUTE_POSITION, vertex_dimesions, GL_FLOAT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(Shader::ATTRIBUTE_POSITION);
|
|
|
|
if (normals_vbo_size > 0) {
|
|
glVertexAttribPointer(Shader::ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertices_vbo_size));
|
|
glEnableVertexAttribArray(Shader::ATTRIBUTE_NORMAL);
|
|
}
|
|
|
|
if (colors_vbo_size > 0) {
|
|
glVertexAttribPointer(Shader::ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_FALSE, 0, (void*)(vertices_vbo_size + normals_vbo_size));
|
|
glEnableVertexAttribArray(Shader::ATTRIBUTE_COLOR);
|
|
}
|
|
|
|
if (uvs_vbo_size > 0) {
|
|
glVertexAttribPointer(Shader::ATTRIBUTE_UV, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertices_vbo_size + normals_vbo_size + colors_vbo_size));
|
|
glEnableVertexAttribArray(Shader::ATTRIBUTE_UV);
|
|
}
|
|
|
|
if (indices_vbo_size > 0) {
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
|
|
|
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (GLvoid*)0);
|
|
} else {
|
|
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
|
}
|
|
|
|
glDisableVertexAttribArray(Shader::ATTRIBUTE_POSITION);
|
|
|
|
if (normals_vbo_size > 0) {
|
|
glDisableVertexAttribArray(Shader::ATTRIBUTE_NORMAL);
|
|
}
|
|
|
|
if (colors_vbo_size > 0) {
|
|
glDisableVertexAttribArray(Shader::ATTRIBUTE_COLOR);
|
|
}
|
|
|
|
if (uvs_vbo_size > 0) {
|
|
glDisableVertexAttribArray(Shader::ATTRIBUTE_UV);
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
Mesh::Mesh() {
|
|
VBO = 0;
|
|
IBO = 0;
|
|
|
|
vertex_dimesions = 3;
|
|
|
|
vertices_vbo_size = 0;
|
|
normals_vbo_size = 0;
|
|
colors_vbo_size = 0;
|
|
uvs_vbo_size = 0;
|
|
indices_vbo_size = 0;
|
|
}
|
|
Mesh::Mesh(int vert_dim) {
|
|
VBO = 0;
|
|
IBO = 0;
|
|
|
|
vertex_dimesions = vert_dim;
|
|
|
|
vertices_vbo_size = 0;
|
|
normals_vbo_size = 0;
|
|
colors_vbo_size = 0;
|
|
uvs_vbo_size = 0;
|
|
indices_vbo_size = 0;
|
|
}
|
|
Mesh::~Mesh() {
|
|
destroy();
|
|
clear();
|
|
}
|