Browse Source

packed geometry mesher

testing
totallyfake 2 years ago
parent
commit
b679541d0b

+ 5
- 0
include/graphics/chunkmesh.h View File

@@ -4,6 +4,8 @@
#include <glm/glm.hpp>
#include <vector>

#include "graphics/voxelmodel.h"

namespace vtk {
class World;

@@ -25,13 +27,16 @@ protected:

std::vector<float> geometry;
std::vector<unsigned> mGeometry;
std::vector<unsigned> mFaceAttribs;
bool mLocked;
bool mUpdated;
unsigned mVAO;
unsigned mGeometryTexVBO;
unsigned mLightVBO;
unsigned mFaceAttribsVBO;
int mFaceCount;
int mGeometryFaceCount;
VoxelModel mVoxelModel;
};
}

+ 22
- 0
include/graphics/voxelmodel.h View File

@@ -0,0 +1,22 @@
#pragma once

#include <vector>
#include <array>

namespace vtk {

class VoxelModel {
public:
VoxelModel();
virtual ~VoxelModel();

// accepts values between 0 and 15 to be packed into the geometry of face
bool packDataIntoFace(const std::vector<unsigned>& data, const int& face);
bool uploadFaceToMesh(std::vector<unsigned>& mesh, const int& face);
std::vector<unsigned>& getFaceMesh(const int& face);
protected:
// top bottom north south east west
std::array<std::vector<unsigned>, 7> mGeometry;
};

} //namespace vtk

+ 2
- 2
res/shaders/voxelfrag.frag.glsl View File

@@ -24,8 +24,8 @@ float getFogFactor(float fogCoord) {
void main() {
//fog calculations

//vec4 texel = texture2DArray(texture, texCoordInterp);
outColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); //texel; //* vec4(lightDataInterp, 1.0f);
vec4 texel = texture2DArray(texture, texCoordInterp);
outColor = texel; //* vec4(lightDataInterp, 1.0f);

float fogCoord = abs(eyeSpacePos.z/eyeSpacePos.w);
outColor = mix(outColor, fogColor, getFogFactor(fogCoord));

+ 16
- 4
res/shaders/voxelvert.vert.glsl View File

@@ -3,6 +3,7 @@
layout(location = 0) in uint position;
//layout(location = 0) in vec3 position;
//layout(location = 1) in vec3 texCoord;
layout(location = 1) in uint face_attrib;

uniform mat4 proj, view, model; //transform matrix

@@ -12,12 +13,23 @@ out vec4 eyeSpacePos;

void main() {
vec3 pos_unpacked;
pos_unpacked.x = float((position ) & 15u) / 15.0f;
pos_unpacked.x = float((position >> 8u) & 15u) / 15.0f;
pos_unpacked.y = float((position >> 4u) & 15u) / 15.0f;
pos_unpacked.z = float((position >> 8u) & 15u) / 15.0f;
vec4 eyeSpacePosVert = view * model * vec4(pos_unpacked, 1.0);
pos_unpacked.z = float((position) & 15u) / 15.0f;

vec2 uv_unpacked;
uv_unpacked.x = float((position >> 16u) & 15u) / 15.0f;
uv_unpacked.y = float((position >> 12u) & 15u) / 15.0f;

vec3 offset_unpacked;
offset_unpacked.x = float((face_attrib >> 10u) & 31u);
offset_unpacked.y = float((face_attrib >> 5u) & 31u);
offset_unpacked.z = float((face_attrib) & 31u);

vec3 final_position = pos_unpacked + offset_unpacked;
vec4 eyeSpacePosVert = view * model * vec4(final_position, 1.0);
gl_Position = proj * eyeSpacePosVert;
texCoordInterp = vec3(1.0f, 1.0f, 1.0f);//texCoord;
texCoordInterp = vec3(uv_unpacked, 0.0f);//texCoord;
lightDataInterp = vec3(1.0f, 1.0f, 1.0f);
eyeSpacePos = eyeSpacePosVert;
}

+ 37
- 37
src/graphics/chunkmesh.cpp View File

@@ -19,6 +19,7 @@ ChunkMesh::ChunkMesh(World& world, glm::ivec3 chunkPos) :
{
glGenBuffers(1, &mGeometryTexVBO);
glGenBuffers(1, &mLightVBO);
glGenBuffers(1, &mFaceAttribsVBO);

glGenVertexArrays(1, &mVAO);

@@ -26,11 +27,17 @@ ChunkMesh::ChunkMesh(World& world, glm::ivec3 chunkPos) :

glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);


//vertices
glVertexAttribPointer(0, 1, GL_UNSIGNED_INT, GL_FALSE, 0, NULL);
glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, GL_FALSE, 0);
glEnableVertexAttribArray(0);


//face attribs
glBindBuffer(GL_ARRAY_BUFFER, mFaceAttribsVBO);

glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, GL_FALSE, 0);
glEnableVertexAttribArray(1);

//tex uv coords
//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 4*sizeof(unsigned), (void*)(1*sizeof(unsigned)));
//glEnableVertexAttribArray(1);
@@ -41,35 +48,6 @@ void ChunkMesh::rebuildChunkGeometry() {
mLocked = true;
//get the chunk from position
auto chunk = mLinkedWorld.getChunk(mLinkedChunkPos);

unsigned uTopModel [] = { 0,0,0,0,0,0 };
//single vertex
uTopModel[0] = (uTopModel[0] << 4) | unsigned(0);
uTopModel[0] = (uTopModel[0] << 4) | unsigned(15);
uTopModel[0] = (uTopModel[0] << 4) | unsigned(0);

uTopModel[1] = (uTopModel[1] << 4) | unsigned(15);
uTopModel[1] = (uTopModel[1] << 4) | unsigned(15);
uTopModel[1] = (uTopModel[1] << 4) | unsigned(0);

uTopModel[2] = (uTopModel[2] << 4) | unsigned(0);
uTopModel[2] = (uTopModel[2] << 4) | unsigned(15);
uTopModel[2] = (uTopModel[2] << 4) | unsigned(15);

uTopModel[3] = (uTopModel[3] << 4) | unsigned(15);
uTopModel[3] = (uTopModel[3] << 4) | unsigned(15);
uTopModel[3] = (uTopModel[3] << 4) | unsigned(15);

uTopModel[4] = (uTopModel[4] << 4) | unsigned(0);
uTopModel[4] = (uTopModel[4] << 4) | unsigned(15);
uTopModel[4] = (uTopModel[4] << 4) | unsigned(15);

uTopModel[5] = (uTopModel[5] << 4) | unsigned(15);
uTopModel[5] = (uTopModel[5] << 4) | unsigned(15);
uTopModel[5] = (uTopModel[5] << 4) | unsigned(0);
//unsigned((uTopModel[0] >> 8)&((1<<4)-1)); extract x, y ,z
//unsigned((uTopModel[0] >> 4)&((1<<4)-1));
//unsigned((uTopModel[0] >> 0)&((1<<4)-1));
//temporary until I finish mesh providers
float texUV [] = {
@@ -134,9 +112,11 @@ void ChunkMesh::rebuildChunkGeometry() {
0.0f, 0.0f, 0.0f, //bl
0.0f, 1.0f, 1.0f //tr
};
// geometry format: x,y,z,u,v,i
geometry.clear();
mGeometry.clear();
mFaceAttribs.clear();
mFaceCount = 0;
int chunkSize = 16; // TODO: make this not hardcoded

@@ -145,12 +125,30 @@ void ChunkMesh::rebuildChunkGeometry() {
for (int j = 0; j < chunkSize; ++j) {
for (int k = 0; k < chunkSize; ++k) {
if (chunk->isVoxelSolid(i,j,k)) {
if (!chunk->isVoxelSolid(i,j+1,k)) {

//build face attrib
// 0b00000000000000000xxxxxyyyyyzzzzz
unsigned faceAttrib = 0;
faceAttrib = faceAttrib | i;
faceAttrib = (faceAttrib << 5) | j;
faceAttrib = (faceAttrib << 5) | k;

//lambda expression for adding vertices
auto addFaceModel = [&](int faceIndex) {
auto mesh = mVoxelModel.getFaceMesh(faceIndex);
++mFaceCount;
for (int l = 0; l < 6; ++l) {
mGeometry.push_back(uTopModel[l]);
mGeometry.push_back(mesh[l]);
mFaceAttribs.push_back(faceAttrib);
}
}
};

if (!chunk->isVoxelSolid(i,j+1,k)) addFaceModel(0); // T
if (!chunk->isVoxelSolid(i,j-1,k)) addFaceModel(1); // B
if (!chunk->isVoxelSolid(i,j,k+1)) addFaceModel(2); // N
if (!chunk->isVoxelSolid(i,j,k-1)) addFaceModel(3); // S
if (!chunk->isVoxelSolid(i+1,j,k)) addFaceModel(4); // E
if (!chunk->isVoxelSolid(i-1,j,k)) addFaceModel(5); // W
}
}
}
@@ -253,7 +251,6 @@ void ChunkMesh::rebuildChunkGeometry() {
}
}
*/
std::cout << mGeometry[1];
mUpdated = true;
mLocked = false;
}
@@ -275,7 +272,10 @@ bool ChunkMesh::updateGeometry() {
mUpdated = false;
glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float) * geometry.size(), geometry.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * mGeometry.size(), mGeometry.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned) * mGeometry.size(), mGeometry.data(), GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, mFaceAttribsVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned) * mFaceAttribs.size(), mFaceAttribs.data(), GL_STATIC_DRAW);
mGeometryFaceCount = mFaceCount;
return true;
}

+ 105
- 0
src/graphics/voxelmodel.cpp View File

@@ -0,0 +1,105 @@
#include <iostream>
#include "graphics/voxelmodel.h"

namespace vtk {

VoxelModel::VoxelModel() {
//placeholder, just build a cube
std::vector<unsigned> top = {
0, 15, 0, 15, 0,
15, 15, 15, 15, 0,
0, 0, 0, 15, 15,
15, 0, 15, 15, 15,
0, 0, 0, 15, 15,
15, 15, 15, 15, 0
};
packDataIntoFace(top, 0);

std::vector<unsigned> bottom = {
0, 15, 0, 0, 15,
15, 15, 15, 0, 15,
0, 0, 0, 0, 0,
15, 0, 15, 0, 0,
0, 0, 0, 0, 0,
15, 15, 15, 0, 15
};
packDataIntoFace(bottom, 1);

std::vector<unsigned> north = {
0, 15, 0, 15, 15,
15, 15, 15, 15, 15,
0, 0, 0, 0, 15,
15, 0, 15, 0, 15,
0, 0, 0, 0, 15,
15, 15, 15, 15, 15
};
packDataIntoFace(north, 2);

std::vector<unsigned> south = {
0, 15, 15, 15, 0,
15, 15, 0, 15, 0,
0, 0, 15, 0, 0,
15, 0, 0, 0, 0,
0, 0, 15, 0, 0,
15, 15, 0, 15, 0
};
packDataIntoFace(south, 3);

std::vector<unsigned> east = {
0, 15, 15, 15, 15,
15, 15, 15, 15, 0,
0, 0, 15, 0, 15,
15, 0, 15, 0, 0,
0, 0, 15, 0, 15,
15, 15, 15, 15, 0
};
packDataIntoFace(east, 4);

std::vector<unsigned> west = {
0, 15, 0, 15, 0,
15, 15, 0, 15, 15,
0, 0, 0, 0, 0,
15, 0, 0, 0, 15,
0, 0, 0, 0, 0,
15, 15, 0, 15, 15
};
packDataIntoFace(west, 5);

}

VoxelModel::~VoxelModel() {

}

bool VoxelModel::packDataIntoFace(const std::vector<unsigned>& data, const int& face) {
for (int i = 0; i < data.size(); i += 5) {
unsigned vertex = 0;
vertex = (vertex ) | data[i ];
vertex = (vertex << 4) | data[i + 1];
vertex = (vertex << 4) | data[i + 2];
vertex = (vertex << 4) | data[i + 3];
vertex = (vertex << 4) | data[i + 4];
//std::cout << vertex << " | ";

mGeometry[face].push_back(vertex);
}
return true;
}



bool VoxelModel::uploadFaceToMesh(std::vector<unsigned>& mesh, const int& face) {
auto& faceModel = mGeometry[face];
if (faceModel.empty()) return false;

for (auto& i : faceModel) {
mesh.push_back(i);
}
return true;
}

std::vector<unsigned>& VoxelModel::getFaceMesh(const int& face) {
return mGeometry[face];
}
}

+ 3
- 3
src/scenes/testscene.cpp View File

@@ -133,9 +133,9 @@ void TestScene::init() {
std::cout << std::endl;

int chunkCount = 1;
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 1; j++) {
for (int k = 0; k < 1; k++) {
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 32; k++) {
std::cout << "\rGenerating chunks (" << chunkCount << "/" << 8*8*8 << ")" << std::flush;
world.generateChunk(i,j,k);
chunkCount++;

+ 2
- 2
src/terraingen.cpp View File

@@ -31,8 +31,8 @@ namespace vtk {

TerrainGen::TerrainGen() {
std::shared_ptr<noise::NoiseModule> noise = std::make_shared<noise::Noise>(6969696);
std::shared_ptr<noise::NoiseModule> yGrad = std::make_shared<noise::YGradient>(0.0, 10.0);
mNoise = yGrad; //std::make_shared<noise::YTurbulence>(yGrad, noise, 40.0);
std::shared_ptr<noise::NoiseModule> yGrad = std::make_shared<noise::YGradient>(0.0, 128.0);
mNoise = std::make_shared<noise::YTurbulence>(yGrad, noise, 40.0);

mTerrainScale = 32.0;
}

Loading…
Cancel
Save