diff --git a/resources/shaders/simple.frag b/resources/shaders/simple.frag index 2010616..0127390 100644 --- a/resources/shaders/simple.frag +++ b/resources/shaders/simple.frag @@ -12,7 +12,7 @@ uniform sampler2DArray tex; void main() { outColour = texture(tex, TexCoord); - //outColour = vec4(.9, .9, .9, 1); + // outColour = vec4(.9, .9, .9, 1); if (outColour.w == .0) discard; diff --git a/src/game.cpp b/src/game.cpp index 332418f..03feba9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12,6 +12,7 @@ #include "renderer/camera.hpp" #include "world/chunk/chunk.hpp" +#include "world/entity.hpp" #include "world/world.hpp" #include "world/block.hpp" @@ -82,16 +83,14 @@ void Game::Setup(int w, int h) { *m_logger << LOGGER_ENDL; IsDisplayOpen = true; - m_cameras["Default"] = std::make_shared(w, h); - m_activeCamera = m_cameras["Default"]; - m_activeCamera->Position = { 0, 70, 0 }; - m_activeCamera->UpdateView(); + std::shared_ptr playercamera = std::make_shared(w, h); + m_player = std::make_shared(glm::vec3(0), glm::vec3(0), playercamera); std::shared_ptr BlockDictionary = CBlockDictionary::GetInstance(); BlockDictionary->Build(); - m_world = std::make_unique(); + m_world = std::make_shared(); Texture texture; m_world->SetTextureMap(texture.LoadTextures(BlockDictionary->Textures)); @@ -132,7 +131,7 @@ void Game::Input(SDL_Event* e) { if (e->window.event == SDL_WINDOWEVENT_RESIZED) { - m_activeCamera->UpdateProjection(e->window.data1, e->window.data2); + m_player->CameraUpdateProjection(e->window.data1, e->window.data2); glViewport(0, 0, e->window.data1, e->window.data2); } @@ -152,11 +151,11 @@ void Game::Input(SDL_Event* e) { } - if (IsMouseActive) m_activeCamera->HandleMouse(*e); + if (IsMouseActive) m_player->HandleMouseSDL(*e); } - m_activeCamera->MoveCamera(state); + m_player->MoveSDL(state); } @@ -175,7 +174,8 @@ void Game::Run() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearBufferfv(GL_COLOR, 0, clear); - m_renderer->Render(m_world , m_activeCamera); + m_world->Update(m_player); + m_renderer->Render(m_world, m_player); SDL_GL_SwapWindow(m_window); diff --git a/src/game.hpp b/src/game.hpp index 18f50ad..daee357 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -22,6 +22,8 @@ class Logger; class Renderer; class Camera; + +class Player; class World; class Game { @@ -43,13 +45,11 @@ private: std::shared_ptr m_logger; - std::shared_ptr m_renderer; std::shared_ptr m_world; - std::map> m_cameras; - std::shared_ptr m_activeCamera; - + std::shared_ptr m_player; + }; #endif diff --git a/src/physics/collider.cpp b/src/physics/collider.cpp index 9ec5801..07fda40 100644 --- a/src/physics/collider.cpp +++ b/src/physics/collider.cpp @@ -26,7 +26,7 @@ float EntityCollider::m_xDepth(ColliderBox a, ColliderBox b) { float EntityCollider::m_yDepth(ColliderBox a, ColliderBox b) { - + } diff --git a/src/physics/collider.hpp b/src/physics/collider.hpp index 62c3c97..49e24f6 100644 --- a/src/physics/collider.hpp +++ b/src/physics/collider.hpp @@ -9,6 +9,12 @@ public: glm::vec3 Max; }; +class Collider : public ColliderBox { +public: + +}; + +// TODO: Trees class EntityCollider { public: @@ -30,5 +36,4 @@ private: }; - #endif diff --git a/src/renderer/camera.cpp b/src/renderer/camera.cpp index 48dce0d..9c55d62 100644 --- a/src/renderer/camera.cpp +++ b/src/renderer/camera.cpp @@ -1,18 +1,37 @@ #include "camera.hpp" -Camera::Camera(int w, int h) { +Camera::Camera() { - projMatrix = glm::perspective(glm::radians(45.0f), (float)w / float(h), 0.1f, 1000.0f); + projMatrix = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 1000.0f); - roll = 0.0f; - pitch = 0.0f; - yaw = 0.0f; + Roll = 0.0f; + Pitch = 0.0f; + Yaw = 0.0f; Position = {}; LookDirection = {}; viewMatrix = {}; + UpdateView(); + +} + +Camera::Camera(int w, int h) { + + projMatrix = glm::perspective(glm::radians(45.0f), (float)w / float(h), 0.1f, 1000.0f); + + Roll = 0.0f; + Pitch = 0.0f; + Yaw = 0.0f; + + Position = {}; + LookDirection = {}; + + viewMatrix = {}; + + UpdateView(); + } void Camera::UpdateView() { @@ -23,9 +42,9 @@ void Camera::UpdateView() { glm::mat4 matYaw = glm::mat4(1.0f); //identity matrix // roll, pitch and yaw - matRoll = glm::rotate(matRoll, roll, glm::vec3(0.0f, 0.0f, 1.0f)); - matPitch = glm::rotate(matPitch, pitch, glm::vec3(1.0f, 0.0f, 0.0f)); - matYaw = glm::rotate(matYaw, yaw, glm::vec3(0.0f, 1.0f, 0.0f)); + matRoll = glm::rotate(matRoll, Roll, glm::vec3(0.0f, 0.0f, 1.0f)); + matPitch = glm::rotate(matPitch, Pitch, glm::vec3(1.0f, 0.0f, 0.0f)); + matYaw = glm::rotate(matYaw, Yaw, glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 rotate = matRoll * matPitch * matYaw; @@ -84,8 +103,8 @@ void Camera::MoveCamera(Uint8* state) { // Rotate by camera direction glm::mat2 rotate { - cos(yaw), -sin(yaw), - sin(yaw), cos(yaw) + cos(Yaw), -sin(Yaw), + sin(Yaw), cos(Yaw) }; glm::vec2 f(0.0, 1.0); @@ -134,11 +153,39 @@ void Camera::MouseMoved(glm::vec2 mouseDelta) { // note that yaw and pitch must be converted to radians. // this is done in UpdateView() by glm::rotate - yaw += MouseSensitivity * (mouseDelta.x/100); - pitch += MouseSensitivity * (mouseDelta.y/100); - pitch = glm::clamp(pitch, -M_PI/2, M_PI/2); + Yaw += MouseSensitivity * (mouseDelta.x/100); + Pitch += MouseSensitivity * (mouseDelta.y/100); + Pitch = glm::clamp(Pitch, -M_PI/2, M_PI/2); UpdateView(); } +void Camera::UpdatePosition(glm::vec3 position) { + + Position = position; + + UpdateView(); + +} + +void Camera::UpdateEulerLookDirection(float roll, float pitch, float yaw) { + + Roll = roll; Pitch = pitch; Yaw = yaw; + LookDirection.x = cos(Yaw) * cos(Pitch); + LookDirection.y = sin(Yaw) * cos(Pitch); + LookDirection.z = sin(Pitch); + + UpdateView(); + +} + +void Camera::UpdateLookDirection(glm::vec3 lookDirection) { + + LookDirection = lookDirection; + Pitch = asin(-lookDirection.y); + Yaw = atan2(lookDirection.x, lookDirection.z); + + UpdateView(); + +} diff --git a/src/renderer/camera.hpp b/src/renderer/camera.hpp index 06e0bde..acbe1a0 100644 --- a/src/renderer/camera.hpp +++ b/src/renderer/camera.hpp @@ -5,31 +5,41 @@ class Camera { public: + Camera(); Camera(int w, int h); void UpdateView(); glm::mat4 GetViewMatrix(); glm::mat4 GetProjectionMatrix(); + glm::mat4 GetFrustrumMatrix(); void UpdateProjection(int width, int height); - void HandleMouse(SDL_Event e); + // Keyboard void MoveCamera(Uint8* state); + // Mouse + void HandleMouse(SDL_Event e); + // Mouse Delta void MouseMoved(glm::vec2 mouseDelta); + // Updatable by float MouseSensitivity = 0.1f; float CameraSpeed = 2.0f; + void UpdatePosition(glm::vec3 position); + void UpdateEulerLookDirection(float roll, float pitch, float yaw); + void UpdateLookDirection(glm::vec3 lookDirection); + glm::vec3 Position = {}; + float Roll, Pitch, Yaw; glm::vec3 LookDirection = {}; private: - float roll, pitch, yaw; glm::mat4 viewMatrix = {}; glm::mat4 projMatrix = {}; - + }; #endif diff --git a/src/renderer/frustrum.cpp b/src/renderer/frustrum.cpp new file mode 100644 index 0000000..43a2d1a --- /dev/null +++ b/src/renderer/frustrum.cpp @@ -0,0 +1,3 @@ +#include "frustrum.hpp" + + diff --git a/src/renderer/frustrum.hpp b/src/renderer/frustrum.hpp new file mode 100644 index 0000000..cefa7e6 --- /dev/null +++ b/src/renderer/frustrum.hpp @@ -0,0 +1,35 @@ +#ifndef MINECRAFT_RENDERER_FRUSTRUM_H_ +#define MINECRAFT_RENDERER_FRUSTRUM_H_ + +#include "../common.hpp" + +namespace EFrustrumPlanes { + + enum Planes { + + Right, + Left, + Top, + Bottom, + Far, + Near + + }; + +}; + +class FrustrumPlane { +public: + + + +}; + +class Frustrum { +public: + + + +}; + +#endif diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 8cb01f3..f927606 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -9,8 +9,8 @@ Renderer::Renderer() { } // Perform the render passes -void Renderer::Render(std::shared_ptr world, std::shared_ptr camera) { +void Renderer::Render(std::shared_ptr world, std::shared_ptr entity) { - world->Render(camera); + world->Render(entity); } diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index 1ad3151..3edbec3 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -3,7 +3,7 @@ #include "../common.hpp" -class Camera; +class Entity; class World; // Does GL render passes then returns to the game loop @@ -11,7 +11,7 @@ class Renderer { public: Renderer(); - void Render(std::shared_ptr world, std::shared_ptr camera); + void Render(std::shared_ptr world, std::shared_ptr entity); }; diff --git a/src/world/block.cpp b/src/world/block.cpp index 253c441..39b400d 100644 --- a/src/world/block.cpp +++ b/src/world/block.cpp @@ -21,6 +21,7 @@ std::shared_ptr CBlockDictionary::GetInstance() { void CBlockDictionary::Build() { + // Order matters ! RegisterTexture("stone.png"); RegisterTexture("dirt.png"); RegisterTexture("grass_side.png"); diff --git a/src/world/chunk/chunk.cpp b/src/world/chunk/chunk.cpp index 8284e0d..d46c902 100644 --- a/src/world/chunk/chunk.cpp +++ b/src/world/chunk/chunk.cpp @@ -53,7 +53,7 @@ Chunk::Chunk(int x, int z, std::shared_ptr terrainGenerator) { continue; } - if (pow(y / (float)CHUNK_HEIGHT, 1.1024f) + terrainGenerator->GetValueFractal(x + (Z * CHUNK_WIDTH), y, z + (X * CHUNK_DEPTH)) * 0.60f < 0.5f) { + if (pow((y / (float)CHUNK_HEIGHT), 1.1024f) + terrainGenerator->GetNoise(x + (Z * CHUNK_WIDTH), y, z + (X * CHUNK_DEPTH)) * 0.40f < 0.5f) { Voxels.push_back((uint8_t)EBlockType::Grass); continue; @@ -149,9 +149,23 @@ void Chunk::Load() { } +void Chunk::Unload() { + + m_vertices.clear(); + m_uvs.clear(); + + glBindVertexArray(m_vao); + + glDeleteBuffers(1, &m_vbo); + glDeleteVertexArrays(1, &m_vao); + + Loaded = false; + +} + void Chunk::UploadMesh() { - if (!MeshReady) + if (!MeshReady || !Loaded) return; glGenVertexArrays(1, &m_vao); @@ -187,7 +201,7 @@ void Chunk::UploadMesh() { void Chunk::Render(std::shared_ptr camera, std::shared_ptr shader) { - if (!Loaded) + if (!MeshReady || !Loaded) return; shader->Use(); @@ -276,4 +290,6 @@ void Chunk::m_mesh() { Chunk::~Chunk() { + Unload(); + } diff --git a/src/world/chunk/chunk.hpp b/src/world/chunk/chunk.hpp index 2588a2c..0422df7 100644 --- a/src/world/chunk/chunk.hpp +++ b/src/world/chunk/chunk.hpp @@ -23,6 +23,7 @@ public: Chunk(int x, int z, std::shared_ptr terrainGenerator); void Load(); + void Unload(); void UploadMesh(); bool MeshReady = false; diff --git a/src/world/entity.cpp b/src/world/entity.cpp index f05e3ff..9e14d4f 100644 --- a/src/world/entity.cpp +++ b/src/world/entity.cpp @@ -1,3 +1,59 @@ #include "entity.hpp" +#include "../renderer/camera.hpp" +Entity::Entity(glm::vec3 postion, glm::vec3 direction, std::shared_ptr camera) + : Position(Position) + , Direction(direction) + , EntityCamera(camera) + { + + if (EntityCamera) { + EntityCamera->UpdateView(); + } +} + +Player::Player(glm::vec3 position, glm::vec3 direction, std::shared_ptr camera) + : Entity(position, direction, camera) { + + Position = { 0, 64, 0 }; + EntityCamera->Position = { Position.x, Position.y + EyePosition, Position.z }; + EntityCamera->UpdateView(); + +} + +void Player::MoveSDL(Uint8* state) { + + EntityCamera->MoveCamera(state); + Position = EntityCamera->Position; + Position.y -= EyePosition; + +} + +void Player::HandleMouseSDL(SDL_Event e) { + + EntityCamera->HandleMouse(e); + Direction = EntityCamera->LookDirection; + +} + +void Player::UpdatePosition(glm::vec3 position) { + + Position = position; + EntityCamera->UpdatePosition({ Position.x, Position.y + EyePosition, Position.z }); + +} + + +void Player::UpdateDirection(glm::vec3 direction) { + + Direction = direction; + EntityCamera->UpdateLookDirection(direction); + +} + +void Player::CameraUpdateProjection(int xres, int yres) { + + EntityCamera->UpdateProjection(xres, yres); + +} diff --git a/src/world/entity.hpp b/src/world/entity.hpp index cc03f15..ade36b9 100644 --- a/src/world/entity.hpp +++ b/src/world/entity.hpp @@ -3,26 +3,48 @@ #include "../common.hpp" +class Camera; + +class Collider; + class Entity { public: - Entity(); + Entity(glm::vec3 position, glm::vec3 direction = { 0.0f, 0.0f, 0.0f }, std::shared_ptr camera = std::make_shared()); - // World position + // World position, 1.7 units below the + // camera position. glm::vec3 Position; - // Look direction + // Look direction of the camera glm::vec3 Direction; - // Velocity in direction // of movement glm::vec3 Velocity; - // Collider + // Can be null + std::shared_ptr EntityCamera; + // Collider + // std::unique_ptr EntityCollider; // Mesh (or reference to) +}; +class Player : public Entity { +public: + + Player(glm::vec3 position, glm::vec3 direction, std::shared_ptr camera); + + float EyePosition = 1.7f; + + void MoveSDL(Uint8* state); + void HandleMouseSDL(SDL_Event e); + + void UpdatePosition(glm::vec3 position); + void UpdateDirection(glm::vec3 direction); + + void CameraUpdateProjection(int xres, int yres); }; diff --git a/src/world/generator/chunkgenerator.hpp b/src/world/generator/chunkgenerator.hpp index 139597f..1425a26 100644 --- a/src/world/generator/chunkgenerator.hpp +++ b/src/world/generator/chunkgenerator.hpp @@ -1,2 +1,6 @@ +#ifndef MINECRAFT_WORLD_GENERATOR_CHUNKGENERATOR_H_ +#define MINECRAFT_WORLD_GENERATOR_CHUNKGENERATOR_H_ + +#endif diff --git a/src/world/generator/chunkmanager.hpp b/src/world/generator/chunkmanager.hpp new file mode 100644 index 0000000..8420177 --- /dev/null +++ b/src/world/generator/chunkmanager.hpp @@ -0,0 +1,28 @@ +#ifndef MINECRAFT_WORLD_GENERATOR_CUNKMANAGER_H_ +#define MINECRAFT_WORLD_GENERATOR_CUNKMANAGER_H_ + +#include "../../common.hpp" + + +class Frustrum; + +class ChunkManager { +public: + + // Instatntiated + ChunkManager(); + + void Update(); + + void Play(); + void Pause(); + + void LoadChunksAroundWorldPoint(glm::vec3 worldPoint); + + + + void CullFrustrumFromRenderQueue(); + +}; + +#endif diff --git a/src/world/world.cpp b/src/world/world.cpp index 92c2a53..f7e3fbb 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -1,12 +1,17 @@ #include "world.hpp" +#include +#include + #include "chunk/chunk.hpp" #include "../renderer/shader.hpp" -#include "../config.hpp" #include "../util/fastnoise.hpp" +#include "../config.hpp" +#include "entity.hpp" + World::World() { } @@ -22,10 +27,11 @@ void World::LoadWorld() { m_noiseGenerator = std::make_shared(); m_noiseGenerator->SetSeed(rand()); - m_noiseGenerator->SetNoiseType(FastNoise::SimplexFractal); + m_noiseGenerator->SetNoiseType(FastNoise::ValueFractal); m_noiseGenerator->SetFractalOctaves(5); + // Generate a 54x54 chunk world for (int x = -4; x < 50; x++) for (int y = -50; y < 4; y++) { @@ -54,9 +60,17 @@ void World::SetTextureMap(GLuint map) { } -glm::vec2 World::GetChunkCoords(glm::vec3 wordCoords) { +glm::vec3 World::GetChunkCoords(glm::vec3 worldCoords) { - return { wordCoords.x / CHUNK_WIDTH, wordCoords.z / CHUNK_DEPTH }; + return { worldCoords.x / static_cast(CHUNK_WIDTH), + worldCoords.y / static_cast(CHUNK_HEIGHT), + worldCoords.z / static_cast(CHUNK_DEPTH) }; + +} + +glm::vec2 World::GetChunk(glm::vec3 worldCoords) { + + return { static_cast(worldCoords.x / CHUNK_WIDTH), static_cast(worldCoords.z / CHUNK_DEPTH) }; } @@ -69,12 +83,12 @@ std::vector> World::GetRenderableChunks() { // Should the chunk be rendererd ? if (chunk.second->ShouldRender) { - m_chunkMutex.lock(); + m_chunkLoderMutex.lock(); if (chunk.second->MeshReady) chunk.second->UploadMesh(); - m_chunkMutex.unlock(); + m_chunkLoderMutex.unlock(); // If not, add it chunks.push_back(chunk.second); @@ -87,7 +101,26 @@ std::vector> World::GetRenderableChunks() { } -void World::Render(std::shared_ptr camera) { +void World::Update(std::shared_ptr player) { + + // glm::vec2 inChunk = GetChunk(player->Position); + + // if (m_chunks.find(inChunk) == m_chunks.end()) { + + // m_chunkLoderMutex.lock(); + + // m_chunkLoaderQueue.push(inChunk); + + // m_chunkLoderMutex.unlock(); + + // } + + // std::cout << "Position: " << player->Position.x << ":" << player->Position.y << ":" << player->Position.z << std::endl; + // std::cout << "Chunk: " << inChunk.x << ":" << inChunk.y << std::endl << std::endl; + +} + +void World::Render(std::shared_ptr player) { glBindTexture(GL_TEXTURE_2D_ARRAY, m_textureMapID); @@ -96,7 +129,7 @@ void World::Render(std::shared_ptr camera) { for (int i = 0; i < chunks.size(); i++) { - chunks[i]->Render(camera, m_shaders["Basic"]); + chunks[i]->Render(player->EntityCamera, m_shaders["Basic"]); } @@ -112,30 +145,36 @@ World::~World() { } + for (auto& chunk : m_chunks) { + + chunk.second->Unload(); + + } + } void World::m_loadChunks() { while (m_generatorRunning) { - m_chunkMutex.lock(); + m_chunkLoderMutex.lock(); glm::vec2 coords = m_chunkLoaderQueue.front(); m_chunkLoaderQueue.pop(); - m_chunkMutex.unlock(); + m_chunkLoderMutex.unlock(); std::shared_ptr loadingChunk = std::make_shared(coords.x, coords.y, m_noiseGenerator); + loadingChunk->ShouldRender = true; std::cout << "Loaded chunk " << coords.x << ":" << coords.y << std::endl; - m_chunkMutex.lock(); + m_chunkLoderMutex.lock(); m_chunks[coords] = loadingChunk; - m_chunks[coords]->ShouldRender = true; - m_chunkMutex.unlock(); + m_chunkLoderMutex.unlock(); while (m_chunkLoaderQueue.empty()) { diff --git a/src/world/world.hpp b/src/world/world.hpp index 1f793f6..771dedc 100644 --- a/src/world/world.hpp +++ b/src/world/world.hpp @@ -5,6 +5,7 @@ #include "../renderer/camera.hpp" +#include "generator/chunkmanager.hpp" #include "chunk/chunk.hpp" #include @@ -15,6 +16,7 @@ class FastNoise; class Shader; +class Entity; class World { public: @@ -22,19 +24,22 @@ public: // Default constructor World(); - // Preps the render threads and loads all of the shaders void LoadWorld(); void SetTextureMap(GLuint map); // Takes world coordinates and gets a chunks coordinates - glm::vec2 GetChunkCoords(glm::vec3 wordCoords); + glm::vec3 GetChunkCoords(glm::vec3 wordCoords); + + // Takes world coordinates and gets the chunk those coorinates + // fall in + glm::vec2 GetChunk(glm::vec3 worldCoords); std::vector> GetRenderableChunks(); - - void Render(std::shared_ptr camera); + void Update(std::shared_ptr player); + void Render(std::shared_ptr player); ~World(); @@ -58,10 +63,11 @@ private: // Indexed by chunk coorinates std::unordered_map> m_chunks; + std::mutex m_chunkUpdaterMutex; std::queue m_chunkUpdatesQueue; - std::queue m_chunkLoaderQueue; - std::mutex m_chunkMutex; + std::mutex m_chunkLoderMutex; + std::queue m_chunkLoaderQueue; // Generator std::shared_ptr m_noiseGenerator;