- Vertex Class with Pos, Normal, and TexCoord attributes

- BlockModel class that contains vector of MeshParts
- MeshPart class that contains Vertices and Indices
- MeshVertexIter & MeshIndexIter classes for MeshPart
master
aurailus 2018-12-05 20:10:16 -08:00
parent 629c44c775
commit aa837305ce
13 changed files with 467 additions and 42 deletions

View File

@ -29,14 +29,19 @@ add_executable(GlProject
GlProject/engine/graphics/Texture.h
GlProject/mesh/MeshGenerator.cpp
GlProject/mesh/MeshGenerator.h
GlProject/mesh/MeshData.cpp
GlProject/mesh/MeshData.h
GlProject/engine/Timer.cpp
GlProject/engine/Timer.h
GlProject/blocks/BlockAtlas.cpp
GlProject/blocks/BlockAtlas.h
GlProject/blocks/BlockDef.cpp
GlProject/blocks/BlockDef.h)
GlProject/blocks/BlockDef.h
GlProject/mesh/MeshPart.cpp
GlProject/mesh/MeshPart.h
GlProject/mesh/MeshMod.h
GlProject/mesh/Vertex.cpp
GlProject/mesh/Vertex.h
GlProject/mesh/BlockModel.cpp
GlProject/mesh/BlockModel.h)
target_link_libraries(GlProject
${OPENGL_gl_LIBRARY}

View File

@ -12,14 +12,12 @@
#include <gtc/type_ptr.hpp>
#include "engine/Window.h"
#include "engine/graphics/Mesh.h"
#include "engine/Entity.h"
#include "engine/graphics/Shader.h"
#include "engine/Camera.h"
#include "engine/graphics/Texture.h"
#include "mesh/MeshData.h"
#include "mesh/BlockModel.h"
#include "engine/graphics/Shader.h"
#include "mesh/MeshGenerator.h"
#include "engine/Timer.h"
#include "engine/Entity.h"
Window* window;
Shader* shader;
@ -32,7 +30,23 @@ Texture* dirtTexture;
GLfloat deltaTime = 0.0f;
GLfloat lastTime = 0.0f;
void makeEntities() {
BlockModel createBlockModel() {
Vertex* topVerts = new Vertex[4] {
Vertex(new glm::vec3(0.0f, 1.0f, 0.0f), nullptr, new glm::vec2(0.0f, 0.0f)),
Vertex(new glm::vec3(0.0f, 1.0f, 1.0f), nullptr, new glm::vec2(0.0f, 1.0f)),
Vertex(new glm::vec3(1.0f, 1.0f, 1.0f), nullptr, new glm::vec2(1.0f, 1.0f)),
Vertex(new glm::vec3(1.0f, 1.0f, 0.0f), nullptr, new glm::vec2(0.0f, 1.0f)),
};
auto* topInds = new unsigned int[6] {
0, 1, 2, 2, 3, 0
};
auto* topPart = new MeshPart(topVerts, 4, topInds, 6, "dirt");
return BlockModel(nullptr, nullptr, topPart, nullptr, nullptr, nullptr, nullptr, true, true);
}
void makeEntities(BlockModel model) {
int array[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
for (int i = 0; i < CHUNK_SIZE; i++) {
@ -44,11 +58,12 @@ void makeEntities() {
}
auto meshGen = new MeshGenerator();
MeshData *m = meshGen->build(array);
MeshData *m = meshGen->build(array, &model);
delete meshGen;
Mesh* mesh = new Mesh();
mesh->create(&m->vertices[0], &m->indices[0], (int)m->vertices.size(), (int)m->indices.size());
for (int i = -16; i < 16; i++) {
for (int j = -16; j < 16; j++) {
auto *chunk = new Entity();
@ -75,8 +90,14 @@ int main() {
dirtTexture = new Texture((char*)"../Textures/default_dirt.png");
dirtTexture->load();
//Create model
BlockModel model = createBlockModel();
auto* mesh = model.topFaces[0];
mesh->debug();
//Create entities
makeEntities();
// makeEntities(model);
//Create shader
shader = new Shader();

View File

@ -0,0 +1,86 @@
//
// Created by aurailus on 04/12/18.
//
#include <utility>
#include "BlockModel.h"
BlockModel::BlockModel(bool culls, bool visible) {
this->nullModel = true;
this->culls = culls;
this->visible = visible;
}
BlockModel::BlockModel(vector<MeshPart*> leftFaces, vector<MeshPart*> rightFaces, vector<MeshPart*> topFaces,
vector<MeshPart*> bottomFaces, vector<MeshPart*> frontFaces, vector<MeshPart*> backFaces,
vector<MeshPart*> noCulledFaces, bool culls, bool visible) {
this->leftFaces = std::move(leftFaces);
this->rightFaces = std::move(rightFaces);
this->topFaces = std::move(topFaces);
this->bottomFaces = std::move(bottomFaces);
this->frontFaces = std::move(frontFaces);
this->backFaces = std::move(backFaces);
this->noCulledFaces = std::move(noCulledFaces);
this->culls = culls;
this->visible = visible;
}
BlockModel::BlockModel(MeshPart* leftFace, MeshPart* rightFace, MeshPart* topFace, MeshPart* bottomFace,
MeshPart* frontFace, MeshPart* backFace, MeshPart* noCulledFace, bool culls, bool visible) {
this->leftFaces = vector<MeshPart*>();
if (leftFace != nullptr)
this->leftFaces.push_back(leftFace);
this->rightFaces = vector<MeshPart*>();
if (rightFace != nullptr)
this->rightFaces.push_back(rightFace);
this->topFaces = vector<MeshPart*>();
if (topFace != nullptr)
this->topFaces.push_back(topFace);
this->bottomFaces = vector<MeshPart*>();
if (bottomFace != nullptr)
this->bottomFaces.push_back(bottomFace);
this->backFaces = vector<MeshPart*>();
if (backFace != nullptr)
this->backFaces.push_back(backFace);
this->frontFaces = vector<MeshPart*>();
if (frontFace != nullptr)
this->frontFaces.push_back(frontFace);
this->noCulledFaces = vector<MeshPart*>();
if (noCulledFace != nullptr)
this->noCulledFaces.push_back(noCulledFace);
this->culls = culls;
this->visible = visible;
}
BlockModel::~BlockModel() {
for (MeshPart* m : leftFaces) { delete m; }
leftFaces.clear();
for (MeshPart* m : rightFaces) { delete m; }
rightFaces.clear();
for (MeshPart* m : topFaces) { delete m; }
topFaces.clear();
for (MeshPart* m : bottomFaces) { delete m; }
bottomFaces.clear();
for (MeshPart* m : frontFaces) { delete m; }
frontFaces.clear();
for (MeshPart* m : backFaces) { delete m; }
backFaces.clear();
for (MeshPart* m : noCulledFaces) { delete m; }
noCulledFaces.clear();
}

View File

@ -0,0 +1,33 @@
//
// Created by aurailus on 04/12/18.
//
#ifndef GLPROJECT_BLOCKMODEL_H
#define GLPROJECT_BLOCKMODEL_H
#include <vector>
#include "MeshPart.h"
using namespace std; //Just to preserve my sanity
struct BlockModel {
public:
//MeshPart Vectors for each face. The vector may be empty but it may not contain null pointers.
vector<MeshPart*> leftFaces, rightFaces, topFaces, bottomFaces, frontFaces, backFaces, noCulledFaces;
bool culls, visible, nullModel;
BlockModel(bool culls, bool visible);
BlockModel(vector<MeshPart*> leftFaces, vector<MeshPart*> rightFaces, vector<MeshPart*> topFaces,
vector<MeshPart*> bottomFaces, vector<MeshPart*> frontFaces, vector<MeshPart*> backFaces,
vector<MeshPart*> noCulledFaces, bool culls, bool visible);
BlockModel(MeshPart* leftFace, MeshPart* rightFace, MeshPart* topFace, MeshPart* bottomFace, MeshPart* frontFace,
MeshPart* backFace, MeshPart* noCulledFace, bool culls, bool visible);
~BlockModel();
};
#endif //GLPROJECT_BLOCKMODEL_H

View File

@ -1,5 +0,0 @@
//
// Created by aurailus on 01/12/18.
//
#include "MeshData.h"

View File

@ -1,16 +0,0 @@
//
// Created by aurailus on 01/12/18.
//
#ifndef GLPROJECT_MESHDATA_H
#define GLPROJECT_MESHDATA_H
#include <vector>
struct MeshData {
std::vector<float> vertices;
std::vector<unsigned int> indices;
};
#endif //GLPROJECT_MESHDATA_H

View File

@ -12,7 +12,7 @@ MeshGenerator::MeshGenerator() {
indOffset = 0;
}
MeshData* MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE]) {
MeshData* MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE], BlockModel* model) {
auto t = Timer("MeshGen");
vertices->reserve(32768);
@ -22,14 +22,16 @@ MeshData* MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE]) {
for (int j = 0; j < CHUNK_SIZE; j++) {
for (int k = 0; k < CHUNK_SIZE; k++) {
if (blocks[i][j][k] == 1) {
add_top_face(&k, &j, &i);
add_bottom_face(&k, &j, &i);
addBlockModel(&k, &j, &i, model);
add_front_face(&k, &j, &i);
add_back_face(&k, &j, &i);
add_left_face(&k, &j, &i);
add_right_face(&k, &j, &i);
// add_top_face(&k, &j, &i);
// add_bottom_face(&k, &j, &i);
//
// add_front_face(&k, &j, &i);
// add_back_face(&k, &j, &i);
//
// add_left_face(&k, &j, &i);
// add_right_face(&k, &j, &i);
}
}
}
@ -47,6 +49,25 @@ MeshData* MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE]) {
return m;
}
void MeshGenerator::addBlockModel(int* x, int* y, int* z, BlockModel* model) {
MeshVertexIter* iter = model->topFaces[0]->getVertexIterator();
while (iter->hasNext()) {
Vertex* vertex = iter->next();
vertices->push_back(vertex->pos->x + *x);
vertices->push_back(vertex->pos->y + *y);
vertices->push_back(vertex->pos->z + *z);
vertices->push_back(vertex->tex->x);
vertices->push_back(vertex->tex->y);
vertices->push_back(0);
vertices->push_back(0);
vertices->push_back(0);
}
}
void MeshGenerator::add_vertices(std::vector<float> *verts, std::vector<unsigned int> *inds, int *x, int *y, int *z) {
//How many values there are per vertex
const unsigned int VERT_SIZE = 5;

View File

@ -7,22 +7,26 @@
#define GLM_ENABLE_EXPERIMENTAL
#include "MeshData.h"
#include "BlockModel.h"
#include <vector>
#include <gtx/normal.hpp>
const int CHUNK_SIZE = 16;
struct MeshData;
class MeshGenerator {
public:
MeshGenerator();
MeshData* build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE]);
MeshData* build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE], BlockModel* model);
~MeshGenerator();
private:
std::vector<float>* vertices;
std::vector<unsigned int>* indices;
unsigned int indOffset;
void addBlockModel(int* x, int* y, int* z, BlockModel* model);
void add_vertices(std::vector<float> *verts, std::vector<unsigned int> *inds, int *x, int *y, int *z);
void add_top_face(int *x, int *y, int *z);
@ -37,5 +41,9 @@ private:
void cleanup();
};
struct MeshData {
std::vector<float> vertices;
std::vector<unsigned int> indices;
};
#endif //GLPROJECT_MESHGENERATOR_H

13
GlProject/mesh/MeshMod.h Normal file
View File

@ -0,0 +1,13 @@
//
// Created by aurailus on 02/12/18.
//
#ifndef GLPROJECT_MESHMOD_H
#define GLPROJECT_MESHMOD_H
enum MeshMod {
NONE,
SHIFT,
};
#endif //GLPROJECT_MESHMOD_H

147
GlProject/mesh/MeshPart.cpp Normal file
View File

@ -0,0 +1,147 @@
//
// Created by aurailus on 02/12/18.
//
#include <iostream>
#include "MeshPart.h"
MeshPart::MeshPart(Vertex* vertices, int vSize, unsigned int* indices, int iSize, const char* texture, MeshMod meshMod, float modValue) {
construct(vertices, vSize, indices, iSize, texture, meshMod, modValue);
}
MeshPart::MeshPart(Vertex* vertices, int vSize, unsigned int* indices, int iSize, const char* texture) {
construct(vertices, vSize, indices, iSize, texture, NONE, 0);
}
//Add normals and compute tex coordinates for the given Vertex array.
void MeshPart::construct(Vertex* vertices, int vSize, unsigned int *indices, int iSize, const char *texture, MeshMod meshMod, float modValue) {
//Set the meshMod and modValue variables on the MeshPart
this->meshMod = meshMod;
this->modValue = modValue;
//These vertex structs do (should) not have normals, so we will generate them here from the triangle information
//To do this, we have to assume that each group of 3 indices is a triangle (which it would be hard for it to not be)
//and that no vertexes are shared on corners or places where vectors should be interpolated.
Vertex *p1, *p2, *p3;
glm::vec3 nml;
//Iterate through the indices to find all used vertices to add normals and adjust texture coordinates.
for (int i = 0; i < iSize/3; i++) {
//Get the three vertices
p1 = &vertices[indices[i*3]];
p2 = &vertices[indices[i*3] + 1];
p3 = &vertices[indices[i*3] + 2];
//Get the normal of the formed triangle
// nml = glm::triangleNormal(*p1->pos, *p2->pos, *p3->pos); //TODO: do this right
auto* normal = new glm::vec3(nml.x, nml.y, nml.z);
//Set the normal on the vertices
p1->nml = normal;
p2->nml = normal;
p3->nml = normal;
//TODO: get the tex dimensions from the texture atlas here
glm::vec4 texBase = glm::vec4(0, 0, 1, 1);
glm::vec2 texWidth = glm::vec2(texBase.x - texBase.z, texBase.y - texBase.w);
//Adjust the texture coordinates to be relative to the texture requested.
//TODO: implement this aaaa
}
//Assign the inputted values to the struct
this->vertices = vertices;
this->vSize = vSize;
this->indices = indices;
this->iSize = iSize;
}
int MeshPart::getVertexCount() {
return vSize;
}
Vertex* MeshPart::getVertex(int index) {
return &vertices[index];
}
int MeshPart::getIndexCount() {
return iSize;
}
unsigned int MeshPart::getIndex(int index) {
return indices[index];
}
MeshVertexIter* MeshPart::getVertexIterator() {
return new MeshVertexIter(this);
}
MeshIndexIter* MeshPart::getIndexIterator() {
return new MeshIndexIter(this);
}
void MeshPart::debug() {
std::cout << "Debugging MeshPart" << std::endl << "Vertices:" << std::endl;
auto* vI = getVertexIterator();
while (vI->hasNext()) {
Vertex* v = vI->next();
std::cout << v->pos->x << ", " << v->pos->y << ", " << v->pos->z << std::endl;
}
auto* iI = getIndexIterator();
bool first = true;
std::cout << "Indices:" << std::endl;
while (iI->hasNext()) {
if (!first) {
std::cout << ", ";
}
else first = false;
std::cout << iI->next();
}
std::cout << std::endl;
std::cout << "----------" << std::endl;
}
//Mesh Vertex Iterator
//Iterator to get the vertices of the MeshPart as a stream.
MeshVertexIter::MeshVertexIter(MeshPart* meshPart) {
this->meshPart = meshPart;
this->index = 0;
}
bool MeshVertexIter::hasNext() {
return (index < this->meshPart->getVertexCount());
}
Vertex* MeshVertexIter::next() {
if (hasNext()) return this->meshPart->getVertex(index++);
}
//Mesh Index Iterator
//Iterator to get the indices of the MeshPart as a stream
MeshIndexIter::MeshIndexIter(MeshPart *meshPart) {
this->meshPart = meshPart;
this->index = 0;
}
bool MeshIndexIter::hasNext() {
return (index < this->meshPart->getIndexCount());
}
unsigned int MeshIndexIter::next() {
if (hasNext()) return this->meshPart->getIndex(index++);
}

71
GlProject/mesh/MeshPart.h Normal file
View File

@ -0,0 +1,71 @@
//
// Created by aurailus on 02/12/18.
//
#ifndef GLPROJECT_MESHPART_H
#define GLPROJECT_MESHPART_H
#define GLM_ENABLE_EXPERIMENTAL
#include <vec4.hpp>
#include <gtx/normal.hpp>
#include "MeshMod.h"
#include "Vertex.h"
class MeshVertexIter;
class MeshIndexIter;
struct MeshPart {
public:
MeshPart(Vertex* vertices, int vSize, unsigned int* indices, int iSize, const char* texture, MeshMod meshMod, float modValue);
MeshPart(Vertex* vertices, int vSize, unsigned int* indices, int iSize, const char* texture);
int getVertexCount();
Vertex* getVertex(int index);
int getIndexCount();
unsigned int getIndex(int index);
MeshVertexIter* getVertexIterator();
MeshIndexIter* getIndexIterator();
void debug();
private:
void construct(Vertex* vertices, int vSize, unsigned int* indices, int iSize, const char* texture, MeshMod meshMod, float modValue);
//TODO: Free these values from memory
float modValue;
Vertex* vertices;
int vSize;
unsigned int* indices;
int iSize;
const char* texture;
MeshMod meshMod;
};
class MeshVertexIter {
public:
explicit MeshVertexIter(MeshPart* meshPart);
bool hasNext();
Vertex* next();
private:
int index;
MeshPart* meshPart;
};
class MeshIndexIter {
public:
explicit MeshIndexIter(MeshPart* meshPart);
bool hasNext();
unsigned int next();
private:
int index;
MeshPart* meshPart;
};
#endif //GLPROJECT_MESHPART_H

18
GlProject/mesh/Vertex.cpp Normal file
View File

@ -0,0 +1,18 @@
//
// Created by aurailus on 02/12/18.
//
#include "Vertex.h"
Vertex::Vertex(glm::vec3* pos, glm::vec3* nml, glm::vec2* tex) {
this->pos = pos;
this->nml = nml;
this->tex = tex;
}
Vertex::~Vertex() {
delete pos;
delete nml;
delete tex;
}

23
GlProject/mesh/Vertex.h Normal file
View File

@ -0,0 +1,23 @@
//
// Created by aurailus on 02/12/18.
//
#ifndef GLPROJECT_VERTEX_H
#define GLPROJECT_VERTEX_H
#include <vec3.hpp>
#include <vec2.hpp>
struct Vertex {
public:
Vertex(glm::vec3* pos, glm::vec3* nml, glm::vec2* tex);
glm::vec3* pos;
glm::vec3* nml;
glm::vec2* tex;
~Vertex();
};
#endif //GLPROJECT_VERTEX_H