A lot of changes in almost all files

This commit is contained in:
MihailRis 2022-02-28 02:30:15 +03:00 committed by GitHub
parent cd3e737385
commit bc9d29cf68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 3485 additions and 476 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -2,6 +2,9 @@
layout (location = 0) in vec2 v_position;
uniform float u_ar;
uniform float u_scale;
void main(){
gl_Position = vec4(v_position, 0.0, 1.0);
gl_Position = vec4(v_position.x * u_ar * u_scale, v_position.y * u_scale, 0.0, 1.0);
}

View File

@ -10,8 +10,8 @@ uniform vec3 u_fogColor;
void main(){
vec4 tex_color = texture(u_texture0, a_texCoord);
if (tex_color.a < 0.5)
discard;
//if (tex_color.a < 0.5)
// discard;
float depth = (a_distance/256.0)*(a_distance/256.0)*256.0;
f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth/256.0));
f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth/256.0/1.0f));
}

View File

@ -12,10 +12,12 @@ uniform mat4 u_model;
uniform mat4 u_proj;
uniform mat4 u_view;
uniform vec3 u_skyLightColor;
uniform vec3 u_cameraPos;
uniform float u_gamma;
void main(){
vec4 viewmodelpos = u_view * u_model * vec4(v_position, 1.0);
vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz;
vec4 viewmodelpos = u_view * u_model * vec4(v_position+vec3(0,pow(length(pos2d)*0.0, 3.0),0), 1.0);
a_color = vec4(pow(v_light.rgb, vec3(u_gamma)),1.0f);
a_texCoord = v_texCoord;
a_color.rgb += u_skyLightColor * v_light.a*0.5;

View File

@ -14,6 +14,9 @@ union {
#include <fstream>
#include <iostream>
#define SECTION_POSITION 1
#define SECTION_ROTATION 2
unsigned long WorldFiles::totalCompressed = 0;
int bytes2Int(const unsigned char* src, unsigned int offset){
@ -27,6 +30,23 @@ void int2Bytes(int value, char* dest, unsigned int offset){
dest[offset+3] = (char) (value >> 0 & 255);
}
void float2Bytes(float fvalue, char* dest, unsigned int offset){
uint32_t value = *((uint32_t*)&fvalue);
dest[offset] = (char) (value >> 24 & 255);
dest[offset+1] = (char) (value >> 16 & 255);
dest[offset+2] = (char) (value >> 8 & 255);
dest[offset+3] = (char) (value >> 0 & 255);
}
float bytes2Float(char* srcs, unsigned int offset){
unsigned char* src = (unsigned char*) srcs;
uint32_t value = ((src[offset] << 24) |
(src[offset+1] << 16) |
(src[offset+2] << 8) |
(src[offset+3]));
return *(float*)(&value);
}
WorldFiles::WorldFiles(const char* directory, size_t mainBufferCapacity) : directory(directory){
mainBufferIn = new char[CHUNK_VOL*2];
mainBufferOut = new char[mainBufferCapacity];
@ -81,6 +101,10 @@ std::string WorldFiles::getRegionFile(int x, int y) {
return directory + std::to_string(x) + "_" + std::to_string(y) + ".bin";
}
std::string WorldFiles::getPlayerFile() {
return directory + "/player.bin";
}
bool WorldFiles::getChunk(int x, int y, char* out){
assert(out != nullptr);
@ -129,7 +153,7 @@ bool WorldFiles::readChunk(int x, int y, char* out){
input.read((char*)(&offset), 4);
// Ordering bytes from big-endian to machine order (any, just reading)
offset = bytes2Int((const unsigned char*)(&offset), 0);
assert (offset < 1000000);
//assert (offset < 1000000);
if (offset == 0){
input.close();
return false;
@ -161,6 +185,48 @@ void WorldFiles::write(){
}
}
void WorldFiles::writePlayer(glm::vec3 position, float camX, float camY){
char dst[1+3*4 + 1+2*4];
size_t offset = 0;
dst[offset++] = SECTION_POSITION;
float2Bytes(position.x, dst, offset); offset += 4;
float2Bytes(position.y, dst, offset); offset += 4;
float2Bytes(position.z, dst, offset); offset += 4;
dst[offset++] = SECTION_ROTATION;
float2Bytes(camX, dst, offset); offset += 4;
float2Bytes(camY, dst, offset); offset += 4;
write_binary_file(getPlayerFile(), (const char*)dst, sizeof(dst));
}
bool WorldFiles::readPlayer(glm::vec3& position, float& camX, float& camY) {
size_t length = 0;
char* data = read_binary_file(getPlayerFile(), length);
if (data == nullptr){
std::cerr << "could not to read player.bin" << std::endl;
return false;
}
size_t offset = 0;
while (offset < length){
char section = data[offset++];
switch (section){
case SECTION_POSITION:
position.x = bytes2Float(data, offset); offset += 4;
position.y = bytes2Float(data, offset); offset += 4;
position.z = bytes2Float(data, offset); offset += 4;
break;
case SECTION_ROTATION:
camX = bytes2Float(data, offset); offset += 4;
camY = bytes2Float(data, offset); offset += 4;
break;
}
}
std::cout << position.x << " " << position.y << " " << position.z << std::endl;
return true;
}
unsigned int WorldFiles::writeRegion(char* out, int x, int y, char** region){
unsigned int offset = REGION_VOL * 4;
for (unsigned int i = 0; i < offset; i++)

View File

@ -3,7 +3,8 @@
#include <map>
#include <unordered_map>
#include <string>
#include <glm/glm.hpp>
#define REGION_SIZE_BIT 5
#define REGION_SIZE (1 << (REGION_SIZE_BIT))
#define REGION_VOL ((REGION_SIZE) * (REGION_SIZE))
@ -26,13 +27,16 @@ public:
void put(const char* chunkData, int x, int y);
bool readPlayer(glm::vec3& position, float& camX, float& camY);
bool readChunk(int x, int y, char* out);
bool getChunk(int x, int y, char* out);
void readRegion(char* fileContent);
unsigned int writeRegion(char* out, int x, int y, char** region);
void writePlayer(glm::vec3 position, float camX, float camY);
void write();
std::string getRegionFile(int x, int y);
std::string getPlayerFile();
};
extern void longToCoords(int& x, int& y, long key);

View File

@ -40,14 +40,18 @@ bool read_binary_file(std::string filename, char* data, size_t size) {
return true;
}
bool read_binary_file(std::string filename, char* data, size_t offset, size_t size) {
char* read_binary_file(std::string filename, size_t& length) {
std::ifstream input(filename, std::ios::binary);
if (!input.is_open())
return false;
input.seekg(offset);
input.read(data, size);
return nullptr;
input.seekg(0, std::ios_base::end);
length = input.tellg();
input.seekg(0, std::ios_base::beg);
char* data = new char[length];
input.read(data, length);
input.close();
return true;
return data;
}
// returns decompressed length

View File

@ -7,6 +7,7 @@ extern bool write_binary_file(std::string filename, const char* data, size_t siz
extern unsigned int append_binary_file(std::string filename, const char* data, size_t size);
extern bool read_binary_file(std::string filename, char* data, size_t size);
extern bool read_binary_file(std::string filename, char* data, size_t offset, size_t size);
extern char* read_binary_file(std::string filename, size_t& length);
extern unsigned int calcRLE(const char* src, unsigned int length);
extern unsigned int compressRLE(const char* src, unsigned int length, char* dst);

View File

@ -67,6 +67,7 @@ void LineBatch::box(float x, float y, float z, float w, float h, float d,
line(x+w, y+h, z-d, x+w, y+h, z+d, r,g,b,a);
}
#include <iostream>
void LineBatch::render(){
if (index == 0)
return;

View File

@ -44,254 +44,271 @@ VoxelRenderer::~VoxelRenderer(){
delete[] buffer;
}
inline void _renderBlock(float* buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){
unsigned int id = vox.id;
if (!id){
return;
}
float l;
float uvsize = 1.0f/16.0f;
Block* block = Block::blocks[id];
unsigned char group = block->drawGroup;
if (!IS_BLOCKED(x,y+1,z,group)){
l = 1.0f;
SETUP_UV(block->textureFaces[3]);
float lr = LIGHT(x,y+1,z, 0) / 15.0f;
float lg = LIGHT(x,y+1,z, 1) / 15.0f;
float lb = LIGHT(x,y+1,z, 2) / 15.0f;
float ls = LIGHT(x,y+1,z, 3) / 15.0f;
float lr0 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, lr0, lg0, lb0, ls0);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1, lg1, lb1, ls1);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2, lg2, lb2, ls2);
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, lr0, lg0, lb0, ls0);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2, lg2, lb2, ls2);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v1, lr3, lg3, lb3, ls3);
}
if (!IS_BLOCKED(x,y-1,z,group)){
l = 0.75f;
SETUP_UV(block->textureFaces[2]);
float lr = LIGHT(x,y-1,z, 0) / 15.0f;
float lg = LIGHT(x,y-1,z, 1) / 15.0f;
float lb = LIGHT(x,y-1,z, 2) / 15.0f;
float ls = LIGHT(x,y-1,z, 3) / 15.0f;
float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr3,lg3,lb3,ls3);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
}
if (!IS_BLOCKED(x+1,y,z,group)){
l = 0.95f;
SETUP_UV(block->textureFaces[1]);
float lr = LIGHT(x+1,y,z, 0) / 15.0f;
float lg = LIGHT(x+1,y,z, 1) / 15.0f;
float lb = LIGHT(x+1,y,z, 2) / 15.0f;
float ls = LIGHT(x+1,y,z, 3) / 15.0f;
float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y-1,z,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y+1,z,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y+1,z,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y-1,z,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y-1,z,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y+1,z,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y+1,z,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y-1,z,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y-1,z,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y+1,z,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y+1,z,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y-1,z,3)) / 5.0f / 15.0f;
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u1,v1, lr3,lg3,lb3,ls3);
}
if (!IS_BLOCKED(x-1,y,z,group)){
l = 0.85f;
SETUP_UV(block->textureFaces[0]);
float lr = LIGHT(x-1,y,z, 0) / 15.0f;
float lg = LIGHT(x-1,y,z, 1) / 15.0f;
float lb = LIGHT(x-1,y,z, 2) / 15.0f;
float ls = LIGHT(x-1,y,z, 3) / 15.0f;
float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y-1,z,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y+1,z,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y+1,z,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y-1,z,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y-1,z,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y+1,z,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y+1,z,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y-1,z,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y-1,z,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y+1,z,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y+1,z,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y-1,z,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y-1,z,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y+1,z,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y+1,z,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y-1,z,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u2,v1, lr3,lg3,lb3,ls3);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
}
if (!IS_BLOCKED(x,y,z+1,group)){
l = 0.9f;
SETUP_UV(block->textureFaces[5]);
float lr = LIGHT(x,y,z+1, 0) / 15.0f;
float lg = LIGHT(x,y,z+1, 1) / 15.0f;
float lb = LIGHT(x,y,z+1, 2) / 15.0f;
float ls = LIGHT(x,y,z+1, 3) / 15.0f;
float lr0 = l*(LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 5.0f / 15.0f;
float lr1 = l*(LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 5.0f / 15.0f;
float lr2 = l*(LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 5.0f / 15.0f;
float lr3 = l*(LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 5.0f / 15.0f;
float lg0 = l*(LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 5.0f / 15.0f;
float lg1 = l*(LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 5.0f / 15.0f;
float lg2 = l*(LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 5.0f / 15.0f;
float lg3 = l*(LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 5.0f / 15.0f;
float lb0 = l*(LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 5.0f / 15.0f;
float lb1 = l*(LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 5.0f / 15.0f;
float lb2 = l*(LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 5.0f / 15.0f;
float lb3 = l*(LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 5.0f / 15.0f;
float ls0 = l*(LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 5.0f / 15.0f;
float ls1 = l*(LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 5.0f / 15.0f;
float ls2 = l*(LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 5.0f / 15.0f;
float ls3 = l*(LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v1, lr3,lg3,lb3,ls3);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
}
if (!IS_BLOCKED(x,y,z-1,group)){
l = 0.8f;
SETUP_UV(block->textureFaces[4]);
float lr = LIGHT(x,y,z-1, 0) / 15.0f;
float lg = LIGHT(x,y,z-1, 1) / 15.0f;
float lb = LIGHT(x,y,z-1, 2) / 15.0f;
float ls = LIGHT(x,y,z-1, 3) / 15.0f;
float lr0 = l*(LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 5.0f / 15.0f;
float lr1 = l*(LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 5.0f / 15.0f;
float lr2 = l*(LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 5.0f / 15.0f;
float lr3 = l*(LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 5.0f / 15.0f;
float lg0 = l*(LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 5.0f / 15.0f;
float lg1 = l*(LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 5.0f / 15.0f;
float lg2 = l*(LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 5.0f / 15.0f;
float lg3 = l*(LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 5.0f / 15.0f;
float lb0 = l*(LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 5.0f / 15.0f;
float lb1 = l*(LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 5.0f / 15.0f;
float lb2 = l*(LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 5.0f / 15.0f;
float lb3 = l*(LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 5.0f / 15.0f;
float ls0 = l*(LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 5.0f / 15.0f;
float ls1 = l*(LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 5.0f / 15.0f;
float ls2 = l*(LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 5.0f / 15.0f;
float ls3 = l*(LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u1,v1, lr3,lg3,lb3,ls3);
}
}
Mesh* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks){
size_t index = 0;
for (int y = 0; y < CHUNK_H; y++){
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
unsigned int id = vox.id;
if (!id){
if (vox.id == 9)
continue;
}
_renderBlock(buffer, x, y, z, chunks, vox, index);
}
}
}
float l;
float uvsize = 1.0f/16.0f;
Block* block = Block::blocks[id];
unsigned char group = block->drawGroup;
if (!IS_BLOCKED(x,y+1,z,group)){
l = 1.0f;
SETUP_UV(block->textureFaces[3]);
float lr = LIGHT(x,y+1,z, 0) / 15.0f;
float lg = LIGHT(x,y+1,z, 1) / 15.0f;
float lb = LIGHT(x,y+1,z, 2) / 15.0f;
float ls = LIGHT(x,y+1,z, 3) / 15.0f;
float lr0 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, lr0, lg0, lb0, ls0);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1, lg1, lb1, ls1);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2, lg2, lb2, ls2);
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, lr0, lg0, lb0, ls0);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2, lg2, lb2, ls2);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v1, lr3, lg3, lb3, ls3);
}
if (!IS_BLOCKED(x,y-1,z,group)){
l = 0.75f;
SETUP_UV(block->textureFaces[2]);
float lr = LIGHT(x,y-1,z, 0) / 15.0f;
float lg = LIGHT(x,y-1,z, 1) / 15.0f;
float lb = LIGHT(x,y-1,z, 2) / 15.0f;
float ls = LIGHT(x,y-1,z, 3) / 15.0f;
float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr3,lg3,lb3,ls3);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
}
if (!IS_BLOCKED(x+1,y,z,group)){
l = 0.95f;
SETUP_UV(block->textureFaces[1]);
float lr = LIGHT(x+1,y,z, 0) / 15.0f;
float lg = LIGHT(x+1,y,z, 1) / 15.0f;
float lb = LIGHT(x+1,y,z, 2) / 15.0f;
float ls = LIGHT(x+1,y,z, 3) / 15.0f;
float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y-1,z,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y+1,z,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y+1,z,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y-1,z,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y-1,z,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y+1,z,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y+1,z,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y-1,z,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y-1,z,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y+1,z,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y+1,z,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y-1,z,3)) / 5.0f / 15.0f;
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u1,v1, lr3,lg3,lb3,ls3);
}
if (!IS_BLOCKED(x-1,y,z,group)){
l = 0.85f;
SETUP_UV(block->textureFaces[0]);
float lr = LIGHT(x-1,y,z, 0) / 15.0f;
float lg = LIGHT(x-1,y,z, 1) / 15.0f;
float lb = LIGHT(x-1,y,z, 2) / 15.0f;
float ls = LIGHT(x-1,y,z, 3) / 15.0f;
float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y-1,z,0)) / 5.0f / 15.0f;
float lr1 = (LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y+1,z,0)) / 5.0f / 15.0f;
float lr2 = (LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y+1,z,0)) / 5.0f / 15.0f;
float lr3 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y-1,z,0)) / 5.0f / 15.0f;
float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y-1,z,1)) / 5.0f / 15.0f;
float lg1 = (LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y+1,z,1)) / 5.0f / 15.0f;
float lg2 = (LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y+1,z,1)) / 5.0f / 15.0f;
float lg3 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y-1,z,1)) / 5.0f / 15.0f;
float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y-1,z,2)) / 5.0f / 15.0f;
float lb1 = (LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y+1,z,2)) / 5.0f / 15.0f;
float lb2 = (LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y+1,z,2)) / 5.0f / 15.0f;
float lb3 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y-1,z,2)) / 5.0f / 15.0f;
float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y-1,z,3)) / 5.0f / 15.0f;
float ls1 = (LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y+1,z,3)) / 5.0f / 15.0f;
float ls2 = (LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y+1,z,3)) / 5.0f / 15.0f;
float ls3 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y-1,z,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u2,v1, lr3,lg3,lb3,ls3);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
}
if (!IS_BLOCKED(x,y,z+1,group)){
l = 0.9f;
SETUP_UV(block->textureFaces[5]);
float lr = LIGHT(x,y,z+1, 0) / 15.0f;
float lg = LIGHT(x,y,z+1, 1) / 15.0f;
float lb = LIGHT(x,y,z+1, 2) / 15.0f;
float ls = LIGHT(x,y,z+1, 3) / 15.0f;
float lr0 = l*(LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 5.0f / 15.0f;
float lr1 = l*(LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 5.0f / 15.0f;
float lr2 = l*(LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 5.0f / 15.0f;
float lr3 = l*(LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 5.0f / 15.0f;
float lg0 = l*(LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 5.0f / 15.0f;
float lg1 = l*(LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 5.0f / 15.0f;
float lg2 = l*(LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 5.0f / 15.0f;
float lg3 = l*(LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 5.0f / 15.0f;
float lb0 = l*(LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 5.0f / 15.0f;
float lb1 = l*(LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 5.0f / 15.0f;
float lb2 = l*(LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 5.0f / 15.0f;
float lb3 = l*(LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 5.0f / 15.0f;
float ls0 = l*(LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 5.0f / 15.0f;
float ls1 = l*(LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 5.0f / 15.0f;
float ls2 = l*(LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 5.0f / 15.0f;
float ls3 = l*(LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v1, lr3,lg3,lb3,ls3);
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1);
}
if (!IS_BLOCKED(x,y,z-1,group)){
l = 0.8f;
SETUP_UV(block->textureFaces[4]);
float lr = LIGHT(x,y,z-1, 0) / 15.0f;
float lg = LIGHT(x,y,z-1, 1) / 15.0f;
float lb = LIGHT(x,y,z-1, 2) / 15.0f;
float ls = LIGHT(x,y,z-1, 3) / 15.0f;
float lr0 = l*(LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 5.0f / 15.0f;
float lr1 = l*(LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 5.0f / 15.0f;
float lr2 = l*(LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 5.0f / 15.0f;
float lr3 = l*(LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 5.0f / 15.0f;
float lg0 = l*(LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 5.0f / 15.0f;
float lg1 = l*(LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 5.0f / 15.0f;
float lg2 = l*(LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 5.0f / 15.0f;
float lg3 = l*(LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 5.0f / 15.0f;
float lb0 = l*(LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 5.0f / 15.0f;
float lb1 = l*(LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 5.0f / 15.0f;
float lb2 = l*(LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 5.0f / 15.0f;
float lb3 = l*(LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 5.0f / 15.0f;
float ls0 = l*(LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 5.0f / 15.0f;
float ls1 = l*(LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 5.0f / 15.0f;
float ls2 = l*(LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 5.0f / 15.0f;
float ls3 = l*(LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 5.0f / 15.0f;
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v2, lr1,lg1,lb1,ls1);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0);
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, lr2,lg2,lb2,ls2);
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u1,v1, lr3,lg3,lb3,ls3);
}
for (int y = 0; y < CHUNK_H; y++){
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
if (vox.id != 9)
continue;
_renderBlock(buffer, x, y, z, chunks, vox, index);
}
}
}

View File

@ -1,3 +1,4 @@
#include <iostream>
#include <assert.h>
#include "LightSolver.h"
#include "Lightmap.h"
@ -60,7 +61,7 @@ void LightSolver::solve(){
};
while (!remqueue.empty()){
lightentry entry = remqueue.front();
const lightentry entry = remqueue.front();
remqueue.pop();
for (size_t i = 0; i < 6; i++) {

View File

@ -6,22 +6,15 @@
#include "../voxels/voxel.h"
#include "../voxels/Block.h"
Chunks* Lighting::chunks = nullptr;
LightSolver* Lighting::solverR = nullptr;
LightSolver* Lighting::solverG = nullptr;
LightSolver* Lighting::solverB = nullptr;
LightSolver* Lighting::solverS = nullptr;
int Lighting::initialize(Chunks* chunks){
Lighting::chunks = chunks;
Lighting::Lighting(Chunks* chunks){
this->chunks = chunks;
solverR = new LightSolver(chunks, 0);
solverG = new LightSolver(chunks, 1);
solverB = new LightSolver(chunks, 2);
solverS = new LightSolver(chunks, 3);
return 0;
}
void Lighting::finalize(){
Lighting::~Lighting(){
delete solverR, solverG, solverB, solverS;
}
@ -37,11 +30,11 @@ void Lighting::clear(){
}
}
void Lighting::onChunkLoaded(int cx, int cy, int cz){
void Lighting::onChunkLoaded(int cx, int cy, int cz, bool sky){
Chunk* chunk = chunks->getChunk(cx, cy, cz);
Chunk* chunkUpper = chunks->getChunk(cx, cy+1, cz);
Chunk* chunkLower = chunks->getChunk(cx, cy-1, cz);
if (chunkLower){
if (chunkLower && sky){
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
int gx = x + cx * CHUNK_W;
@ -65,7 +58,7 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
break;
voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz);
Block* block = Block::blocks[vox->id];
if (!block->lightPassing)
if (!block->skyLightPassing)
break;
//current->lightmap->setS(x,y,z, 0);
current->modified = true;
@ -76,7 +69,7 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
}
}
}
if (chunkUpper){
if (chunkUpper && sky){
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
int gx = x + cx * CHUNK_W;
@ -99,7 +92,7 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
break;
voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz);
Block* block = Block::blocks[vox->id];
if (!block->lightPassing)
if (!block->skyLightPassing)
break;
current->lightmap->setS(x,y,z, 15);
current->modified = true;
@ -110,7 +103,7 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
}
}
}
} else {
} else if (sky){
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
int gx = x + cx * CHUNK_W;
@ -129,11 +122,11 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
break;
voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz);
Block* block = Block::blocks[vox->id];
if (!block->lightPassing)
if (!block->skyLightPassing)
break;
current->lightmap->setS(x,y,z, 15);
current->modified = true;
//solverS->add(gx,y+ncy*CHUNK_H,gz);
solverS->add(gx,y+ncy*CHUNK_H,gz);
}
}
}
@ -163,10 +156,13 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
int gx = x + cx * CHUNK_W;
int gy = y + cy * CHUNK_H;
int gz = z + cz * CHUNK_D;
solverR->add(gx,gy,gz);
solverG->add(gx,gy,gz);
solverB->add(gx,gy,gz);
solverS->add(gx,gy,gz);
if (chunks->getLight(x,y,z)){
solverR->add(gx,gy,gz);
solverG->add(gx,gy,gz);
solverB->add(gx,gy,gz);
if (sky)
solverS->add(gx,gy,gz);
}
}
}
}
@ -199,7 +195,7 @@ void Lighting::onBlockSet(int x, int y, int z, int id){
if (chunks->getLight(x,y+1,z, 3) == 0xF){
for (int i = y; i >= 0; i--){
voxel* vox = chunks->get(x,i,z);
if (vox == nullptr || vox->id != 0)
if (vox == nullptr || vox->id != 0 && Block::blocks[id]->skyLightPassing)
break;
solverS->add(x,i,z, 0xF);
}
@ -220,7 +216,7 @@ void Lighting::onBlockSet(int x, int y, int z, int id){
solverR->remove(x,y,z);
solverG->remove(x,y,z);
solverB->remove(x,y,z);
if (!block->lightPassing){
if (!block->skyLightPassing){
solverS->remove(x,y,z);
for (int i = y-1; i >= 0; i--){
solverS->remove(x,i,z);

View File

@ -5,18 +5,18 @@ class Chunks;
class LightSolver;
class Lighting {
static Chunks* chunks;
static LightSolver* solverR;
static LightSolver* solverG;
static LightSolver* solverB;
static LightSolver* solverS;
Chunks* chunks = nullptr;
LightSolver* solverR = nullptr;
LightSolver* solverG = nullptr;
LightSolver* solverB = nullptr;
LightSolver* solverS = nullptr;
public:
static int initialize(Chunks* chunks);
static void finalize();
Lighting(Chunks* chunks);
~Lighting();
static void clear();
static void onChunkLoaded(int cx, int cy, int cz);
static void onBlockSet(int x, int y, int z, int id);
void clear();
void onChunkLoaded(int cx, int cy, int cz, bool sky);
void onBlockSet(int x, int y, int z, int id);
};
#endif /* LIGHTING_LIGHTING_H_ */

View File

@ -10,3 +10,9 @@ Lightmap::Lightmap(){
Lightmap::~Lightmap(){
delete[] map;
}
void Lightmap::set(const Lightmap* lightmap) {
for (unsigned int i = 0; i < CHUNK_VOL; i++){
map[i] = lightmap->map[i];
}
}

View File

@ -9,6 +9,12 @@ public:
Lightmap();
~Lightmap();
void set(const Lightmap* lightmap);
inline unsigned short get(int x, int y, int z){
return (map[y*CHUNK_D*CHUNK_W+z*CHUNK_W+x]);
}
inline unsigned char get(int x, int y, int z, int channel){
return (map[y*CHUNK_D*CHUNK_W+z*CHUNK_W+x] >> (channel << 2)) & 0xF;
}

View File

@ -101,7 +101,7 @@ int _png_load(const char* file, int* width, int* height){
alpha, GL_UNSIGNED_BYTE, (GLvoid *) image_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);

2433
src/maths/FastNoiseLite.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <algorithm>
#include <vector>
#include <ctime>
// GLM
@ -27,6 +29,7 @@ using namespace glm;
#include "voxels/Chunks.h"
#include "voxels/Block.h"
#include "voxels/WorldGenerator.h"
#include "voxels/ChunksController.h"
#include "files/files.h"
#include "files/WorldFiles.h"
#include "lighting/LightSolver.h"
@ -67,6 +70,7 @@ void setup_definitions() {
Block* block = new Block(0,0);
block->drawGroup = 1;
block->lightPassing = true;
block->skyLightPassing = true;
block->obstacle = false;
Block::blocks[block->id] = block;
@ -96,6 +100,28 @@ void setup_definitions() {
// PLANKS
block = new Block(5,6);
Block::blocks[block->id] = block;
// WOOD
block = new Block(6,7);
block->textureFaces[2] = 8;
block->textureFaces[3] = 8;
Block::blocks[block->id] = block;
// LEAVES
block = new Block(7,9);
Block::blocks[block->id] = block;
// ACTUAL STONE
block = new Block(8,10);
Block::blocks[block->id] = block;
// WATER
block = new Block(9,11);
block->drawGroup = 4;
block->lightPassing = true;
block->skyLightPassing = false;
block->obstacle = false;
Block::blocks[block->id] = block;
}
// Shaders, textures, renderers
@ -131,8 +157,70 @@ int initialize_assets() {
return 0;
}
void draw_chunk(size_t index, Camera* camera){
Chunk* chunk = chunks->chunks[index];
Mesh* mesh = chunks->meshes[index];
if (mesh == nullptr)
return;
// Simple frustum culling (culling chunks behind the camera in 2D - XZ)
if (occlusion){
const float cameraX = camera->position.x;
const float cameraZ = camera->position.z;
const float camDirX = camera->dir.x;
const float camDirZ = camera->dir.z;
bool unoccluded = false;
do {
if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
} while (false);
if (!unoccluded)
return;
}
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f));
shader->uniformMatrix("u_model", model);
mesh->draw(GL_TRIANGLES);
}
float find_most_distant_sqr(float px, float pz, float distance_limit2){
float max_dist2 = -1.0f;
for (size_t i = 0; i < chunks->volume; i++){
Chunk* chunk = chunks->chunks[i];
if (chunk == nullptr)
continue;
float dist2 = (chunk->x - px) * (chunk->z - pz);
if (dist2 > max_dist2 && dist2 < distance_limit2){
max_dist2 = dist2;
}
}
return max_dist2;
}
float _camera_cx;
float _camera_cz;
bool chunks_comparator(size_t i, size_t j) {
Chunk* a = chunks->chunks[i];
Chunk* b = chunks->chunks[j];
return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz)
>
(b->x + 0.5f - _camera_cx)*(b->x + 0.5f - _camera_cx) + (b->z + 0.5f - _camera_cz)*(b->z + 0.5f - _camera_cz));
}
void draw_world(Camera* camera){
glClearColor(0.7f,0.85f,1.0f,1);
glClearColor(0.7f,0.71f,0.73f,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw VAO
@ -141,50 +229,37 @@ void draw_world(Camera* camera){
shader->uniformMatrix("u_view", camera->getView());
shader->uniform1f("u_gamma", 1.6f);
shader->uniform3f("u_skyLightColor", 1.8f,1.8f,1.8f);
shader->uniform3f("u_fogColor", 0.7f,0.85f,1.0f);
shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f);
shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z);
texture->bind();
mat4 model(1.0f);
const float cameraX = camera->position.x;
const float cameraZ = camera->position.z;
const float camDirX = camera->dir.x;
const float camDirZ = camera->dir.z;
std::vector<size_t> indices;
for (size_t i = 0; i < chunks->volume; i++){
Chunk* chunk = chunks->chunks[i];
if (chunk == nullptr)
continue;
Mesh* mesh = chunks->meshes[i];
if (mesh == nullptr)
continue;
if (chunks->meshes[i] != nullptr)
indices.push_back(i);
}
// Simple frustum culling (culling chunks behind the camera in 2D - XZ)
if (occlusion){
bool unoccluded = false;
do {
if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
} while (false);
if (!unoccluded)
continue;
}
std::sort(indices.begin(), indices.end(), chunks_comparator);
model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f));
shader->uniformMatrix("u_model", model);
mesh->draw(GL_TRIANGLES);
float px = camera->position.x / (float)CHUNK_W;
float pz = camera->position.z / (float)CHUNK_D;
_camera_cx = px;
_camera_cz = pz;
for (size_t i = 0; i < indices.size(); i++){
draw_chunk(indices[i], camera);
}
crosshairShader->use();
crosshairShader->uniform1f("u_ar", (float)Window::height / (float)Window::width);
crosshairShader->uniform1f("u_scale", 1.0f / ((float)Window::height / 1000.0f));
crosshair->draw(GL_LINES);
linesShader->use();
@ -233,30 +308,39 @@ int main() {
return result;
}
Camera* camera = new Camera(vec3(-320,255,32), radians(90.0f));
wfile = new WorldFiles("world/", REGION_VOL * (CHUNK_VOL * 2 + 8));
chunks = new Chunks(32,1,32, 0,0,0);
VoxelRenderer renderer(1024*1024);
lineBatch = new LineBatch(4096);
PhysicsSolver physics(vec3(0,-16.0f,0));
Lighting::initialize(chunks);
crosshair = new Mesh(vertices, 4, attrs);
Camera* camera = new Camera(vec3(32,32,32), radians(90.0f));
Hitbox* hitbox = new Hitbox(vec3(32,120,32), vec3(0.2f,0.9f,0.2f));
float lastTime = glfwGetTime();
float delta = 0.0f;
chunks = new Chunks(34,1,34, 0,0,0);
float camX = 0.0f;
float camY = 0.0f;
float playerSpeed = 4.0f;
wfile->readPlayer(camera->position, camX, camY);
camera->rotation = mat4(1.0f);
camera->rotate(camY, camX, 0);
Hitbox* hitbox = new Hitbox(vec3(camera->position.x,camera->position.y+1,camera->position.z), vec3(0.2f,0.9f,0.2f));
VoxelRenderer renderer(1024*1024);
lineBatch = new LineBatch(4096);
PhysicsSolver physics(vec3(0,-16.0f,0));
Lighting lighting(chunks);
crosshair = new Mesh(vertices, 4, attrs);
ChunksController chunksController(chunks, &lighting);
float lastTime = glfwGetTime();
float delta = 0.0f;
float playerSpeed = 5.0f;
int choosenBlock = 1;
long frame = 0;
glfwSwapInterval(0);
glfwSwapInterval(1);
while (!Window::isShouldClose()){
frame++;
@ -264,8 +348,8 @@ int main() {
delta = currentTime - lastTime;
lastTime = currentTime;
//if (frame % 240 == 0)
// std::cout << delta << std::endl;
if (frame % 240 == 0)
std::cout << 1.0/delta << std::endl;
if (Events::jpressed(GLFW_KEY_O)){
occlusion = !occlusion;
@ -278,7 +362,7 @@ int main() {
Events::toogleCursor();
}
for (int i = 1; i < 6; i++){
for (int i = 1; i < 10; i++){
if (Events::jpressed(GLFW_KEY_0+i)){
choosenBlock = i;
}
@ -334,8 +418,8 @@ int main() {
hitbox->velocity.z = dir.z * speed;
chunks->setCenter(wfile, camera->position.x,0,camera->position.z);
chunks->_buildMeshes(&renderer);
chunks->loadVisible(wfile);
chunksController._buildMeshes(&renderer, frame);
chunksController.loadVisible(wfile);
if (Events::_cursor_locked){
camY += -Events::deltaY / Window::height * 2;
@ -365,7 +449,7 @@ int main() {
int y = (int)iend.y;
int z = (int)iend.z;
chunks->set(x,y,z, 0);
Lighting::onBlockSet(x,y,z,0);
lighting.onBlockSet(x,y,z,0);
}
if (Events::jclicked(GLFW_MOUSE_BUTTON_2)){
int x = (int)(iend.x)+(int)(norm.x);
@ -373,7 +457,7 @@ int main() {
int z = (int)(iend.z)+(int)(norm.z);
if (!physics.isBlockInside(x,y,z, hitbox)){
chunks->set(x, y, z, choosenBlock);
Lighting::onBlockSet(x,y,z, choosenBlock);
lighting.onBlockSet(x,y,z, choosenBlock);
}
}
}
@ -384,10 +468,10 @@ int main() {
Events::pullEvents();
}
wfile->writePlayer(hitbox->position, camX, camY);
write_world();
close_world();
Lighting::finalize();
finalize_assets();
Window::terminate();
return 0;

View File

@ -11,6 +11,7 @@ public:
unsigned char emission[3];
unsigned char drawGroup = 0;
bool lightPassing = false;
bool skyLightPassing = false;
bool obstacle = true;
Block(unsigned int id, int texture);

View File

@ -27,3 +27,11 @@ bool Chunk::isEmpty(){
}
return true;
}
Chunk* Chunk::clone() const {
Chunk* other = new Chunk(x,y,z);
for (int i = 0; i < CHUNK_VOL; i++)
other->voxels[i] = voxels[i];
other->lightmap->set(lightmap);
return other;
}

View File

@ -15,10 +15,15 @@ public:
voxel* voxels;
Lightmap* lightmap;
bool modified = true;
bool ready = false;
bool accepted = false;
bool generated = false;
Chunk(int x, int y, int z);
~Chunk();
bool isEmpty();
Chunk* clone() const;
};
#endif /* VOXELS_CHUNK_H_ */

View File

@ -6,14 +6,8 @@
#include "../lighting/Lightmap.h"
#include "../files/WorldFiles.h"
#include "../lighting/Lighting.h"
#include "../graphics/VoxelRenderer.h"
#include "../graphics/Mesh.h"
#include <glm/glm.hpp>
using namespace glm;
#include <math.h>
#include <limits.h>
@ -38,77 +32,6 @@ Chunks::~Chunks(){
delete[] chunks;
}
bool Chunks::_buildMeshes(VoxelRenderer* renderer) {
int nearX = 0;
int nearY = 0;
int nearZ = 0;
int minDistance = 1000000000;
for (unsigned int y = 0; y < h; y++){
for (unsigned int z = 1; z < d-1; z++){
for (unsigned int x = 1; x < w-1; x++){
int index = (y * d + z) * w + x;
Chunk* chunk = chunks[index];
if (chunk == nullptr)
continue;
Mesh* mesh = meshes[index];
if (mesh != nullptr && !chunk->modified)
continue;
int lx = x - w / 2;
int ly = y - h / 2;
int lz = z - d / 2;
int distance = (lx * lx + ly * ly + lz * lz);
if (distance < minDistance){
minDistance = distance;
nearX = x;
nearY = y;
nearZ = z;
}
}
}
}
int index = (nearY * d + nearZ) * w + nearX;
Chunk* closes[27];
Chunk* chunk = chunks[index];
if (chunk == nullptr)
return false;
Mesh* mesh = meshes[index];
if (mesh == nullptr || chunk->modified){
if (mesh != nullptr)
delete mesh;
if (chunk->isEmpty()){
meshes[index] = nullptr;
return false;
}
chunk->modified = false;
for (int i = 0; i < 27; i++)
closes[i] = nullptr;
for (size_t j = 0; j < volume; j++){
Chunk* other = chunks[j];
if (other == nullptr)
continue;
int ox = other->x - chunk->x;
int oy = other->y - chunk->y;
int oz = other->z - chunk->z;
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
continue;
ox += 1;
oy += 1;
oz += 1;
closes[(oy * 3 + oz) * 3 + ox] = other;
}
mesh = renderer->render(chunk, (const Chunk**)closes);
meshes[index] = mesh;
return true;
}
return false;
}
voxel* Chunks::get(int x, int y, int z){
x -= ox * CHUNK_W;
y -= oy * CHUNK_H;
@ -158,6 +81,27 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){
return chunk->lightmap->get(lx,ly,lz, channel);
}
unsigned short Chunks::getLight(int x, int y, int z){
x -= ox * CHUNK_W;
y -= oy * CHUNK_H;
z -= oz * CHUNK_D;
int cx = x / CHUNK_W;
int cy = y / CHUNK_H;
int cz = z / CHUNK_D;
if (x < 0) cx--;
if (y < 0) cy--;
if (z < 0) cz--;
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
return 0;
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
if (chunk == nullptr)
return 0;
int lx = x - cx * CHUNK_W;
int ly = y - cy * CHUNK_H;
int lz = z - cz * CHUNK_D;
return chunk->lightmap->get(lx,ly,lz);
}
Chunk* Chunks::getChunkByVoxel(int x, int y, int z){
x -= ox * CHUNK_W;
y -= oy * CHUNK_H;
@ -317,46 +261,6 @@ void Chunks::setCenter(WorldFiles* worldFiles, int x, int y, int z) {
translate(worldFiles, cx,cy,cz);
}
bool Chunks::loadVisible(WorldFiles* worldFiles){
int nearX = 0;
int nearY = 0;
int nearZ = 0;
int minDistance = (w/2)*(w/2);
for (unsigned int y = 0; y < h; y++){
for (unsigned int z = 1; z < d-1; z++){
for (unsigned int x = 1; x < w-1; x++){
int index = (y * d + z) * w + x;
Chunk* chunk = chunks[index];
if (chunk != nullptr)
continue;
int lx = x - w / 2;
int ly = y - h / 2;
int lz = z - d / 2;
int distance = (lx * lx + ly * ly + lz * lz);
if (distance < minDistance){
minDistance = distance;
nearX = x;
nearY = y;
nearZ = z;
}
}
}
}
int index = (nearY * d + nearZ) * w + nearX;
Chunk* chunk = chunks[index];
if (chunk != nullptr)
return false;
chunk = new Chunk(nearX+ox,nearY+oy,nearZ+oz);
if (!worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels)){
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z);
}
chunks[index] = chunk;
Lighting::onChunkLoaded(ox+nearX, oy+nearY, oz+nearZ);
return true;
}
void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
for (unsigned int i = 0; i < volume; i++){
chunksSecond[i] = nullptr;
@ -395,3 +299,33 @@ void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
oy += dy;
oz += dz;
}
void Chunks::_setOffset(int x, int y, int z){
ox = x;
oy = y;
oz = z;
}
bool Chunks::putChunk(Chunk* chunk) {
int x = chunk->x;
int y = chunk->y;
int z = chunk->z;
x -= ox;
y -= oy;
z -= oz;
if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d)
return false;
chunks[(y * d + z) * w + x] = chunk;
return true;
}
void Chunks::clear(bool freeMemory){
for (size_t i = 0; i < volume; i++){
if (freeMemory){
delete chunks[i];
delete meshes[i];
}
chunks[i] = nullptr;
meshes[i] = nullptr;
}
}

View File

@ -26,20 +26,25 @@ public:
Chunks(int w, int h, int d, int ox, int oy, int oz);
~Chunks();
bool putChunk(Chunk* chunk);
Chunk* getChunk(int x, int y, int z);
Chunk* getChunkByVoxel(int x, int y, int z);
voxel* get(int x, int y, int z);
unsigned short getLight(int x, int y, int z);
unsigned char getLight(int x, int y, int z, int channel);
void set(int x, int y, int z, int id);
voxel* rayCast(vec3 start, vec3 dir, float maxLength, vec3& end, vec3& norm, vec3& iend);
bool isObstacle(int x, int y, int z);
// does not move chunks inside
void _setOffset(int x, int y, int z);
void setCenter(WorldFiles* worldFiles, int x, int y, int z);
void translate(WorldFiles* worldFiles, int x, int y, int z);
bool loadVisible(WorldFiles* worldFiles);
bool _buildMeshes(VoxelRenderer* renderer);
void clear(bool freeMemory);
};
#endif /* VOXELS_CHUNKS_H_ */

View File

@ -0,0 +1,209 @@
#include "ChunksController.h"
#include "Chunk.h"
#include "Chunks.h"
#include "WorldGenerator.h"
#include "../graphics/Mesh.h"
#include "../graphics/VoxelRenderer.h"
#include "../lighting/Lighting.h"
#include "../files/WorldFiles.h"
#include "ChunksLoader.h"
#include <iostream>
#define LOADERS_COUNT 3
ChunksController::ChunksController(Chunks* chunks, Lighting* lighting) : chunks(chunks), lighting(lighting){
loaders = new ChunksLoader*[LOADERS_COUNT];
for (int i = 0; i < LOADERS_COUNT; i++){
loaders[i] = new ChunksLoader();
}
}
ChunksController::~ChunksController(){
for (int i = 0; i < LOADERS_COUNT; i++)
delete loaders[i];
delete[] loaders;
}
bool ChunksController::loadVisible(WorldFiles* worldFiles){
const int w = chunks->w;
const int h = chunks->h;
const int d = chunks->d;
const int ox = chunks->ox;
const int oy = chunks->oy;
const int oz = chunks->oz;
int nearX = 0;
int nearY = 0;
int nearZ = 0;
int minDistance = (w/2)*(w/2);
for (int y = 0; y < h; y++){
for (int z = 2; z < d-2; z++){
for (int x = 2; x < w-2; x++){
int index = (y * d + z) * w + x;
Chunk* chunk = chunks->chunks[index];
if (chunk != nullptr)
continue;
int lx = x - w / 2;
int ly = y - h / 2;
int lz = z - d / 2;
int distance = (lx * lx + ly * ly + lz * lz);
if (distance < minDistance){
minDistance = distance;
nearX = x;
nearY = y;
nearZ = z;
}
}
}
}
int index = (nearY * d + nearZ) * w + nearX;
Chunk* chunk = chunks->chunks[index];
if (chunk != nullptr)
return false;
ChunksLoader* freeLoader = nullptr;
for (int i = 0; i < LOADERS_COUNT; i++){
ChunksLoader* loader = loaders[i];
if (loader->isBusy())
continue;
freeLoader = loader;
break;
}
if (freeLoader == nullptr)
return false;
chunk = new Chunk(nearX+ox,nearY+oy,nearZ+oz);
if (worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels))
chunk->generated = true;
chunks->chunks[index] = chunk;
Chunk* closes[27];
for (int i = 0; i < 27; i++)
closes[i] = nullptr;
for (size_t j = 0; j < chunks->volume; j++){
Chunk* other = chunks->chunks[j];
if (other == nullptr)
continue;
if (!other->ready)
continue;
int ox = other->x - chunk->x;
int oy = other->y - chunk->y;
int oz = other->z - chunk->z;
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
continue;
ox += 1;
oy += 1;
oz += 1;
closes[(oy * 3 + oz) * 3 + ox] = other;
}
freeLoader->perform(chunk, (const Chunk**)closes);
return true;
}
bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
const int w = chunks->w;
const int h = chunks->h;
const int d = chunks->d;
int nearX = 0;
int nearY = 0;
int nearZ = 0;
int minDistance = 1000000000;
for (int y = 0; y < h; y++){
for (int z = 1; z < d-1; z++){
for (int x = 1; x < w-1; x++){
int index = (y * d + z) * w + x;
Chunk* chunk = chunks->chunks[index];
if (chunk == nullptr)
continue;
Mesh* mesh = chunks->meshes[index];
if (mesh != nullptr && !chunk->modified)
continue;
if (!chunk->ready){
continue;
}
int lx = x - w / 2;
int ly = y - h / 2;
int lz = z - d / 2;
int distance = (lx * lx + ly * ly + lz * lz);
if (distance < minDistance){
minDistance = distance;
nearX = x;
nearY = y;
nearZ = z;
}
}
}
}
int index = (nearY * d + nearZ) * w + nearX;
Chunk* chunk = chunks->chunks[index];
if (chunk == nullptr){
for (int y = 0; y < h; y++){
for (int z = 1; z < d-1; z++){
for (int x = 1; x < w-1; x++){
int index = (y * d + z) * w + x;
chunk = chunks->chunks[index];
if (chunk != nullptr && chunk->ready && !chunk->accepted){
int lx = x - w / 2;
int ly = y - h / 2;
int lz = z - d / 2;
int distance = (lx * lx + ly * ly + lz * lz);
lighting->onChunkLoaded(chunk->x, chunk->y, chunk->z, false);
for (int i = 0; i < chunks->volume; i++){
Chunk* other = chunks->chunks[i];
if (other)
other->modified = true;
}
chunk->accepted = true;
std::cout << "1: built mesh for " << chunk << std::endl;
return true;
}
}
}
}
return false;
}
Mesh* mesh = chunks->meshes[index];
if (mesh == nullptr || chunk->modified){
Chunk* closes[27];
if (mesh != nullptr)
delete mesh;
if (chunk->isEmpty()){
chunks->meshes[index] = nullptr;
return false;
}
chunk->modified = false;
for (int i = 0; i < 27; i++)
closes[i] = nullptr;
for (size_t j = 0; j < chunks->volume; j++){
Chunk* other = chunks->chunks[j];
if (other == nullptr)
continue;
if (!other->ready)
continue;
int ox = other->x - chunk->x;
int oy = other->y - chunk->y;
int oz = other->z - chunk->z;
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
continue;
ox += 1;
oy += 1;
oz += 1;
closes[(oy * 3 + oz) * 3 + ox] = other;
}
mesh = renderer->render(chunk, (const Chunk**)closes);
chunks->meshes[index] = mesh;
//std::cout << "2: built mesh for " << chunk << std::endl;
return true;
}
return false;
}

View File

@ -0,0 +1,23 @@
#ifndef VOXELS_CHUNKSCONTROLLER_H_
#define VOXELS_CHUNKSCONTROLLER_H_
class Chunks;
class Lighting;
class WorldFiles;
class VoxelRenderer;
class ChunksLoader;
class ChunksController {
private:
Chunks* chunks;
Lighting* lighting;
ChunksLoader** loaders;
public:
ChunksController(Chunks* chunks, Lighting* lighting);
~ChunksController();
bool loadVisible(WorldFiles* worldFiles);
bool _buildMeshes(VoxelRenderer* renderer, int tick);
};
#endif /* VOXELS_CHUNKSCONTROLLER_H_ */

View File

@ -0,0 +1,64 @@
#include "ChunksLoader.h"
#include <chrono>
#include "Chunk.h"
#include "Chunks.h"
#include "WorldGenerator.h"
#include "../lighting/Lighting.h"
#include <iostream>
void ChunksLoader::_thread(){
Chunks chunks(3,3,3, -1,-1,-1);
Lighting lighting(&chunks);
while (working){
if (current == nullptr){
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
Chunk* chunk = current;
//std::cout << "LOADER: received chunk " << chunk->x << " " << chunk->y << " " << chunk->z << std::endl;
chunks._setOffset(chunk->x-1, chunk->y-1, chunk->z-1);
if (!chunk->generated){
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z);
//std::cout << "LOADER: generated chunk" << std::endl;
}
/*for (int i = 0; i < 27; i++){
Chunk* other = closes[i];
if (other == nullptr)
continue;
chunks.putChunk(other);
}*/
chunks.putChunk(chunk);
lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true);
chunks.clear(false);
for (int i = 0; i < 27; i++){
Chunk* other = closes[i];
delete other;
}
chunk->ready = true;
current = nullptr;
//std::cout << "LOADER: success" << std::endl;
}
}
void ChunksLoader::perform(Chunk* chunk, const Chunk** cs){
if (isBusy()){
std::cerr << "performing while busy" << std::endl;
return;
}
if (closes == nullptr){
closes = new Chunk*[27];
}
for (int i = 0; i < 27; i++){
const Chunk* other = cs[i];
if (other == nullptr)
closes[i] = nullptr;
else
closes[i] = other->clone();
}
current = chunk;
}

36
src/voxels/ChunksLoader.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef VOXELS_CHUNKSLOADER_H_
#define VOXELS_CHUNKSLOADER_H_
#include <thread>
#include <atomic>
class Chunk;
class ChunksLoader final {
private:
std::thread loaderThread;
void _thread();
std::atomic<Chunk*> current {nullptr};
std::atomic<Chunk**> closes {nullptr};
std::atomic<bool> working {true};
public:
ChunksLoader() : loaderThread{} {
loaderThread = std::thread{&ChunksLoader::_thread, this};
}
~ChunksLoader(){
working = false;
loaderThread.join();
}
bool isBusy(){
return current != nullptr;
}
void perform(Chunk* chunk, const Chunk** closes);
void stop(){
working = false;
}
};
#endif /* VOXELS_CHUNKSLOADER_H_ */

View File

@ -5,29 +5,129 @@
#include <math.h>
#include <glm/glm.hpp>
#include <glm/gtc/noise.hpp>
#define FNL_IMPL
#include "../maths/FastNoiseLite.h"
#include <time.h>
class PseudoRandom {
unsigned seed;
public:
PseudoRandom(){
seed = (unsigned)time(0);
}
int rand(){
seed = (8253729 * seed + 2396403);
return seed % 32768;
}
void setSeed(int number){
seed = (unsigned)number+8253729;
rand();
}
};
float calc_height(fnl_state *noise, int real_x, int real_z){
const float s = 0.2f;
float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f);
height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f;
height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f;
height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f;
height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f;
height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F;
height = height * 0.5f + 0.5f;
height *= height;
height *= (140.0f)*0.12f/s;
height += (42)*0.12f/s;
return height;
}
float calc_height_faster(fnl_state *noise, int real_x, int real_z){
const float s = 0.2f;
float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f);
height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f;
height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f;
height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f;
height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f;
//height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F;
height = height * 0.5f + 0.5f;
height *= height;
height *= (140.0f)*0.12f/s;
height += (42)*0.12f/s;
return height;
}
#include <iostream>
int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, int real_x, int real_y, int real_z, int tileSize){
const int tileX = floor((double)real_x/(double)tileSize);
const int tileY = floor((double)real_z/(double)tileSize);
random->setSeed(tileX*4325261+tileY*12160951+tileSize*9431111);
bool gentree = fnlGetNoise3D(noise, tileX*3.0f+633, 0.0, tileY*3.0f) > -0.1f && (random->rand() % 10) < 7;
if (!gentree)
return 0;
const int randomX = (random->rand() % (tileSize/2)) - tileSize/4;
const int randomZ = (random->rand() % (tileSize/2)) - tileSize/4;
int centerX = tileX * tileSize + tileSize/2 + randomX;
int centerY = tileY * tileSize + tileSize/2 + randomZ;
int height = (int)calc_height_faster(noise, centerX, centerY);
if (height < 55)
return 0;
int lx = real_x - centerX;
int radius = random->rand() % 4 + 3;
int ly = real_y - height - 3 * radius;
int lz = real_z - centerY;
if (lx == 0 && lz == 0 && real_y - height < 4*radius)
return 6;
if (lx*lx+ly*ly/2+lz*lz < radius*radius)
return 7;
return 0;
}
void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){
const float s = 0.25f;
fnl_state noise = fnlCreateState();
noise.noise_type = FNL_NOISE_OPENSIMPLEX2;
PseudoRandom random;
float heights[CHUNK_VOL];
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
int real_x = x + cx * CHUNK_W;
int real_z = z + cz * CHUNK_D;
float height = glm::perlin(glm::vec3(real_x*0.0125f*s,real_z*0.0125f*s, 0.0f));
height += glm::perlin(glm::vec3(real_x*0.025f*s,real_z*0.025f*s, 0.0f))*0.5f;
height += glm::perlin(glm::vec3(real_x*0.05f*s,real_z*0.05f*s, 0.0f))*0.25f;
height += glm::perlin(glm::vec3(real_x*0.1f*s,real_z*0.1f*s, 0.0f))*0.225f;
height += glm::perlin(glm::vec3(real_x*0.2f*s,real_z*0.2f*s, 0.0f))*0.125f;
height = height * 0.5f + 0.5f;
height *= height;
height *= 140.0f;
height += 48;
float height = calc_height(&noise, real_x, real_z);
heights[z*CHUNK_W+x] = height;
}
}
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
int real_x = x + cx * CHUNK_W;
int real_z = z + cz * CHUNK_D;
float height = heights[z*CHUNK_W+x];
for (int y = 0; y < CHUNK_H; y++){
int real_y = y + cy * CHUNK_H;
int id = 0;
int id = real_y < 55 ? 9 : 0;
if (real_y == (int)height)
id = 2;
else if (real_y < height)
id = 1;
else if (real_y < height){
if (real_y < height-6)
id = 8;
else
id = 1;
} else {
int tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 16);
if (tree)
id = tree;
else if ((tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 19))){
id = tree;
}else if ((tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 23))){
id = tree;
}
}
if (real_y <= 2)
id = 2;
voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id;