gltest/src/GLObjects/Mesh.cpp
2018-01-30 19:47:36 +03:00

94 lines
2.8 KiB
C++

#include "Mesh.h"
#include <glm/gtc/type_ptr.hpp>
#include <glm/vec3.hpp>
#include <iostream>
Mesh::Mesh(ShaderProgram* shader, std::size_t size) : GLObject(shader), _size(size), _xs(size), _ys(size), _normals(2*size*size) {
_vertexCount = _size*_size;
_indexCount = (_size - 1)*(_size - 1)*6;
_vertices = std::make_unique<Vertex[]>(_vertexCount);
_indices = std::make_unique<GLuint[]>(_indexCount);
}
Mesh::~Mesh() {
}
void Mesh::generateVertices() const {
for(std::size_t j = 0; j < _size; ++j) {
for (std::size_t i = 0; i < _size; ++i) {
size_t idx = j*_size + i;
_vertices[idx].x = (float)i/_size - 0.5f;
_vertices[idx].y = (float)j/_size - 0.5f;
_vertices[idx].z = 0.f;
_vertices[idx].nx = 0.f;
_vertices[idx].ny = 0.f;
_vertices[idx].nz = 0.f;
}
}
}
inline size_t Mesh::normalIndex(size_t x, size_t y) {
return 2*(x + y*_size);
}
void Mesh::updateVertices() const {
for(std::size_t j = 0; j < _size; ++j) {
for(std::size_t i = 0; i < _size; ++i) {
std::size_t idx = j*_size + i;
_vertices[idx].z = heightMap(i, j);
}
}
// 1. Calc normals for all triangles
_normals.clear();
for(std::size_t j = 0; j < _size; ++j) {
for(std::size_t i = 0; i < _size; ++i) {
float x = _xs[i], x2 = _xs[i + 1];
float y = _ys[j], y2 = _ys[j + 1];
glm::vec3 p1(x, y, _vertices[j*(_size - 1) + i].z);
glm::vec3 p2(x2, y, _vertices[j*(_size - 1) + i + 1].z);
glm::vec3 p3(x, y2, _vertices[(j + 1)*(_size - 1) + i].z);
glm::vec3 p4(x2, y2, _vertices[(j + 1)*(_size - 1) + i + 1].z);
glm::vec3 v1 = p1 - p3;
glm::vec3 v2 = p2 - p3;
glm::vec3 v3 = p4 - p3;
glm::vec3 norm1 = glm::cross(v2, v1);
glm::vec3 norm2 = glm::cross(v3, v2);
_normals.emplace_back(norm1);
_normals.emplace_back(norm2);
}
}
// 2. Calc normals for all vertices based on precalculated normals for triangles
// Normal of vertex is an average of normals of adjacent triangles
for(std::size_t j = 0; j < _size; ++j) {
for (std::size_t i = 0; i < _size; ++i) {
size_t idx1 = normalIndex(i - 1, j - 1);
size_t idx2 = normalIndex(i - 1, j);
}
}
}
void Mesh::generateIndices() const {
GLuint u = (GLuint)_size, v = (GLuint)_size;
for (unsigned i = 0; i < (u - 1); i++)
for (unsigned j = 0; j < (v - 1); j++)
{
GLuint indexa = j*(u - 1) + i;
GLuint indexb = j*u + i;
_indices[indexa*6 + 0] = indexb;
_indices[indexa*6 + 1] = indexb + 1 + u;
_indices[indexa*6 + 2] = indexb + 1;
_indices[indexa*6 + 3] = indexb;
_indices[indexa*6 + 4] = indexb + u;
_indices[indexa*6 + 5] = indexb + u + 1;
}
}