Added mesh
This commit is contained in:
@@ -2,6 +2,7 @@ set(HEADERS
|
|||||||
${HEADERS}
|
${HEADERS}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/colour.h
|
${CMAKE_CURRENT_SOURCE_DIR}/colour.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/fbo.h
|
${CMAKE_CURRENT_SOURCE_DIR}/fbo.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/mesh.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h
|
${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h
|
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/shader.h
|
${CMAKE_CURRENT_SOURCE_DIR}/shader.h
|
||||||
@@ -9,9 +10,11 @@ set(HEADERS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.h
|
${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.h
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
${SOURCE}
|
${SOURCE}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/fbo.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/fbo.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/mesh.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/texture.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/texture.cpp
|
||||||
|
|||||||
+148
@@ -0,0 +1,148 @@
|
|||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
constexpr char *BUFFER_OFFSET(int i) {
|
||||||
|
return (char *) NULL + i * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int componentsInVertex() {
|
||||||
|
return 3 + 3 + 2; // position, normal, uv
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int sizeOfVertexInBytes() {
|
||||||
|
return componentsInVertex() * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh::mesh() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh::~mesh() {
|
||||||
|
if (initialized) {
|
||||||
|
glDeleteVertexArrays(1, &vao_id);
|
||||||
|
glDeleteBuffers(1, &vbo_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mesh::render(bool flat_shaded) {
|
||||||
|
if (!initialized) {
|
||||||
|
glGenVertexArrays(1, &vao_id);
|
||||||
|
glGenBuffers(1, &vbo_id);
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct data
|
||||||
|
if ((facets.size() * 3) > vbo_size_in_elements) {
|
||||||
|
|
||||||
|
if (vbo_data != nullptr)
|
||||||
|
delete[] vbo_data;
|
||||||
|
|
||||||
|
vbo_data = new float[componentsInVertex() * facets.size() * 3];
|
||||||
|
vbo_size_in_elements = facets.size() * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill in buffer
|
||||||
|
int i = 0;
|
||||||
|
for (auto &f: facets) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
vbo_data[i++] = vertices[f.vertices[j]].position.x;
|
||||||
|
vbo_data[i++] = vertices[f.vertices[j]].position.y;
|
||||||
|
vbo_data[i++] = vertices[f.vertices[j]].position.z;
|
||||||
|
if (flat_shaded) {
|
||||||
|
vbo_data[i++] = f.normal.x;
|
||||||
|
vbo_data[i++] = f.normal.y;
|
||||||
|
vbo_data[i++] = f.normal.z;
|
||||||
|
} else {
|
||||||
|
vbo_data[i++] = vertices[f.vertices[j]].normal.x;
|
||||||
|
vbo_data[i++] = vertices[f.vertices[j]].normal.y;
|
||||||
|
vbo_data[i++] = vertices[f.vertices[j]].normal.z;
|
||||||
|
}
|
||||||
|
vbo_data[i++] = f.text_coords[j].x;
|
||||||
|
vbo_data[i++] = f.text_coords[j].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(vao_id);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeOfVertexInBytes() * facets.size() * 3, vbo_data, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0); // vertices on stream 0
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeOfVertexInBytes(), BUFFER_OFFSET(0));
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(1); // normals on stream 1
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeOfVertexInBytes(), BUFFER_OFFSET(3));
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(2); // text coords on stream 2
|
||||||
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeOfVertexInBytes(), BUFFER_OFFSET(6));
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, facets.size() * 3);
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(2);
|
||||||
|
glDisableVertexAttribArray(1);
|
||||||
|
glDisableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mesh::merge(mesh &mesh) {
|
||||||
|
vertices.reserve(vertices.size() + mesh.vertices.size());
|
||||||
|
vertices.insert(vertices.end(), mesh.vertices.begin(), mesh.vertices.end());
|
||||||
|
|
||||||
|
auto original_facet_count = facets.size();
|
||||||
|
facets.reserve(facets.size() + mesh.facets.size());
|
||||||
|
for (auto &f: mesh.facets) {
|
||||||
|
facet new_f = f;
|
||||||
|
new_f.a += original_facet_count;
|
||||||
|
new_f.b += original_facet_count;
|
||||||
|
new_f.c += original_facet_count;
|
||||||
|
facets.push_back(new_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t original_edge_count = edges.size();
|
||||||
|
edges.reserve(edges.size() + mesh.edges.size());
|
||||||
|
for (auto &e: mesh.edges) {
|
||||||
|
edge new_edge = e;
|
||||||
|
new_edge.from += original_edge_count;
|
||||||
|
new_edge.to += original_edge_count;
|
||||||
|
edges.push_back(new_edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mesh::copy(mesh &mesh) {
|
||||||
|
vertices = mesh.vertices;
|
||||||
|
facets = mesh.facets;
|
||||||
|
edges = mesh.edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculate_normals(mesh &mesh) {
|
||||||
|
for (auto &vertex: mesh.vertices)
|
||||||
|
vertex.normal = glm::vec3(0);
|
||||||
|
|
||||||
|
for (auto &facet: mesh.facets) {
|
||||||
|
glm::vec3 a = mesh.vertices[facet.b].position - mesh.vertices[facet.a].position;
|
||||||
|
glm::vec3 b = mesh.vertices[facet.c].position - mesh.vertices[facet.a].position;
|
||||||
|
facet.normal = cross(a, b);
|
||||||
|
if (length(facet.normal) > 0.00001) {
|
||||||
|
facet.normal = normalize(facet.normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.vertices[facet.a].normal += facet.normal;
|
||||||
|
mesh.vertices[facet.b].normal += facet.normal;
|
||||||
|
mesh.vertices[facet.c].normal += facet.normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &vertex: mesh.vertices)
|
||||||
|
vertex.normal = normalize(vertex.normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flip_normals(mesh &mesh) {
|
||||||
|
for (auto &vertex: mesh.vertices)
|
||||||
|
vertex.normal = -vertex.normal;
|
||||||
|
|
||||||
|
for (auto &facet: mesh.facets)
|
||||||
|
facet.normal = -facet.normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
struct vertex {
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct facet {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
size_t a, b, c;
|
||||||
|
};
|
||||||
|
size_t vertices[3];
|
||||||
|
};
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec2 text_coords[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct edge {
|
||||||
|
size_t from;
|
||||||
|
size_t to;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mesh {
|
||||||
|
mesh();
|
||||||
|
~mesh();
|
||||||
|
|
||||||
|
std::vector<vertex> vertices;
|
||||||
|
std::vector<facet> facets;
|
||||||
|
std::vector<edge> edges;
|
||||||
|
|
||||||
|
void render(bool flat_shaded);
|
||||||
|
void merge(mesh &mesh);
|
||||||
|
void copy(mesh &mesh);
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
GLuint vbo_id = 0;
|
||||||
|
GLuint vao_id = 0;
|
||||||
|
float *vbo_data = nullptr;
|
||||||
|
int vbo_size_in_elements = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void calculate_normals(mesh & mesh);
|
||||||
|
void flip_normals(mesh & mesh);
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
+3
-5
@@ -1,7 +1,5 @@
|
|||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
BEGIN_NAMESPACE
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
@@ -68,10 +66,10 @@ void shader::unuse() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int shader::getUniform(const char *uniformName) {
|
int shader::getUniform(const char *uniformName) {
|
||||||
if (uniformCache.count(uniformName) == 0) {
|
if (uniform_cache.count(uniformName) == 0) {
|
||||||
uniformCache[uniformName] = glGetUniformLocation(program_id, uniformName);
|
uniform_cache[uniformName] = glGetUniformLocation(program_id, uniformName);
|
||||||
}
|
}
|
||||||
return uniformCache[uniformName];
|
return uniform_cache[uniformName];
|
||||||
}
|
}
|
||||||
|
|
||||||
void shader::setMatrix3Uniform(float *matrix, const char *uniformName) {
|
void shader::setMatrix3Uniform(float *matrix, const char *uniformName) {
|
||||||
|
|||||||
+1
-2
@@ -7,7 +7,6 @@ BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class shader {
|
class shader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
shader(const char *vs_content, const char *ps_content);
|
shader(const char *vs_content, const char *ps_content);
|
||||||
virtual ~shader();
|
virtual ~shader();
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
GLuint program_id;
|
GLuint program_id;
|
||||||
GLuint shader_ids[2];
|
GLuint shader_ids[2];
|
||||||
std::map<const char *, int> uniformCache;
|
std::map<const char *, int> uniform_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user