diff --git a/Debug/makefile b/Debug/makefile index 6d4fc22f..cbc3aa03 100644 --- a/Debug/makefile +++ b/Debug/makefile @@ -11,6 +11,7 @@ RM := rm -rf -include src/window/subdir.mk -include src/voxels/subdir.mk -include src/physics/subdir.mk +-include src/objects/subdir.mk -include src/loaders/subdir.mk -include src/lighting/subdir.mk -include src/graphics/subdir.mk diff --git a/Debug/sources.mk b/Debug/sources.mk index 580fe4b9..8671876e 100644 --- a/Debug/sources.mk +++ b/Debug/sources.mk @@ -27,6 +27,7 @@ src/files \ src/graphics \ src/lighting \ src/loaders \ +src/objects \ src/physics \ src \ src/voxels \ diff --git a/Debug/src/objects/subdir.mk b/Debug/src/objects/subdir.mk new file mode 100644 index 00000000..4757b8dd --- /dev/null +++ b/Debug/src/objects/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +CPP_SRCS += \ +../src/objects/Player.cpp + +OBJS += \ +./src/objects/Player.o + +CPP_DEPS += \ +./src/objects/Player.d + + +# Each subdirectory must supply rules for building sources it contributes +src/objects/%.o: ../src/objects/%.cpp src/objects/subdir.mk + @echo 'Building file: $<' + @echo 'Invoking: Cross G++ Compiler' + g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/src/declarations.h b/src/declarations.h new file mode 100644 index 00000000..412d2afb --- /dev/null +++ b/src/declarations.h @@ -0,0 +1,119 @@ +#ifndef DECLARATIONS_CPP +#define DECLARATIONS_CPP + +#include + +#include "graphics/Shader.h" +#include "graphics/Texture.h" +#include "window/Window.h" + +#include "voxels/Block.h" + + +Shader *shader, *linesShader, *crosshairShader; +Texture *texture; + + +// Shaders, textures, renderers +int initialize_assets() { + shader = load_shader("res/main.glslv", "res/main.glslf"); + if (shader == nullptr){ + std::cerr << "failed to load shader" << std::endl; + Window::terminate(); + return 1; + } + + crosshairShader = load_shader("res/crosshair.glslv", "res/crosshair.glslf"); + if (crosshairShader == nullptr){ + std::cerr << "failed to load crosshair shader" << std::endl; + Window::terminate(); + return 1; + } + + linesShader = load_shader("res/lines.glslv", "res/lines.glslf"); + if (linesShader == nullptr){ + std::cerr << "failed to load lines shader" << std::endl; + Window::terminate(); + return 1; + } + + texture = load_texture("res/block.png"); + if (texture == nullptr){ + std::cerr << "failed to load texture" << std::endl; + delete shader; + Window::terminate(); + return 1; + } + return 0; +} + +// Deleting GL objects like shaders, textures +void finalize_assets(){ + delete shader; + delete texture; + delete crosshairShader; + delete linesShader; +} + + +// All in-game definitions (blocks, items, etc..) +void setup_definitions() { + // AIR + Block* block = new Block(0,0); + block->drawGroup = 1; + block->lightPassing = true; + block->skyLightPassing = true; + block->obstacle = false; + Block::blocks[block->id] = block; + + // STONE + block = new Block(1,2); + Block::blocks[block->id] = block; + + // GRASS + block = new Block(2,4); + block->textureFaces[2] = 2; + block->textureFaces[3] = 1; + Block::blocks[block->id] = block; + + // LAMP + block = new Block(3,3); + block->emission[0] = 15; + block->emission[1] = 14; + block->emission[2] = 13; + Block::blocks[block->id] = block; + + // GLASS + block = new Block(4,5); + block->drawGroup = 2; + block->lightPassing = true; + Block::blocks[block->id] = block; + + // 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; +} +#endif // DECLARATIONS_CPP + diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index f0c56e9c..17fee0f0 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -1,6 +1,9 @@ #include "WorldFiles.h" #include "files.h" +#include "../window/Camera.h" +#include "../objects/Player.h" +#include "../physics/Hitbox.h" #include "../voxels/Chunk.h" union { @@ -185,9 +188,11 @@ void WorldFiles::write(){ } } -void WorldFiles::writePlayer(glm::vec3 position, float camX, float camY){ +void WorldFiles::writePlayer(Player* player){ char dst[1+3*4 + 1+2*4]; + glm::vec3 position = player->hitbox->position; + size_t offset = 0; dst[offset++] = SECTION_POSITION; float2Bytes(position.x, dst, offset); offset += 4; @@ -195,19 +200,20 @@ void WorldFiles::writePlayer(glm::vec3 position, float camX, float camY){ float2Bytes(position.z, dst, offset); offset += 4; dst[offset++] = SECTION_ROTATION; - float2Bytes(camX, dst, offset); offset += 4; - float2Bytes(camY, dst, offset); offset += 4; + float2Bytes(player->camX, dst, offset); offset += 4; + float2Bytes(player->camY, dst, offset); offset += 4; write_binary_file(getPlayerFile(), (const char*)dst, sizeof(dst)); } -bool WorldFiles::readPlayer(glm::vec3& position, float& camX, float& camY) { +bool WorldFiles::readPlayer(Player* player) { 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; } + glm::vec3 position = player->hitbox->position; size_t offset = 0; while (offset < length){ char section = data[offset++]; @@ -218,12 +224,13 @@ bool WorldFiles::readPlayer(glm::vec3& position, float& camX, float& camY) { position.z = bytes2Float(data, offset); offset += 4; break; case SECTION_ROTATION: - camX = bytes2Float(data, offset); offset += 4; - camY = bytes2Float(data, offset); offset += 4; + player->camX = bytes2Float(data, offset); offset += 4; + player->camY = bytes2Float(data, offset); offset += 4; break; } } - std::cout << position.x << " " << position.y << " " << position.z << std::endl; + player->hitbox->position = position; + player->camera->position = position + vec3(0, 1, 0); return true; } diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index 88b93f37..e79aed04 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -3,7 +3,8 @@ #include #include -#include + +class Player; #define REGION_SIZE_BIT 5 #define REGION_SIZE (1 << (REGION_SIZE_BIT)) @@ -27,12 +28,12 @@ public: void put(const char* chunkData, int x, int y); - bool readPlayer(glm::vec3& position, float& camX, float& camY); + bool readPlayer(Player* player); 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 writePlayer(Player* player); void write(); std::string getRegionFile(int x, int y); diff --git a/src/lighting/Lighting.cpp b/src/lighting/Lighting.cpp index 2e1282cb..12bca112 100644 --- a/src/lighting/Lighting.cpp +++ b/src/lighting/Lighting.cpp @@ -15,7 +15,10 @@ Lighting::Lighting(Chunks* chunks){ } Lighting::~Lighting(){ - delete solverR, solverG, solverB, solverS; + delete solverR; + delete solverG; + delete solverB; + delete solverS; } void Lighting::clear(){ @@ -38,7 +41,6 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz, bool sky){ for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ int gx = x + cx * CHUNK_W; - int gy = cy * CHUNK_H; int gz = z + cz * CHUNK_D; int light = chunk->lightmap->getS(x,0,z); @@ -195,7 +197,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 && Block::blocks[id]->skyLightPassing) + if ((vox == nullptr || vox->id != 0) && Block::blocks[id]->skyLightPassing) break; solverS->add(x,i,z, 0xF); } diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp new file mode 100644 index 00000000..5acec728 --- /dev/null +++ b/src/objects/Player.cpp @@ -0,0 +1,10 @@ +#include "Player.h" +#include "../physics/Hitbox.h" + +#include + +Player::Player(glm::vec3 position, float speed, Camera* camera) : + speed(speed), + camera(camera){ + hitbox = new Hitbox(position, vec3(0.2f,0.9f,0.2f)); +} diff --git a/src/objects/Player.h b/src/objects/Player.h new file mode 100644 index 00000000..335cb5cd --- /dev/null +++ b/src/objects/Player.h @@ -0,0 +1,19 @@ +#ifndef SRC_OBJECTS_PLAYER_H_ +#define SRC_OBJECTS_PLAYER_H_ + +#include + +class Camera; +class Hitbox; + +class Player { +public: + float speed; + Camera* camera; + Hitbox* hitbox; + float camX, camY; + Player(glm::vec3 position, float speed, Camera* camera); + ~Player(); +}; + +#endif /* SRC_OBJECTS_PLAYER_H_ */ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 05f4e47e..53b8b785 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -38,245 +37,19 @@ using namespace glm; #include "physics/Hitbox.h" #include "physics/PhysicsSolver.h" +#include "objects/Player.h" + +#include "declarations.h" +#include "world_render.h" + int WIDTH = 1280; int HEIGHT = 720; -float vertices[] = { - // x y - -0.01f,-0.01f, - 0.01f, 0.01f, - - -0.01f, 0.01f, - 0.01f,-0.01f, -}; - -int attrs[] = { - 2, 0 //null terminator -}; - -Mesh *crosshair; -Shader *shader, *linesShader, *crosshairShader; -Texture *texture; -LineBatch *lineBatch; - Chunks* chunks; WorldFiles* wfile; bool occlusion = false; -// All in-game definitions (blocks, items, etc..) -void setup_definitions() { - // AIR - Block* block = new Block(0,0); - block->drawGroup = 1; - block->lightPassing = true; - block->skyLightPassing = true; - block->obstacle = false; - Block::blocks[block->id] = block; - - // STONE - block = new Block(1,2); - Block::blocks[block->id] = block; - - // GRASS - block = new Block(2,4); - block->textureFaces[2] = 2; - block->textureFaces[3] = 1; - Block::blocks[block->id] = block; - - // LAMP - block = new Block(3,3); - block->emission[0] = 15; - block->emission[1] = 14; - block->emission[2] = 13; - Block::blocks[block->id] = block; - - // GLASS - block = new Block(4,5); - block->drawGroup = 2; - block->lightPassing = true; - Block::blocks[block->id] = block; - - // 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 -int initialize_assets() { - shader = load_shader("res/main.glslv", "res/main.glslf"); - if (shader == nullptr){ - std::cerr << "failed to load shader" << std::endl; - Window::terminate(); - return 1; - } - - crosshairShader = load_shader("res/crosshair.glslv", "res/crosshair.glslf"); - if (crosshairShader == nullptr){ - std::cerr << "failed to load crosshair shader" << std::endl; - Window::terminate(); - return 1; - } - - linesShader = load_shader("res/lines.glslv", "res/lines.glslf"); - if (linesShader == nullptr){ - std::cerr << "failed to load lines shader" << std::endl; - Window::terminate(); - return 1; - } - - texture = load_texture("res/block.png"); - if (texture == nullptr){ - std::cerr << "failed to load texture" << std::endl; - delete shader; - Window::terminate(); - return 1; - } - 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.71f,0.73f,1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // Draw VAO - shader->use(); - shader->uniformMatrix("u_proj", camera->getProjection()); - 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.71f,0.73f); - shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); - texture->bind(); - - std::vector indices; - - for (size_t i = 0; i < chunks->volume; i++){ - Chunk* chunk = chunks->chunks[i]; - if (chunk == nullptr) - continue; - if (chunks->meshes[i] != nullptr) - indices.push_back(i); - } - - std::sort(indices.begin(), indices.end(), chunks_comparator); - - - 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(); - linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView()); - glLineWidth(2.0f); - lineBatch->render(); -} - -// Deleting GL objects like shaders, textures -void finalize_assets(){ - delete shader; - delete texture; - delete crosshair; - delete crosshairShader; - delete linesShader; - delete lineBatch; -} // Save all world data to files void write_world(){ @@ -313,30 +86,24 @@ int main() { wfile = new WorldFiles("world/", REGION_VOL * (CHUNK_VOL * 2 + 8)); chunks = new Chunks(34,1,34, 0,0,0); - float camX = 0.0f; - float camY = 0.0f; - wfile->readPlayer(camera->position, camX, camY); + Player* player = new Player(vec3(camera->position), 5.0f, camera); + wfile->readPlayer(player); 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)); + camera->rotate(player->camY, player->camX, 0); VoxelRenderer renderer(1024*1024); - lineBatch = new LineBatch(4096); PhysicsSolver physics(vec3(0,-16.0f,0)); Lighting lighting(chunks); - crosshair = new Mesh(vertices, 4, attrs); + init_renderer(); ChunksController chunksController(chunks, &lighting); float lastTime = glfwGetTime(); float delta = 0.0f; - float playerSpeed = 5.0f; - int choosenBlock = 1; long frame = 0; @@ -369,10 +136,11 @@ int main() { } // Controls + Hitbox* hitbox = player->hitbox; bool sprint = Events::pressed(GLFW_KEY_LEFT_CONTROL); bool shift = Events::pressed(GLFW_KEY_LEFT_SHIFT) && hitbox->grounded && !sprint; - float speed = playerSpeed; + float speed = player->speed; int substeps = (int)(delta * 1000); substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps)); physics.step(chunks, hitbox, delta, substeps, shift); @@ -422,18 +190,18 @@ int main() { chunksController.loadVisible(wfile); if (Events::_cursor_locked){ - camY += -Events::deltaY / Window::height * 2; - camX += -Events::deltaX / Window::height * 2; + player->camY += -Events::deltaY / Window::height * 2; + player->camX += -Events::deltaX / Window::height * 2; - if (camY < -radians(89.0f)){ - camY = -radians(89.0f); + if (player->camY < -radians(89.0f)){ + player->camY = -radians(89.0f); } - if (camY > radians(89.0f)){ - camY = radians(89.0f); + if (player->camY > radians(89.0f)){ + player->camY = radians(89.0f); } camera->rotation = mat4(1.0f); - camera->rotate(camY, camX, 0); + camera->rotate(player->camY, player->camX, 0); } { @@ -462,16 +230,17 @@ int main() { } } } - draw_world(camera); + draw_world(camera, shader, texture, crosshairShader, linesShader, chunks, occlusion); Window::swapBuffers(); Events::pullEvents(); } - wfile->writePlayer(hitbox->position, camX, camY); + wfile->writePlayer(player); write_world(); close_world(); + finalize_renderer(); finalize_assets(); Window::terminate(); return 0; diff --git a/src/world_render.h b/src/world_render.h new file mode 100644 index 00000000..630736da --- /dev/null +++ b/src/world_render.h @@ -0,0 +1,152 @@ +#ifndef WORLD_RENDERER_CPP +#define WORLD_RENDERER_CPP + +#include +#include +#include + +#include +#include +#include + +#include "window/Window.h" +#include "window/Camera.h" +#include "graphics/Mesh.h" +#include "graphics/Shader.h" +#include "graphics/Texture.h" +#include "graphics/LineBatch.h" +#include "voxels/Chunks.h" +#include "voxels/Chunk.h" + +float _camera_cx; +float _camera_cz; +Chunks* _chunks; + +Mesh *crosshair; + +float vertices[] = { + // x y + -0.01f,-0.01f, + 0.01f, 0.01f, + + -0.01f, 0.01f, + 0.01f,-0.01f, +}; + +int attrs[] = { + 2, 0 //null terminator +}; + +LineBatch *lineBatch; + +void init_renderer(){ + crosshair = new Mesh(vertices, 4, attrs); + lineBatch = new LineBatch(4096); +} + + +void finalize_renderer(){ + delete crosshair; + delete lineBatch; +} + +void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ + 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); +} + +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, Shader* shader, Texture* texture, + Shader* crosshairShader, Shader* linesShader, + Chunks* chunks, bool occlusion){ + glClearColor(0.7f,0.71f,0.73f,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + _chunks = chunks; + + // Draw VAO + shader->use(); + shader->uniformMatrix("u_proj", camera->getProjection()); + 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.71f,0.73f); + shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); + texture->bind(); + + std::vector indices; + + for (size_t i = 0; i < chunks->volume; i++){ + Chunk* chunk = chunks->chunks[i]; + if (chunk == nullptr) + continue; + if (chunks->meshes[i] != nullptr) + indices.push_back(i); + } + + std::sort(indices.begin(), indices.end(), chunks_comparator); + + + 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, shader, occlusion); + } + + 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(); + linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView()); + glLineWidth(2.0f); + lineBatch->render(); +} + +#endif // WORLD_RENDERER_CPP