Browse Source

mesher mostly working

testing
Michael Porter 3 years ago
parent
commit
482b9d30ef

+ 1
- 0
include/chunk.h View File

@@ -20,6 +20,7 @@

#include "voxelutils.h"
#include "chunkrenderer.h"
#include "graphics/chunkmesh.h"

#include <glm/glm.hpp>


+ 2
- 2
include/graphics/chunkmesh.h View File

@@ -9,8 +9,8 @@ namespace vtk {
class ChunkMesh {
public:
ChunkMesh(World& world, glm::ivec3 linkedChunkPos);
void rebuildChunkGeometry(const unsigned& vao);
void rebuildChunkLighting(const unsigned& vao);
void rebuildChunkGeometry();
void rebuildChunkLighting();
void draw();

protected:

+ 2
- 0
include/mathplus.h View File

@@ -37,10 +37,12 @@ template <typename T> int signum(const T& val) {
return (T(0) < val) - (val < T(0));
}

//floating point modulus
template <typename T> T mod(const T& a, const T& b) {
return fmod(fmod(a,b) + b, b);
}

// constrain a value to bounds
template <typename T>
T constrain(const T& value, const T& min, const T& max) {
if (value <= min) return min;

+ 18
- 0
include/voxelutils.h View File

@@ -19,6 +19,7 @@
#pragma once

#include <tuple>
#include <glm/glm.hpp>

namespace vtk {

@@ -54,4 +55,21 @@ struct iPosEqual : public std::binary_function<iPos, iPos, bool> {
}
};

// basic hash function for glm::ivec3
struct ivec3Hash : public std::unary_function<iPos, std::size_t> {
std::size_t operator()(const glm::ivec3& k) const {
return k.x ^ k.y ^ k.z;
}
};

/*
struct ivec3Equal : public std::binary_function<iPos, iPos, bool> {
bool operator()(const iPos& a, const iPos& b) const {
return (std::get<0>(a) == std::get<0>(b) &&
std::get<1>(a) == std::get<1>(b) &&
std::get<2>(a) == std::get<2>(b));
}
};
*/

}

+ 2
- 0
include/world.h View File

@@ -22,6 +22,7 @@
#include "voxelinfo.h"
#include "voxelmath.h"
#include "terraingen.h"
#include "graphics/chunkmesh.h"

#include <unordered_map>
#include <vector>
@@ -54,6 +55,7 @@ public:
void forceGlobalGeometryUpdate(); //Rebuilds all geometry. Don't do this.

std::unordered_map<iPos, Chunk*, iPosHash, iPosEqual> chunks;
std::unordered_map<glm::ivec3, ChunkMesh, ivec3Hash> mChunkMeshes;
std::vector<iPos> chunkUpdateQueue;

unsigned chunkSize;

+ 20
- 0
res/shaders/voxel.vert View File

@@ -0,0 +1,20 @@

#version 430

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 texCoord;
layout(location = 2) in vec3 lightData;

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

out vec3 texCoordInterp;
out vec3 lightDataInterp;
out vec4 eyeSpacePos;

void main() {
vec4 eyeSpacePosVert = view * model * vec4(position, 1.0);
gl_Position = proj * eyeSpacePosVert;
texCoordInterp = texCoord;
lightDataInterp = lightData;
eyeSpacePos = eyeSpacePosVert;
}

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

@@ -25,7 +25,7 @@ void main() {
//fog calculations

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

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

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

@@ -2,7 +2,6 @@

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 texCoord;
layout(location = 2) in vec3 lightData;

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

@@ -11,9 +10,9 @@ out vec3 lightDataInterp;
out vec4 eyeSpacePos;

void main() {
vec4 eyeSpacePosVert = view * model * vec4(position, 1.0);
vec4 eyeSpacePosVert = view * model * vec4(position, 1.0);
gl_Position = proj * eyeSpacePosVert;
texCoordInterp = texCoord;
lightDataInterp = lightData;
eyeSpacePos = eyeSpacePosVert;
lightDataInterp = vec3(1.0f, 1.0f, 1.0f);
eyeSpacePos = eyeSpacePosVert;
}

+ 88
- 0
src/#chunk.cpp# View File

@@ -0,0 +1,88 @@
/*
* =====================================================================================
*
* Filename: chunk.cpp
*
* Description: Chunk
*
* Version: 1.0
* Created: 04/04/2014 09:44:36 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "chunk.h"
#include "world.h"

#include <iostream>

namespace vtk {

Chunk::Chunk(World& world) :
mLinkedWorld(world)
{
mPos = glm::ivec3(0,0,0);
renderer.linkedChunk = this;

//fill voxels with 0
for (unsigned i = 0; i < 4096; i++) {
voxels[i] = 0;
}
}

bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
if (x < 0 || x > 15 ||
y < 0 || y > 15 ||
z < 0 || z > 15 )
{ //position is outside of the chunk
return mLinkedWorld.isVoxelSolid(mPos.x * 16 + x,
mPos.y * 16 + y,
mPos.z * 16 + z);
}

return (getVoxelType((unsigned)x,(unsigned)y,(unsigned)z) != 0);
}

void Chunk::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type) {
auto index = x + 16 * (y + 16 * z);
if (index > 4095) {
std::cout << "CHUNK ACCESS ERROR (set voxel): Out of range, doing nothing\n";
return;
}
voxels[index] = type;

}

unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z) {
auto index = x + 16 * (y + 16 * z);
if (index > 4095) {
std::cout << "CHUNK ACCESS ERROR (get voxel): Out of range, returning type 0\n";
return 0;
}
return voxels[index];
}

glm::ivec3 Chunk::getWorldCoords(const int& x, const int& y, const int& z) {
return glm::ivec3(mPos.x * 16 + x,
mPos.y * 16 + y,
mPos.z * 16 + z);
}

void Chunk::setPos(const glm::ivec3& pos) {
mPos = pos;
}


glm::ivec3 Chunk::getPos() {
return mPos;
}

World& Chunk::getWorld() {
return mLinkedWorld;
}

}

+ 1
- 0
src/.#chunk.cpp View File

@@ -0,0 +1 @@
user@ryuko.5534:1501725475

+ 88
- 9
src/graphics/chunkmesh.cpp View File

@@ -30,10 +30,10 @@ namespace vtk {

//tex uv coords
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
}

void ChunkMesh::rebuildChunkGeometry(const unsigned& vao) {
void ChunkMesh::rebuildChunkGeometry() {
//get the chunk from position
auto chunk = mLinkedWorld.getChunk(mLinkedChunkPos);

@@ -61,14 +61,14 @@ namespace vtk {
1.0f, 0.0f, 1.0f, //tr
0.0f, 0.0f, 0.0f, //bl
1.0f, 0.0f, 0.0f, //br
0.0f, 0.0f, 1.0f, //bl
0.0f, 0.0f, 0.0f, //bl
1.0f, 0.0f, 1.0f //tr
};
float northModel [] = {
//x y z u v
0.0f, 1.0f, 1.0f, //tl
1.0f, 1.0f, 1.0f, //tr
0.0f, 1.0f, 1.0f, //bl
0.0f, 0.0f, 1.0f, //bl
1.0f, 0.0f, 1.0f, //br
0.0f, 0.0f, 1.0f, //bl
1.0f, 1.0f, 1.0f //tr
@@ -111,25 +111,104 @@ namespace vtk {
for (int k = 0; k < chunkSize; ++k) {
//for each voxel in the chunk...
// TODO: move this code into a mesh provider system

//top
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j + 1, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
for (int m = 0; m < 3; ++m) {
geometry.push_back(northModel[(l * 3) + m]);
}
geometry.push_back(topModel[(l * 3)] + (float)i);
geometry.push_back(topModel[(l * 3) + 1] + (float)j);
geometry.push_back(topModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//bottom
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j - 1, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(bottomModel[(l * 3)] + (float)i);
geometry.push_back(bottomModel[(l * 3) + 1] + (float)j);
geometry.push_back(bottomModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(1, Face3D::TOP));
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//north
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j, k + 1)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(northModel[(l * 3)] + (float)i);
geometry.push_back(northModel[(l * 3) + 1] + (float)j);
geometry.push_back(northModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
//south
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j, k - 1)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(southModel[(l * 3)] + (float)i);
geometry.push_back(southModel[(l * 3) + 1] + (float)j);
geometry.push_back(southModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
//east
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i + 1, j, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(eastModel[(l * 3)] + (float)i);
geometry.push_back(eastModel[(l * 3) + 1] + (float)j);
geometry.push_back(eastModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//west
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i - 1, j, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(westModel[(l * 3)] + (float)i);
geometry.push_back(westModel[(l * 3) + 1] + (float)j);
geometry.push_back(westModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
}
}
}

glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * geometry.size(), geometry.data(), GL_STATIC_DRAW);
}

void ChunkMesh::rebuildChunkLighting(const unsigned& vao) {
void ChunkMesh::rebuildChunkLighting() {
//this doesn't do anything yet
}


+ 23
- 0
src/world.cpp View File

@@ -102,6 +102,8 @@ bool World::makeChunk(const int& x, const int& y, const int& z) {
newChunk->renderer.init();
newChunk->renderer.setChunkPosition(x,y,z);

mChunkMeshes.emplace(posvec, ChunkMesh(*this, posvec));
return true;
}

@@ -131,15 +133,28 @@ void World::queueChunkUpdate(const iPos& pos) {
}

void World::draw() {
/*
for (auto& i : chunks) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
(float)i.second->getPos().x * 16,
(float)i.second->getPos().y * 16,
(float)i.second->getPos().z * 16
));
glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second->renderer.drawChunk();
}
*/
for (auto& i : mChunkMeshes) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
(float)i.first.x * 16,
(float)i.first.y * 16,
(float)i.first.z * 16
));
glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second.draw();
}
}

void World::update() {
@@ -156,12 +171,20 @@ void World::update() {

void World::forceGlobalGeometryUpdate() {
int chunkCount = 1;
/*
for (auto& i : chunks) {
std::cout << "\rUpdating chunk geometry (" << chunkCount << "/" << chunks.size() << ")" << std::flush;
i.second->renderer.updateGeometry();
chunkCount++;
//i.second->renderer.updateVertexData();
}
*/
chunkCount = 1;
for (auto& i : mChunkMeshes) {
std::cout << "\rUpdating chunk geometry, but better (" << chunkCount << "/" << mChunkMeshes.size() << ")" << std::flush;
i.second.rebuildChunkGeometry();
++chunkCount;
}
}

}

Loading…
Cancel
Save