@@ -35,7 +35,7 @@ public: | |||
glm::ivec3 getWorldCoords(const int& x, const int& y, const int& z); | |||
unsigned getLightLevel(const glm::ivec3& pos); | |||
unsigned getLightPacked(const glm::ivec3& pos); | |||
unsigned short getLightPacked(const glm::ivec3& pos); | |||
HeightMap* getHeightMap(); | |||
void setPos(const glm::ivec3& pos); | |||
@@ -48,6 +48,7 @@ protected: | |||
bool isQueuedForMeshRebuild(); | |||
std::array<util::MobileAtomic<unsigned>, 4096> mData; | |||
std::array<util::MobileAtomic<unsigned short>, 4096> mLighting; | |||
World& mLinkedWorld; | |||
glm::ivec3 mPos; | |||
std::atomic<bool> mLoaded; |
@@ -28,7 +28,7 @@ protected: | |||
std::vector<float> geometry; | |||
std::vector<unsigned> mGeometry; | |||
std::vector<unsigned> mFaceAttribs; | |||
std::vector<unsigned> mLighting; | |||
std::vector<unsigned short> mLighting; | |||
bool mLocked; | |||
bool mUpdated; | |||
unsigned mVAO; |
@@ -29,7 +29,7 @@ public: | |||
zero_weight controls how "smoothed" the lighting is. Read the function body for more info on how this works | |||
*/ | |||
void getFaceLighting(std::vector<unsigned>& lighting, const FaceDirection& face, const std::array<unsigned, 27>& surrounding_light, const unsigned& zero_weight); | |||
void getFaceLighting(std::vector<unsigned short>& lighting, const FaceDirection& face, const std::array<unsigned short, 27>& surrounding_light, const unsigned& zero_weight); | |||
protected: | |||
// top bottom north south east west, special | |||
std::array<std::vector<unsigned>, 7> mGeometry; |
@@ -1,4 +1,4 @@ | |||
#version 330 | |||
#version 450 | |||
layout(location = 0) in uint position; | |||
layout(location = 1) in uint face_attrib; | |||
@@ -27,10 +27,10 @@ void main() { | |||
float tex_index = float(face_attrib >> 15u); | |||
vec4 light_unpacked; | |||
light_unpacked.x = float((light >> 24u) & 255u) / 255.0f; | |||
light_unpacked.y = float((light >> 16u) & 255u) / 255.0f; | |||
light_unpacked.z = float((light >> 8u) & 255u) / 255.0f; | |||
light_unpacked.w = float((light) & 255u) / 255.0f; | |||
light_unpacked.x = float((light >> 12u) & 15u) / 15.0f; | |||
light_unpacked.y = float((light >> 8u) & 15u) / 15.0f; | |||
light_unpacked.z = float((light >> 4u) & 15u) / 15.0f; | |||
light_unpacked.w = float((light) & 15u) / 15.0f; | |||
vec3 sun_color = vec3(1.0f, 1.0f, 1.0f) * light_unpacked.w; | |||
vec3 light_color = vec3(max(light_unpacked.x, sun_color.x), |
@@ -1,20 +1,3 @@ | |||
/* | |||
* ===================================================================================== | |||
* | |||
* 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" | |||
@@ -30,9 +13,13 @@ Chunk::Chunk(World& world) : | |||
mPos = glm::ivec3(0,0,0); | |||
//fill voxels with 0 | |||
for (unsigned i = 0; i < mData.size(); i++) { | |||
for (unsigned i = 0; i < mData.size(); ++i) { | |||
mData[i].store(0); | |||
} | |||
for (unsigned i = 0; i < mLighting.size(); ++i) { | |||
mLighting[i].store(0); | |||
} | |||
mLoaded.store(true); | |||
} | |||
@@ -51,7 +38,7 @@ unsigned Chunk::breakVoxel(const glm::ivec3& pos) { | |||
->unblockHeight(glm::ivec3(pos.x, pos.y + mPos.y * 16, pos.z)); | |||
mLinkedWorld.queueChunkUpdate(mPos); | |||
//update the neightboring chunk if voxel lies along border | |||
//update the neightboring chunks if voxel lies along border | |||
glm::ivec3 neighborPos(0,0,0); | |||
if (pos.x == 0) neighborPos.x--; | |||
@@ -62,10 +49,19 @@ unsigned Chunk::breakVoxel(const glm::ivec3& pos) { | |||
if (pos.z == 0) neighborPos.z--; | |||
else if (pos.z == 15) neighborPos.z++; | |||
if (neighborPos != glm::ivec3(0,0,0)) { | |||
mLinkedWorld.queueChunkUpdate(mPos + neighborPos); | |||
} | |||
if (neighborPos.x != 0) | |||
mLinkedWorld.queueChunkUpdate(glm::ivec3(mPos.x + neighborPos.x, | |||
mPos.y, | |||
mPos.z)); | |||
if (neighborPos.y != 0) | |||
mLinkedWorld.queueChunkUpdate(glm::ivec3(mPos.x, | |||
mPos.y + neighborPos.y, | |||
mPos.z)); | |||
if (neighborPos.z != 0) | |||
mLinkedWorld.queueChunkUpdate(glm::ivec3(mPos.x, | |||
mPos.y, | |||
mPos.z + neighborPos.z)); | |||
return voxelType; | |||
} | |||
@@ -83,7 +79,7 @@ bool Chunk::placeVoxel(const glm::ivec3& pos, const unsigned& type) { | |||
mLinkedWorld.queueChunkUpdate(mPos); | |||
//update the neightboring chunk if voxel lies along border | |||
//update the neightboring chunks if voxel lies along border | |||
glm::ivec3 neighborPos(0,0,0); | |||
if (pos.x == 0) neighborPos.x--; | |||
@@ -95,9 +91,18 @@ bool Chunk::placeVoxel(const glm::ivec3& pos, const unsigned& type) { | |||
if (pos.z == 0) neighborPos.z--; | |||
else if (pos.z == 15) neighborPos.z++; | |||
if (neighborPos != glm::ivec3(0,0,0)) { | |||
mLinkedWorld.queueChunkUpdate(mPos + neighborPos); | |||
} | |||
if (neighborPos.x != 0) | |||
mLinkedWorld.queueChunkUpdate(glm::ivec3(mPos.x + neighborPos.x, | |||
mPos.y, | |||
mPos.z)); | |||
if (neighborPos.y != 0) | |||
mLinkedWorld.queueChunkUpdate(glm::ivec3(mPos.x, | |||
mPos.y + neighborPos.y, | |||
mPos.z)); | |||
if (neighborPos.z != 0) | |||
mLinkedWorld.queueChunkUpdate(glm::ivec3(mPos.x, | |||
mPos.y, | |||
mPos.z + neighborPos.z)); | |||
return true; | |||
} | |||
@@ -156,16 +161,16 @@ unsigned Chunk::getLightLevel(const glm::ivec3 &pos) { | |||
return 15; | |||
} | |||
unsigned Chunk::getLightPacked(const glm::ivec3 &pos) { | |||
unsigned short Chunk::getLightPacked(const glm::ivec3 &pos) { | |||
if (isVoxelSolid(pos.x, pos.y, pos.z)) { | |||
return 0x00000000; | |||
return 0x0000; | |||
} | |||
auto wPos = chunkPosToWorldPos(mPos, pos); | |||
if (mLinkedWorld.getHeight(glm::ivec2(wPos.x, wPos.z)) > wPos.y) { //voxel is below ground | |||
//std::cout << mLinkedWorld.getHeight(glm::ivec2(pos.x, pos.z)) << ", "; | |||
return 0x000000AA; | |||
return 0x000A; | |||
} | |||
return 0x000000FF; | |||
return 0x000F; | |||
} | |||
HeightMap* Chunk::getHeightMap() { |
@@ -37,7 +37,7 @@ ChunkMesh::ChunkMesh(World& world, glm::ivec3 chunkPos) : | |||
//light | |||
glBindBuffer(GL_ARRAY_BUFFER, mLightVBO); | |||
glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, GL_FALSE, 0); | |||
glVertexAttribIPointer(2, 1, GL_UNSIGNED_SHORT, GL_FALSE, 0); | |||
glEnableVertexAttribArray(2); | |||
} | |||
@@ -66,8 +66,9 @@ bool ChunkMesh::rebuildChunkGeometry() { | |||
for (int k = 0; k < chunkSize; ++k) { | |||
if (chunk->isVoxelSolid(i,j,k)) { | |||
glm::ivec3 lpos(i,j,k); | |||
std::array<unsigned, 27> surrounding_light; | |||
std::array<unsigned short, 27> surrounding_light; | |||
for (int l = 0; l < 27; ++l) { | |||
//magic to iterate through the 27 voxels around in proper order | |||
glm::ivec3 offset((l % 3) - 1, //x component | |||
(l / 9) - 1, //y component | |||
((l % 9) / 3) - 1); //y component | |||
@@ -85,7 +86,7 @@ bool ChunkMesh::rebuildChunkGeometry() { | |||
//lambda expression for adding vertices | |||
auto addFaceModel = [&](FaceDirection faceDirection) { | |||
auto mesh = mVoxelModel.getFaceMesh(static_cast<unsigned>(faceDirection)); | |||
static std::vector<unsigned> faceLighting; | |||
static std::vector<unsigned short> faceLighting; | |||
faceLighting.clear(); | |||
mVoxelModel.getFaceLighting(faceLighting, faceDirection, surrounding_light, 0); | |||
unsigned texIndex = mLinkedWorld.voxelInfo.getTextureIndex(chunk->getVoxelType(i,j,k), faceDirection); |
@@ -106,8 +106,9 @@ std::vector<unsigned>& VoxelModel::getFaceMesh(const int& face) { | |||
return mGeometry[face]; | |||
} | |||
void VoxelModel::getFaceLighting(std::vector<unsigned>& lighting, const FaceDirection& face, const std::array<unsigned, 27>& surrounding_light, const unsigned& zero_weight) { | |||
void VoxelModel::getFaceLighting(std::vector<unsigned short>& lighting, const FaceDirection& face, const std::array<unsigned short, 27>& surrounding_light, const unsigned& zero_weight) { | |||
/* | |||
auto blend = [](unsigned a, unsigned b, unsigned weight) { | |||
unsigned aw = 7 - weight; | |||
unsigned bw = weight; | |||
@@ -125,24 +126,25 @@ void VoxelModel::getFaceLighting(std::vector<unsigned>& lighting, const FaceDire | |||
((((b) & 0xFF) * bw) / 7u), 255u); | |||
return newLight; | |||
}; | |||
*/ | |||
auto average4 = [](unsigned a, unsigned b, unsigned c, unsigned d) { | |||
unsigned avg = (((a >> 24) & 0xFF) + | |||
((b >> 24) & 0xFF) + | |||
((c >> 24) & 0xFF) + | |||
((d >> 24) & 0xFF)) / 4; | |||
avg = (avg << 8) | (((a >> 16) & 0xFF) + | |||
((b >> 16) & 0xFF) + | |||
((c >> 16) & 0xFF) + | |||
((d >> 16) & 0xFF)) / 4; | |||
avg = (avg << 8) | (((a >> 8) & 0xFF) + | |||
((b >> 8) & 0xFF) + | |||
((c >> 8) & 0xFF) + | |||
((d >> 8) & 0xFF)) / 4; | |||
avg = (avg << 8) | ((a & 0xFF) + | |||
(b & 0xFF) + | |||
(c & 0xFF) + | |||
(d & 0xFF)) / 4; | |||
auto average4 = [](unsigned short a, unsigned short b, unsigned short c, unsigned short d) { | |||
unsigned short avg = (((a >> 12) & 0xF) + | |||
((b >> 12) & 0xF) + | |||
((c >> 12) & 0xF) + | |||
((d >> 12) & 0xF)) / 4; | |||
avg = (avg << 8) | (((a >> 8) & 0xF) + | |||
((b >> 8) & 0xF) + | |||
((c >> 8) & 0xF) + | |||
((d >> 8) & 0xF)) / 4; | |||
avg = (avg << 8) | (((a >> 4) & 0xF) + | |||
((b >> 4) & 0xF) + | |||
((c >> 4) & 0xF) + | |||
((d >> 4) & 0xF)) / 4; | |||
avg = (avg << 8) | ((a & 0xF) + | |||
(b & 0xF) + | |||
(c & 0xF) + | |||
(d & 0xF)) / 4; | |||
return avg; | |||
}; |