Compare commits

17 Commits

Author SHA1 Message Date
benkyd
aefe55e314 ok epic 2022-05-11 13:36:24 +00:00
Benjamin Kyd
ae8b69b96d Merge pull request #12 from benkyd/add-license-1
Create LICENSE
2021-03-02 17:46:50 +00:00
Benjamin Kyd
9c40baacb6 Create LICENSE 2021-03-02 17:46:42 +00:00
Ben
6e42ac9e8b voxel meshes perhaps 2021-03-02 17:42:24 +00:00
Ben
9f9daa3a6e renderer structure 2021-02-17 03:47:08 +00:00
Ben Kyd
fb75f6b8d6 welp picking this project back up 2021-02-12 00:43:19 +00:00
Ben
2872ac6268 face? 2020-05-28 17:10:02 +01:00
Ben
e4dbfa672c done barely anything smh 2020-05-20 01:12:18 +01:00
Ben
24d95d1ad4 fixed smh 2020-05-16 22:04:27 +01:00
Ben
05ff8543bb added old files which will work fine 2020-05-16 20:04:38 +01:00
Ben
4e5a1bec24 some OpenGL boilerplate 2020-05-16 19:59:46 +01:00
Ben
72a359bce7 added back legacy code 2020-05-15 15:12:13 +01:00
Ben
8f9318c83a merge 2020-05-15 15:10:22 +01:00
Ben
1ce214bf7f Started complete rewrite, i learned an awful lot but this is unsalvegable 2020-05-15 14:59:51 +01:00
Benjamin Kyd
a81d6bd00f Merge pull request #10 from plane000/dev
Dev
2019-11-23 16:28:05 +00:00
Ben
7e859edd8e btuhs 2019-11-18 02:12:31 +00:00
Ben Kyd
b2ac1f3757 dynamic chunk loader issues - dyre nead of refractor 2019-11-14 15:20:22 +00:00
40 changed files with 96 additions and 21573 deletions

View File

@@ -1,10 +1,9 @@
cmake_minimum_required(VERSION 3.7)
project(OpenGLPlayground)
project(MingeCraft)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CMakeModules/)
cmake_policy(SET CMP0037 OLD)
set(CMAKE_BUILD_TYPE Debug)
# set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-Ofast")
set(executable output)
@@ -16,6 +15,7 @@ add_definitions(-DMC_RESOURCES="${CMAKE_SOURCE_DIR}/resources/")
message(${CMAKE_SOURCE_DIR}/resources)
if (UNIX)
find_package(glm REQUIRED)
find_package(SDL2 REQUIRED)
endif(UNIX)
@@ -46,23 +46,23 @@ include_directories(${executable}
file(GLOB SourceFiles
${SrcDIR}/*
${SrcDIR}/util/*
${SrcDIR}/game/*
${SrcDIR}/world/*
${SrcDIR}/world/chunk/*
${SrcDIR}/renderer/*
${SrcDIR}/ThirdParty/*
${SrcDIR}/Rendering/*
${SrcDIR}/Rendering/Platform/*
${SrcDIR}/World/*
)
add_executable(${executable} ${SourceFiles})
set_target_properties(${executable} PROPERTIES
CXX_STANDARD 17
CXX_EXTENSIONS OFF
CXX_STANDARD 20
CXX_EXTENSIONS ON
)
if (UNIX)
target_link_libraries(${executable}
SDL2
glm
OpenGL::OpenGL
OpenGL::GL
Threads::Threads

View File

@@ -3,6 +3,7 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/hash.hpp>
#include <glm/glm.hpp>

View File

@@ -1,16 +0,0 @@
#ifndef MINECRAFT_CONFIG_H_
#define MINECRAFT_CONFIG_H_
#include "common.hpp"
class Config {
public:
std::string ResourceBase = MC_RESOURCES;
// std::string ResourceBase = "E:/Games/minecraft/resources/";
};
static Config GameConfig;
#endif

View File

@@ -1,184 +0,0 @@
#include "game.hpp"
// For glm::vec2 as the key of a hashmap
#define GLM_ENABLE_EXPERIMENTAL
#define LOGGER_DEFINITION
#include <logger.h>
#include "renderer/renderer.hpp"
#include "renderer/texture.hpp"
#include "renderer/shader.hpp"
#include "renderer/camera.hpp"
#include "world/chunk/chunk.hpp"
#include "world/entity.hpp"
#include "world/world.hpp"
#include "world/block.hpp"
#include "common.hpp"
#include "config.hpp"
Game::Game() {
}
void Game::Setup(int w, int h) {
m_logger = std::make_shared<Logger>();
*m_logger << "----------------" << LOGGER_ENDL;
*m_logger << "Minecraft 1.14.2" << LOGGER_ENDL;
*m_logger << "----------------" << LOGGER_ENDL;
*m_logger << LOGGER_ENDL;
#ifdef __DEBUG
*m_logger << LOGGER_DEBUG << "Debug mode enabled" << LOGGER_ENDL;
#endif
*m_logger << LOGGER_INFO << "Initializing display" << LOGGER_ENDL;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
// Create GL window
*m_logger << LOGGER_INFO << "Creating window" << LOGGER_ENDL;
m_window = SDL_CreateWindow("Minecraft 1.14.2",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, w, h,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
// Create GL context
*m_logger << LOGGER_INFO << "Creating OpenGL context" << LOGGER_ENDL;
m_glContext = SDL_GL_CreateContext(m_window);
SDL_SetRelativeMouseMode(SDL_TRUE);
// Set VSYNC swap interval
SDL_GL_SetSwapInterval(1);
*m_logger << LOGGER_INFO << "Display set up" << LOGGER_ENDL;
// Load OpenGL
gladLoadGLLoader(SDL_GL_GetProcAddress);
glEnable(GL_MULTISAMPLE);
// glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
*m_logger << LOGGER_INFO << "Loaded OpenGL" << LOGGER_ENDL;
*m_logger << LOGGER_ENDL;
IsDisplayOpen = true;
std::shared_ptr<Camera> playercamera = std::make_shared<Camera>(w, h);
m_player = std::make_shared<Player>(glm::vec3(0), glm::vec3(0), playercamera);
std::shared_ptr<CBlockDictionary> BlockDictionary = CBlockDictionary::GetInstance();
BlockDictionary->Build();
m_world = std::make_shared<World>();
Texture texture;
m_world->SetTextureMap(texture.LoadTextures(BlockDictionary->Textures));
m_world->LoadWorld();
}
void Game::Input(SDL_Event* e) {
Uint8* state = (Uint8*)SDL_GetKeyboardState(NULL);
while (SDL_PollEvent(e)) {
switch (e->type) {
case SDL_KEYDOWN:
{
if (e->key.keysym.sym == SDLK_ESCAPE) {
IsMouseActive = !IsMouseActive;
if (IsMouseActive)
SDL_SetRelativeMouseMode(SDL_TRUE);
else
SDL_SetRelativeMouseMode(SDL_FALSE);
}
break;
}
case SDL_WINDOWEVENT:
{
if (e->window.event == SDL_WINDOWEVENT_RESIZED) {
m_player->CameraUpdateProjection(e->window.data1, e->window.data2);
glViewport(0, 0, e->window.data1, e->window.data2);
}
break;
}
case SDL_QUIT:
{
IsDisplayOpen = false;
break;
}
}
if (IsMouseActive) m_player->HandleMouseSDL(*e);
}
m_player->MoveSDL(state);
}
void Game::Run() {
SDL_Event e;
const float clear[] = { 186.0f / 255.0f, 214.0f / 255.0f, 254.0f / 255.0f };
m_renderer = std::make_unique<Renderer>();
while (IsDisplayOpen) {
Input(&e);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearBufferfv(GL_COLOR, 0, clear);
m_world->Update(m_player);
m_renderer->Render(m_world, m_player);
SDL_GL_SwapWindow(m_window);
}
}

View File

@@ -1,55 +0,0 @@
#ifndef MINECRAFT_GAME_H_
#define MINECRAFT_GAME_H_
#ifdef NDEBUG
#define __DEBUG
#endif
#define __DEBUG
// #define __IMGUI
#include <memory>
#include <string>
#include <map>
#if _WIN32
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
class Logger;
class Renderer;
class Camera;
class Player;
class World;
class Game {
public:
Game();
void Setup(int w, int h);
void Input(SDL_Event* e);
void Run();
bool IsDisplayOpen = false;
bool IsMouseActive = true;
private:
SDL_Window* m_window = nullptr;
SDL_GLContext m_glContext = nullptr;
std::shared_ptr<Logger> m_logger;
std::shared_ptr<Renderer> m_renderer;
std::shared_ptr<World> m_world;
std::shared_ptr<Player> m_player;
};
#endif

View File

@@ -1,14 +1,90 @@
#include <iostream>
#include <sstream>
#include "game.hpp"
#define LOGGER_DEFINITION
#include <logger.h>
#if _WIN32
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
#include "display.hpp"
#include "settings.hpp"
#include "Rendering/rendermaster.hpp"
#include "Rendering/texture.hpp"
#include "Rendering/camera.hpp"
#include "Rendering/mesh.hpp"
int main(int argc, char** argv) {
#define __DEBUG
Game game;
game.Setup(1080, 720);
game.Run();
static const int VERSION_MAJOR = 0;
static const int VERSION_MINOR = 0;
static const int VERSION_PATCH = 1;
return 0;
void version()
{
std::stringstream version;
const auto& container = []( std::string s ) { std::string r = ""; for ( auto& c : s ) { r += "-"; } return r; };
version << "Minecraft ";
version << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH;
std::cout << container( version.str() ) << std::endl;
std::cout << version.str() << std::endl;
std::cout << container( version.str() ) << std::endl;
}
void Loop( Display* display )
{
SDL_Event e;
while ( display->IsWindowOpen )
{
display->PrepareFrame();
// make framerate agnostic
display->Input( &e );
// rendering here
display->NextFrame();
}
// cleanup
}
int main( int argc, char** argv )
{
version();
Logger mLogger;
#ifdef __DEBUG
mLogger << LOGGER_DEBUG << "Debug mode enabled" << LOGGER_ENDL;
#endif
// settup display
std::stringstream version;
version << "Minecraft ";
version << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH;
Display display { WindowWidth, WindowHeight, version.str() };
Loop( &display );
return 0;
}

View File

@@ -1,35 +0,0 @@
#include "collider.hpp"
EntityCollider::EntityCollider() {
}
glm::vec3 EntityCollider::TerrainCollide(std::vector<uint8_t> terrain) {
}
bool EntityCollider::m_aabb(ColliderBox a, ColliderBox b) {
return {
(a.Min.x <= b.Min.x + b.Max.x && a.Min.x + a.Max.x >= b.Min.x) &&
(a.Min.y <= b.Min.y + b.Max.y && a.Min.y + a.Max.y >= b.Min.y) &&
(a.Min.z <= b.Min.z + b.Max.z && a.Min.z + a.Max.z >= b.Min.z)
};
}
float EntityCollider::m_xDepth(ColliderBox a, ColliderBox b) {
}
float EntityCollider::m_yDepth(ColliderBox a, ColliderBox b) {
}
float EntityCollider::m_zDepth(ColliderBox a, ColliderBox b) {
}

View File

@@ -1,39 +0,0 @@
#ifndef MINECRAFT_PHYSICS_COLLIDER_H_
#define MINECRAFT_PHYSICS_COLLIDER_H_
#include "../common.hpp"
class ColliderBox {
public:
glm::vec3 Min;
glm::vec3 Max;
};
class Collider : public ColliderBox {
public:
};
// TODO: Trees
class EntityCollider {
public:
EntityCollider();
// Surrounding blocks indexed XYZ
// Returns point of collision
glm::vec3 TerrainCollide(std::vector<uint8_t> surroundingBlocks);
ColliderBox Bounds;
private:
bool m_aabb(ColliderBox a, ColliderBox b);
float m_xDepth(ColliderBox a, ColliderBox b);
float m_yDepth(ColliderBox a, ColliderBox b);
float m_zDepth(ColliderBox a, ColliderBox b);
};
#endif

View File

@@ -1,191 +0,0 @@
#include "camera.hpp"
Camera::Camera() {
projMatrix = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 1000.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() {
// roll can be removed
glm::mat4 matRoll = glm::mat4(1.0f); //identity matrix;
glm::mat4 matPitch = glm::mat4(1.0f);//identity matrix
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));
glm::mat4 rotate = matRoll * matPitch * matYaw;
glm::mat4 translate = glm::mat4(1.0f);
translate = glm::translate(translate, -Position);
viewMatrix = rotate * translate;
// Work out Look Vector
glm::mat4 inverseView = glm::inverse(viewMatrix);
LookDirection.x = inverseView[2][0];
LookDirection.y = inverseView[2][1];
LookDirection.z = inverseView[2][2];
}
glm::mat4 Camera::GetViewMatrix() {
return viewMatrix;
}
glm::mat4 Camera::GetProjectionMatrix() {
return projMatrix;
}
void Camera::UpdateProjection(int width, int height) {
projMatrix = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 1000.0f);
}
void Camera::HandleMouse(SDL_Event e) {
if (e.type != SDL_MOUSEMOTION)
return;
float mouseDX = e.motion.xrel;
float mouseDY = e.motion.yrel;
glm::vec2 mouseDelta{ mouseDX, mouseDY };
MouseMoved(mouseDelta);
}
void Camera::MoveCamera(Uint8* state) {
float dx = 0;
float dz = 0;
float dy = 0;
// Rotate by camera direction
glm::mat2 rotate {
cos(Yaw), -sin(Yaw),
sin(Yaw), cos(Yaw)
};
glm::vec2 f(0.0, 1.0);
f = f * rotate;
if (state[SDL_SCANCODE_W]) {
dz -= f.y;
dx -= f.x;
}
if (state[SDL_SCANCODE_S]) {
dz += f.y;
dx += f.x;
}
if (state[SDL_SCANCODE_A]) {
dz += f.x;
dx += -f.y;
}
if (state[SDL_SCANCODE_D]) {
dz -= f.x;
dx -= -f.y;
}
if (state[SDL_SCANCODE_SPACE]) {
dy += 1;
}
if (state[SDL_SCANCODE_LSHIFT]) {
dy -= 1;
}
// get current view matrix
glm::mat4 mat = GetViewMatrix();
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
// forward vector must be negative to look forward.
// read :http://in2gpu.com/2015/05/17/view-matrix/
Position.x += dx * CameraSpeed;
Position.z += dz * CameraSpeed;
Position.y += dy * CameraSpeed;
// update the view matrix
UpdateView();
}
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<float>(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();
}

View File

@@ -1,43 +0,0 @@
#ifndef MINECRAFT_RENDERER_CAMERA_H_
#define MINECRAFT_RENDERER_CAMERA_H_
#include "../common.hpp"
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);
// Keyboard
void MoveCamera(Uint8* state);
// Mouse
void HandleMouse(SDL_Event e);
void MouseMoved(glm::vec2 mouseDelta);
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:
glm::mat4 viewMatrix = {};
glm::mat4 projMatrix = {};
};
#endif

View File

@@ -1,3 +0,0 @@
#include "frustrum.hpp"

View File

@@ -1,36 +0,0 @@
#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

View File

@@ -1,16 +0,0 @@
#include "renderer.hpp"
#include "../world/chunk/chunk.hpp"
#include "../world/world.hpp"
#include "shader.hpp"
Renderer::Renderer() {
}
// Perform the render passes
void Renderer::Render(std::shared_ptr<World> world, std::shared_ptr<Entity> entity) {
world->Render(entity);
}

View File

@@ -1,18 +0,0 @@
#ifndef MINECRAFT_RENDERER_RENDERER_H_
#define MINECRAFT_RENDERER_RENDERER_H_
#include "../common.hpp"
class Entity;
class World;
// Does GL render passes then returns to the game loop
class Renderer {
public:
Renderer();
void Render(std::shared_ptr<World> world, std::shared_ptr<Entity> entity);
};
#endif

View File

@@ -1,109 +0,0 @@
#include "shader.hpp"
Shader::Shader()
: m_fileReader() {
Program = 0;
m_frag = 0;
m_vert = 0;
m_logger = std::make_shared<Logger>();
}
void Shader::Load(std::string path) {
std::string vertexLocation = path + ".vert";
Load(vertexLocation, GL_VERTEX_SHADER);
*m_logger << LOGGER_INFO << "Vertex shader at '" << vertexLocation << "' loaded..." << LOGGER_ENDL;
std::string fragmentLocation = path + ".frag";
Load(fragmentLocation, GL_FRAGMENT_SHADER);
*m_logger << LOGGER_INFO << "Fragment shader at '" << fragmentLocation << "' loaded..." << LOGGER_ENDL;
}
void Shader::Load(std::string path, GLenum type) {
GLuint activeShader = 0;
if (type == GL_VERTEX_SHADER)
m_vert = activeShader = glCreateShader(type);
if (type == GL_FRAGMENT_SHADER)
m_frag = activeShader = glCreateShader(type);
std::string loadedShaderSource = m_fileReader.LoadTextFromFile(path);
const char* shaderSource = loadedShaderSource.c_str();
int shaderSourceLength = loadedShaderSource.length();
glShaderSource(activeShader, 1, &shaderSource, &shaderSourceLength);
}
void Shader::Link() {
if (m_vert == 0 || m_frag == 0) {
*m_logger << LOGGER_ERROR << "Failed to link programs: Both programs not present" << LOGGER_ENDL;
return;
}
glCompileShader(m_vert);
if (m_CheckShader(m_vert)) {
*m_logger << LOGGER_INFO << "Vertex shader '" << m_vert << "' compiled..." << LOGGER_ENDL;
}
glCompileShader(m_frag);
if (m_CheckShader(m_frag)) {
*m_logger << LOGGER_INFO << "Fragment shader '" << m_frag << "' compiled..." << LOGGER_ENDL;
}
Program = glCreateProgram();
glAttachShader(Program, m_vert);
glAttachShader(Program, m_frag);
glLinkProgram(Program);
glDeleteShader(m_vert);
glDeleteShader(m_frag);
*m_logger << LOGGER_INFO << "Program '" << Program << "' loaded..." << LOGGER_ENDL;
}
void Shader::Use() {
glUseProgram(Program);
}
bool Shader::m_CheckShader(GLuint uid) {
GLint status = GL_TRUE;
glGetShaderiv(uid, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
char buf[512];
glGetShaderInfoLog(uid, 512, NULL, buf);
*m_logger << LOGGER_ERROR << buf << LOGGER_ENDL;
delete buf;
return false;
}
return true;
}
Shader::~Shader() {
glDeleteProgram(Program);
glDeleteShader(m_vert);
glDeleteShader(m_frag);
}

View File

@@ -1,33 +0,0 @@
#ifndef MINECRAFT_RENDERER_SHADER_H_
#define MINECRAFT_RENDERER_SHADER_H_
#include <logger.h>
#include "../util/filereader.hpp"
#include "../common.hpp"
class Shader {
public:
Shader();
void Load(std::string path);
void Load(std::string path, GLenum type);
GLuint Program;
void Link();
void Use();
~Shader();
private:
std::shared_ptr<Logger> m_logger;
bool m_CheckShader(GLuint uid);
FileReader m_fileReader;
GLuint m_vert;
GLuint m_frag;
};
#endif

View File

@@ -1,60 +0,0 @@
#include "texture.hpp"
#include <logger.h>
#include "../config.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "../util/stb_image.hpp"
GLuint Texture::LoadTextures(std::vector<std::string> textures) {
Logger logger;
std::string basePath = GameConfig.ResourceBase + "textures/";
int x = 16;
int y = 16;
GLsizei layers = textures.size();
GLubyte* texels = (GLubyte*)malloc(x * y * 4 * layers * sizeof(GLubyte));
for (int i = 0; i < layers; i++) {
std::string path = basePath + textures[i];
int xR = 0;
int yR = 0;
int cR = 0;
unsigned char* texture = stbi_load(path.c_str(), &xR, &yR, &cR, STBI_rgb_alpha);
memcpy(texels + (i * x * y * 4), texture, x * y * 4);
stbi_image_free(texture);
logger << LOGGER_INFO << "Texture at '" << path << "' Loaded..." << LOGGER_ENDL;
}
GLuint textureArray = 0;
glGenTextures(1, &textureArray);
glBindTexture(GL_TEXTURE_2D_ARRAY, textureArray);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, x, y, layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, x, y, layers, GL_RGBA, GL_UNSIGNED_BYTE, texels);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
free(texels);
return textureArray;
}

View File

@@ -1,11 +0,0 @@
#ifndef MINECRAFT_RENDERER_TEXTURE_H_
#define MINECRAFT_RENDERER_TEXTURE_H_
#include "../common.hpp"
class Texture {
public:
GLuint LoadTextures(std::vector<std::string> textures);
};
#endif

View File

@@ -6,8 +6,8 @@
// TODO: import settings and stuff
// for now this works
static const int WindowWidth = 1920;
static const int WindowHeight = 1080;
static const int WindowWidth = 1000;
static const int WindowHeight = 600;
static const std::string ResourceBase = MC_RESOURCES;

File diff suppressed because it is too large Load Diff

View File

@@ -1,311 +0,0 @@
// FastNoise.h
//
// MIT License
//
// Copyright(c) 2017 Jordan Peck
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// The developer's email is jorzixdan.me2@gzixmail.com (for great email, take
// off every 'zix'.)
//
// VERSION: 0.4.1
#ifndef FASTNOISE_H
#define FASTNOISE_H
// Uncomment the line below to use doubles throughout FastNoise instead of floats
//#define FN_USE_DOUBLES
#define FN_CELLULAR_INDEX_MAX 3
#ifdef FN_USE_DOUBLES
typedef double FN_DECIMAL;
#else
typedef float FN_DECIMAL;
#endif
class FastNoise
{
public:
explicit FastNoise(int seed = 1337) { SetSeed(seed); CalculateFractalBounding(); }
enum NoiseType { Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, Cellular, WhiteNoise, Cubic, CubicFractal };
enum Interp { Linear, Hermite, Quintic };
enum FractalType { FBM, Billow, RigidMulti };
enum CellularDistanceFunction { Euclidean, Manhattan, Natural };
enum CellularReturnType { CellValue, NoiseLookup, Distance, Distance2, Distance2Add, Distance2Sub, Distance2Mul, Distance2Div };
// Sets seed used for all noise types
// Default: 1337
void SetSeed(int seed);
// Returns seed used for all noise types
int GetSeed() const { return m_seed; }
// Sets frequency for all noise types
// Default: 0.01
void SetFrequency(FN_DECIMAL frequency) { m_frequency = frequency; }
// Returns frequency used for all noise types
FN_DECIMAL GetFrequency() const { return m_frequency; }
// Changes the interpolation method used to smooth between noise values
// Possible interpolation methods (lowest to highest quality) :
// - Linear
// - Hermite
// - Quintic
// Used in Value, Perlin Noise and Position Warping
// Default: Quintic
void SetInterp(Interp interp) { m_interp = interp; }
// Returns interpolation method used for supported noise types
Interp GetInterp() const { return m_interp; }
// Sets noise return type of GetNoise(...)
// Default: Simplex
void SetNoiseType(NoiseType noiseType) { m_noiseType = noiseType; }
// Returns the noise type used by GetNoise
NoiseType GetNoiseType() const { return m_noiseType; }
// Sets octave count for all fractal noise types
// Default: 3
void SetFractalOctaves(int octaves) { m_octaves = octaves; CalculateFractalBounding(); }
// Returns octave count for all fractal noise types
int GetFractalOctaves() const { return m_octaves; }
// Sets octave lacunarity for all fractal noise types
// Default: 2.0
void SetFractalLacunarity(FN_DECIMAL lacunarity) { m_lacunarity = lacunarity; }
// Returns octave lacunarity for all fractal noise types
FN_DECIMAL GetFractalLacunarity() const { return m_lacunarity; }
// Sets octave gain for all fractal noise types
// Default: 0.5
void SetFractalGain(FN_DECIMAL gain) { m_gain = gain; CalculateFractalBounding(); }
// Returns octave gain for all fractal noise types
FN_DECIMAL GetFractalGain() const { return m_gain; }
// Sets method for combining octaves in all fractal noise types
// Default: FBM
void SetFractalType(FractalType fractalType) { m_fractalType = fractalType; }
// Returns method for combining octaves in all fractal noise types
FractalType GetFractalType() const { return m_fractalType; }
// Sets distance function used in cellular noise calculations
// Default: Euclidean
void SetCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction) { m_cellularDistanceFunction = cellularDistanceFunction; }
// Returns the distance function used in cellular noise calculations
CellularDistanceFunction GetCellularDistanceFunction() const { return m_cellularDistanceFunction; }
// Sets return type from cellular noise calculations
// Note: NoiseLookup requires another FastNoise object be set with SetCellularNoiseLookup() to function
// Default: CellValue
void SetCellularReturnType(CellularReturnType cellularReturnType) { m_cellularReturnType = cellularReturnType; }
// Returns the return type from cellular noise calculations
CellularReturnType GetCellularReturnType() const { return m_cellularReturnType; }
// Noise used to calculate a cell value if cellular return type is NoiseLookup
// The lookup value is acquired through GetNoise() so ensure you SetNoiseType() on the noise lookup, value, Perlin or simplex is recommended
void SetCellularNoiseLookup(FastNoise* noise) { m_cellularNoiseLookup = noise; }
// Returns the noise used to calculate a cell value if the cellular return type is NoiseLookup
FastNoise* GetCellularNoiseLookup() const { return m_cellularNoiseLookup; }
// Sets the 2 distance indices used for distance2 return types
// Default: 0, 1
// Note: index0 should be lower than index1
// Both indices must be >= 0, index1 must be < 4
void SetCellularDistance2Indices(int cellularDistanceIndex0, int cellularDistanceIndex1);
// Returns the 2 distance indices used for distance2 return types
void GetCellularDistance2Indices(int& cellularDistanceIndex0, int& cellularDistanceIndex1) const;
// Sets the maximum distance a cellular point can move from its grid position
// Setting this high will make artifacts more common
// Default: 0.45
void SetCellularJitter(FN_DECIMAL cellularJitter) { m_cellularJitter = cellularJitter; }
// Returns the maximum distance a cellular point can move from its grid position
FN_DECIMAL GetCellularJitter() const { return m_cellularJitter; }
// Sets the maximum warp distance from original location when using GradientPerturb{Fractal}(...)
// Default: 1.0
void SetGradientPerturbAmp(FN_DECIMAL gradientPerturbAmp) { m_gradientPerturbAmp = gradientPerturbAmp; }
// Returns the maximum warp distance from original location when using GradientPerturb{Fractal}(...)
FN_DECIMAL GetGradientPerturbAmp() const { return m_gradientPerturbAmp; }
//2D
FN_DECIMAL GetValue(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetValueFractal(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetPerlin(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetPerlinFractal(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetSimplex(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetSimplexFractal(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetCellular(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetWhiteNoise(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetWhiteNoiseInt(int x, int y) const;
FN_DECIMAL GetCubic(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetCubicFractal(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL GetNoise(FN_DECIMAL x, FN_DECIMAL y) const;
void GradientPerturb(FN_DECIMAL& x, FN_DECIMAL& y) const;
void GradientPerturbFractal(FN_DECIMAL& x, FN_DECIMAL& y) const;
//3D
FN_DECIMAL GetValue(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetValueFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetPerlin(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetPerlinFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetSimplex(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetSimplexFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetCellular(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetWhiteNoise(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetWhiteNoiseInt(int x, int y, int z) const;
FN_DECIMAL GetCubic(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetCubicFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL GetNoise(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
void GradientPerturb(FN_DECIMAL& x, FN_DECIMAL& y, FN_DECIMAL& z) const;
void GradientPerturbFractal(FN_DECIMAL& x, FN_DECIMAL& y, FN_DECIMAL& z) const;
//4D
FN_DECIMAL GetSimplex(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z, FN_DECIMAL w) const;
FN_DECIMAL GetWhiteNoise(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z, FN_DECIMAL w) const;
FN_DECIMAL GetWhiteNoiseInt(int x, int y, int z, int w) const;
private:
unsigned char m_perm[512];
unsigned char m_perm12[512];
int m_seed = 1337;
FN_DECIMAL m_frequency = FN_DECIMAL(0.01);
Interp m_interp = Quintic;
NoiseType m_noiseType = Simplex;
int m_octaves = 3;
FN_DECIMAL m_lacunarity = FN_DECIMAL(2);
FN_DECIMAL m_gain = FN_DECIMAL(0.5);
FractalType m_fractalType = FBM;
FN_DECIMAL m_fractalBounding;
CellularDistanceFunction m_cellularDistanceFunction = Euclidean;
CellularReturnType m_cellularReturnType = CellValue;
FastNoise* m_cellularNoiseLookup = nullptr;
int m_cellularDistanceIndex0 = 0;
int m_cellularDistanceIndex1 = 1;
FN_DECIMAL m_cellularJitter = FN_DECIMAL(0.45);
FN_DECIMAL m_gradientPerturbAmp = FN_DECIMAL(1);
void CalculateFractalBounding();
//2D
FN_DECIMAL SingleValueFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleValueFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleValueFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleValue(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SinglePerlinFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SinglePerlinFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SinglePerlinFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SinglePerlin(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleSimplexFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleSimplexFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleSimplexFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleSimplexFractalBlend(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleSimplex(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleCubicFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleCubicFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleCubicFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleCubic(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleCellular(FN_DECIMAL x, FN_DECIMAL y) const;
FN_DECIMAL SingleCellular2Edge(FN_DECIMAL x, FN_DECIMAL y) const;
void SingleGradientPerturb(unsigned char offset, FN_DECIMAL warpAmp, FN_DECIMAL frequency, FN_DECIMAL& x, FN_DECIMAL& y) const;
//3D
FN_DECIMAL SingleValueFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleValueFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleValueFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleValue(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SinglePerlinFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SinglePerlinFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SinglePerlinFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SinglePerlin(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleSimplexFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleSimplexFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleSimplexFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleSimplex(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleCubicFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleCubicFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleCubicFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleCubic(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleCellular(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
FN_DECIMAL SingleCellular2Edge(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
void SingleGradientPerturb(unsigned char offset, FN_DECIMAL warpAmp, FN_DECIMAL frequency, FN_DECIMAL& x, FN_DECIMAL& y, FN_DECIMAL& z) const;
//4D
FN_DECIMAL SingleSimplex(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z, FN_DECIMAL w) const;
inline unsigned char Index2D_12(unsigned char offset, int x, int y) const;
inline unsigned char Index3D_12(unsigned char offset, int x, int y, int z) const;
inline unsigned char Index4D_32(unsigned char offset, int x, int y, int z, int w) const;
inline unsigned char Index2D_256(unsigned char offset, int x, int y) const;
inline unsigned char Index3D_256(unsigned char offset, int x, int y, int z) const;
inline unsigned char Index4D_256(unsigned char offset, int x, int y, int z, int w) const;
inline FN_DECIMAL ValCoord2DFast(unsigned char offset, int x, int y) const;
inline FN_DECIMAL ValCoord3DFast(unsigned char offset, int x, int y, int z) const;
inline FN_DECIMAL GradCoord2D(unsigned char offset, int x, int y, FN_DECIMAL xd, FN_DECIMAL yd) const;
inline FN_DECIMAL GradCoord3D(unsigned char offset, int x, int y, int z, FN_DECIMAL xd, FN_DECIMAL yd, FN_DECIMAL zd) const;
inline FN_DECIMAL GradCoord4D(unsigned char offset, int x, int y, int z, int w, FN_DECIMAL xd, FN_DECIMAL yd, FN_DECIMAL zd, FN_DECIMAL wd) const;
};
#endif

View File

@@ -1,15 +0,0 @@
#include "filereader.hpp"
#include <fstream>
FileReader::FileReader() {
}
std::string FileReader::LoadTextFromFile(std::string path) {
std::ifstream t(path);
std::string text((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
return text;
}

View File

@@ -1,14 +0,0 @@
#ifndef MINECRAFT_UTIL_FILEREADER_H_
#define MINECRAFT_UTIL_FILEREADER_H_
#include <string>
class FileReader {
public:
FileReader();
std::string LoadTextFromFile(std::string path);
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +0,0 @@
#include "block.hpp"
#include "../config.hpp"
#include <iostream>
std::shared_ptr<CBlockDictionary> CBlockDictionary::Instance;
std::shared_ptr<CBlockDictionary> CBlockDictionary::GetInstance() {
if (!CBlockDictionary::Instance) {
CBlockDictionary::Instance = std::make_shared<CBlockDictionary>();
}
return CBlockDictionary::Instance;
}
void CBlockDictionary::Build() {
RegisterTexture("stone.png");
RegisterTexture("dirt.png");
RegisterTexture("grass_side.png");
RegisterTexture("grass_top.png");
RegisterTexture("cobblestone.png");
RegisterTexture("bedrock.png");
// Texture winding order - top, bottom, left, right, front, back
RegisterBlock(EBlockType::Air, { });
RegisterBlock(EBlockType::Stone, { EFaceTexture::Stone, EFaceTexture::Stone, EFaceTexture::Stone, EFaceTexture::Stone, EFaceTexture::Stone, EFaceTexture::Stone });
RegisterBlock(EBlockType::Dirt, { EFaceTexture::Dirt, EFaceTexture::Dirt, EFaceTexture::Dirt, EFaceTexture::Dirt, EFaceTexture::Dirt, EFaceTexture::Dirt });
RegisterBlock(EBlockType::Grass, { EFaceTexture::Grass, EFaceTexture::Dirt, EFaceTexture::GrassSide, EFaceTexture::GrassSide, EFaceTexture::GrassSide, EFaceTexture::GrassSide });
RegisterBlock(EBlockType::Cobblestone, { EFaceTexture::Cobblestone, EFaceTexture::Cobblestone, EFaceTexture::Cobblestone, EFaceTexture::Cobblestone, EFaceTexture::Cobblestone, EFaceTexture::Cobblestone });
RegisterBlock(EBlockType::Bedrock, { EFaceTexture::Bedrock, EFaceTexture::Bedrock, EFaceTexture::Bedrock, EFaceTexture::Bedrock, EFaceTexture::Bedrock, EFaceTexture::Bedrock });
}
void CBlockDictionary::RegisterTexture(std::string texture) {
Textures.push_back(texture);
}
void CBlockDictionary::RegisterBlock(EBlockType::Block block, std::vector<uint16_t> faceTextures) {
BlockEntries[block] = std::make_shared<CBlockEntry>((uint8_t)block, faceTextures);
}

View File

@@ -1,86 +0,0 @@
#ifndef MINECRAFT_WORLD_BLOCK_H_
#define MINECRAFT_WORLD_BLOCK_H_
#include "../common.hpp"
namespace EBlockType {
enum Block : uint8_t {
Air = 0,
Stone,
Grass,
Dirt,
Cobblestone,
Bedrock
};
}
namespace EFaceTexture {
enum Texture : uint16_t {
Stone,
Dirt,
GrassSide,
Grass,
Cobblestone,
Bedrock
};
}
// Texture winding order - top, bottom, left, right, front, back
class CBlockEntry {
public:
CBlockEntry(uint8_t id, std::vector<uint16_t> faceTextures)
: ID(id), FaceTextures(faceTextures) { }
uint8_t ID;
std::vector<uint16_t> FaceTextures;
};
// TODO: Make design of the class data oriented
// ie, import all the data used in the build from
// files and that
class CBlockDictionary {
public:
static std::shared_ptr<CBlockDictionary> GetInstance();
static std::shared_ptr<CBlockDictionary> Instance;
public:
void Build();
// The index of the texutres path in this array is equal to
// that textures ID, to be referenced in the block entry
std::vector<std::string> Textures;
// Only supports up to 255 blocs, 0 being air
// word stores vectors of chunks which are 16x16x256
// vectors of uint8_t which reference the block dictionary
std::map<uint8_t, std::shared_ptr<CBlockEntry>> BlockEntries;
// Expects textures to be inserted in order, 0-...
void RegisterTexture(std::string texture);
void RegisterBlock(EBlockType::Block block, std::vector<uint16_t> faceTextures);
};
// static std::vector<std::pair<int, std::string>> TextureIdsAndPaths {
// {0, "dirt.png"},
// {1, "grass_side.png"},
// {2, "grass_top.png"}
// };
#endif

View File

@@ -1,279 +0,0 @@
#include "chunk.hpp"
#include "voxel.hpp"
#include "../../renderer/shader.hpp"
#include "../../renderer/camera.hpp"
#include "../block.hpp"
#include "../../util/fastnoise.hpp"
#include <random>
static std::default_random_engine generator;
Chunk::Chunk() {
}
Chunk::Chunk(int x, int z) {
X = x, Z = z;
Load();
}
Chunk::Chunk(int x, int z, std::vector<uint8_t> voxels) {
X = x, Z = z;
Voxels = voxels;
Load();
}
Chunk::Chunk(int x, int z, std::shared_ptr<FastNoise> terrainGenerator) {
X = x, Z = z;
int y;
for (x = 0; x < CHUNK_WIDTH; x++)
for (y = 0; y < CHUNK_HEIGHT; y++)
for (z = 0; z < CHUNK_DEPTH; z++) {
if (y == 0) {
Voxels.push_back((uint8_t)EBlockType::Bedrock);
continue;
}
if (y == 1 && (float)rand() / (float)RAND_MAX > 0.5f) {
Voxels.push_back((uint8_t)EBlockType::Bedrock);
continue;
}
if (pow(y / (float)CHUNK_HEIGHT, 1.1024f) + terrainGenerator->GetNoise(x + (Z * CHUNK_WIDTH), y, z + (X * CHUNK_DEPTH)) * 0.60f < 0.5f) {
Voxels.push_back((uint8_t)EBlockType::Grass);
continue;
}
Voxels.push_back((uint8_t)EBlockType::Air);
}
for (x = 0; x < CHUNK_WIDTH; x++)
for (y = 0; y < CHUNK_HEIGHT; y++)
for (z = 0; z < CHUNK_DEPTH; z++) {
if (BlockAt(x, y, z) == EBlockType::Bedrock)
continue;
// No need for bounds checking as a closed loop
if (BlockAt(x, y + 1, z) == EBlockType::Grass)
Voxels[x + CHUNK_WIDTH * (y + CHUNK_HEIGHT * z)] = EBlockType::Dirt;
}
// Add stone 3 layers below dirt
for (x = 0; x < CHUNK_WIDTH; x++)
for (y = 0; y < CHUNK_HEIGHT; y++)
for (z = 0; z < CHUNK_DEPTH; z++) {
if (BlockAt(x, y, z) == EBlockType::Bedrock)
continue;
if (BlockAt(x, y + 1, z) == EBlockType::Dirt)
if (BlockAt(x, y + 2, z) == EBlockType::Dirt)
// if (BlockAt(x, y + 3, z) == EBlockType::Dirt)
Voxels[x + CHUNK_WIDTH * (y + CHUNK_HEIGHT * z)] = EBlockType::Stone;
}
// Add the rest of the stone
for (x = 0; x < CHUNK_WIDTH; x++)
for (y = 0; y < CHUNK_HEIGHT; y++)
for (z = 0; z < CHUNK_DEPTH; z++) {
if (BlockAt(x, y, z) == EBlockType::Bedrock)
continue;
if (BlockAt(x, y + 1, z) == EBlockType::Stone)
Voxels[x + CHUNK_WIDTH * (y + CHUNK_HEIGHT * z)] = EBlockType::Stone;
}
Load();
}
void Chunk::Load() {
if (Loaded)
return;
m_model = glm::translate(glm::mat4(1.0f), { X * CHUNK_WIDTH, 0, Z * CHUNK_DEPTH });
if (!Voxels.empty()) {
m_mesh();
Loaded = true;
return;
}
// Generate a superflat chunk if nothing is there
// [x + WIDTH * (y + HEIGHT * z)]
for (int x = 0; x < CHUNK_WIDTH; x++)
for (int y = 0; y < CHUNK_HEIGHT; y++)
for (int z = 0; z < CHUNK_DEPTH; z++) {
if (y > 32) {
Voxels.push_back((uint8_t)EBlockType::Air);
continue;
}
if (y == 0)
Voxels.push_back((uint8_t)EBlockType::Bedrock);
else if (y < 28)
Voxels.push_back((uint8_t)EBlockType::Stone);
else if (y < 32)
Voxels.push_back((uint8_t)EBlockType::Dirt);
else
Voxels.push_back((uint8_t)EBlockType::Grass);
}
m_mesh();
Loaded = true;
}
void Chunk::UploadMesh() {
if (!MeshReady)
return;
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
std::vector<glm::vec3> data;
data.insert(data.end(), m_vertices.begin(), m_vertices.end());
data.insert(data.end(), m_uvs.begin(), m_uvs.end());
m_numVerts = m_vertices.size();
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(glm::vec3), &data[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (const void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (const void*)(m_vertices.size() * sizeof(glm::vec3)));
m_vertices.clear();
m_uvs.clear();
data.clear();
glBindVertexArray(0);
MeshReady = !MeshReady;
}
void Chunk::Render(std::shared_ptr<Camera> camera, std::shared_ptr<Shader> shader) {
if (!Loaded)
return;
shader->Use();
glBindVertexArray(m_vao);
GLint uniTrans = glGetUniformLocation(shader->Program, "model");
glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(m_model));
GLint uniView = glGetUniformLocation(shader->Program, "view");
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(camera->GetViewMatrix()));
GLint uniProj = glGetUniformLocation(shader->Program, "proj");
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(camera->GetProjectionMatrix()));
glDrawArrays(GL_TRIANGLES, 0, m_numVerts);
}
void Chunk::Update(std::vector<uint8_t> voxels) {
Voxels = voxels;
m_mesh();
}
uint8_t Chunk::BlockAt(int x, int y, int z) {
if (x > CHUNK_WIDTH - 1) return 0;
if (y > CHUNK_HEIGHT - 1) return 0;
if (z > CHUNK_DEPTH - 1) return 0;
if (x < 0) return 0;
if (y < 0) return 0;
if (z < 0) return 0;
return Voxels[x + CHUNK_WIDTH * (y + CHUNK_HEIGHT * z)];
}
void Chunk::m_mesh() {
// TODO: Use greedy meshing for MAXIMUM performance
for (int x = 0; x < CHUNK_WIDTH; x++)
for (int y = 0; y < CHUNK_HEIGHT; y++)
for (int z = 0; z < CHUNK_DEPTH; z++) {
std::vector<glm::vec3> tempVerts;
std::vector<glm::vec3> tempUVs;
uint8_t block = BlockAt(x, y, z);
if (block == EBlockType::Air) continue;
Voxel tmp({x, y, z}, block);
if (BlockAt(x + 1, y, z) == EBlockType::Air)
tmp.AddFace(EFaceType::Right);
if (BlockAt(x - 1, y, z) == EBlockType::Air)
tmp.AddFace(EFaceType::Left);
if (BlockAt(x, y + 1, z) == EBlockType::Air)
tmp.AddFace(EFaceType::Top);
if (BlockAt(x, y - 1, z) == EBlockType::Air)
tmp.AddFace(EFaceType::Bottom);
if (BlockAt(x, y, z + 1) == EBlockType::Air)
tmp.AddFace(EFaceType::Front);
if (BlockAt(x, y, z - 1) == EBlockType::Air)
tmp.AddFace(EFaceType::Back);
tmp.GetMesh(tempVerts, tempUVs);
m_vertices.insert(m_vertices.end(), tempVerts.begin(), tempVerts.end());
m_uvs.insert(m_uvs.end(), tempUVs.begin(), tempUVs.end());
tmp.Clear();
}
MeshReady = true;
}
Chunk::~Chunk() {
}

View File

@@ -1,69 +0,0 @@
#ifndef MINECRAFT_RENDERER_CHUNK_H_
#define MINECRAFT_RENDERER_CHUNK_H_
#include "../../common.hpp"
#define CHUNK_HEIGHT 128
#define CHUNK_WIDTH 16
#define CHUNK_DEPTH 16
class FastNoise;
class Camera;
class Shader;
class Voxel;
class Chunk {
public:
Chunk();
Chunk(int x, int z);
Chunk(int x, int z, std::vector<uint8_t> voxels);
Chunk(int x, int z, std::shared_ptr<FastNoise> terrainGenerator);
void Load();
void UploadMesh();
bool MeshReady = false;
void Render(std::shared_ptr<Camera> camera, std::shared_ptr<Shader> shader);
void Update(std::vector<uint8_t> voxels);
uint8_t BlockAt(int x, int y, int z);
// Indexed sequentially [x + WIDTH * (y + HEIGHT * z)] = voxelID
// the voxel id is used to index the block dictionary to get properties
// to generate a mesh and send it to the GPU
std::vector<uint8_t> Voxels;
// To only be changed by the class its self
bool Loaded = false;
// To only be changed by render components
bool ShouldRender = false;
// Chunk World pos
int X,Z;
~Chunk();
private:
void m_mesh();
GLuint m_vao = 0;
GLuint m_vbo = 0;
// Must be translated by a multiple of 16 in the x or z, nothing in y
glm::mat4 m_model;
std::vector<glm::vec3> m_vertices;
int m_numVerts = 0;
std::vector<glm::vec3> m_uvs;
};
#endif

View File

@@ -1,127 +0,0 @@
#ifndef MINECRAFT_RENDERER_FACE_H_
#define MINECRAFT_RENDERER_FACE_H_
#include "../../common.hpp"
namespace EFaceType {
enum Face : uint8_t {
Top,
Bottom,
Left,
Right,
Front,
Back,
};
}
static std::vector<glm::vec3> CubeTopFace = {
{ -0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f },
{ -0.5f, 0.5f, -0.5f }
};
static std::vector<glm::vec2> CubeTopFaceUVs = {
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f },
{ 1.0f, 1.0f },
{ 0.0f, 1.0f },
{ 0.0f, 0.0f }
};
static std::vector<glm::vec3> CubeBottomFace = {
{ -0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, -0.5f, 0.5f },
{ -0.5f, -0.5f, 0.5f },
{ -0.5f, -0.5f, -0.5f }
};
static std::vector<glm::vec2> CubeBottomFaceUVs = {
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f },
{ 1.0f, 1.0f },
{ 0.0f, 1.0f },
{ 0.0f, 0.0f }
};
static std::vector<glm::vec3> CubeLeftFace = {
{ -0.5f, 0.5f, 0.5f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, -0.5f, -0.5f },
{ -0.5f, -0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f }
};
static std::vector<glm::vec2> CubeLeftFaceUVs = {
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f },
{ 1.0f, 1.0f },
{ 0.0f, 1.0f },
{ 0.0f, 0.0f }
};
static std::vector<glm::vec3> CubeRightFace = {
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f },
};
static std::vector<glm::vec2> CubeRightFaceUVs = {
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f },
{ 1.0f, 1.0f },
{ 0.0f, 1.0f },
{ 0.0f, 0.0f }
};
static std::vector<glm::vec3> CubeFrontFace = {
{ -0.5f, -0.5f, 0.5f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f },
{ -0.5f, -0.5f, 0.5f }
};
static std::vector<glm::vec2> CubeFrontFaceUVs = {
{ 1.0f, 1.0f },
{ 0.0f, 1.0f },
{ 0.0f, 0.0f },
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f }
};
static std::vector<glm::vec3> CubeBackFace = {
{ -0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, -0.5f, -0.5f }
};
static std::vector<glm::vec2> CubeBackFaceUVs = {
{ 1.0f, 1.0f },
{ 0.0f, 1.0f },
{ 0.0f, 0.0f },
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f }
};
#endif

View File

@@ -1,132 +0,0 @@
#include "voxel.hpp"
#include <iostream>
#include <memory>
#include "../../renderer/shader.hpp"
#include "../../renderer/camera.hpp"
#include "face.hpp"
#include "../block.hpp"
Voxel::Voxel(glm::vec3 coordsInChunk, uint8_t block) {
// Texture winding order - top, bottom, left, right, front, back
Block = block;
m_coordsInChunk = coordsInChunk;
}
void Voxel::AddFace(EFaceType::Face face) {
std::vector<glm::vec3> verts;
std::vector<glm::vec2> uvs;
switch (face) {
case EFaceType::Top:
{
verts = CubeTopFace;
uvs = CubeTopFaceUVs;
break;
}
case EFaceType::Bottom:
{
verts = CubeBottomFace;
uvs = CubeBottomFaceUVs;
break;
}
case EFaceType::Left:
{
verts = CubeLeftFace;
uvs = CubeLeftFaceUVs;
break;
}
case EFaceType::Right:
{
verts = CubeRightFace;
uvs = CubeRightFaceUVs;
break;
}
case EFaceType::Front:
{
verts = CubeFrontFace;
uvs = CubeFrontFaceUVs;
break;
}
case EFaceType::Back:
{
verts = CubeBackFace;
uvs = CubeBackFaceUVs;
break;
}
}
verts = m_translateIntoChunk(verts, m_coordsInChunk);
m_vertices.insert(m_vertices.end(), verts.begin(), verts.end());
std::shared_ptr<CBlockEntry> block = CBlockDictionary::GetInstance()->BlockEntries[Block];
uint16_t tex = block->FaceTextures[(uint16_t)face];
std::vector<glm::vec3> uvws = {
{ uvs[0].x, uvs[0].y, (float)tex },
{ uvs[1].x, uvs[1].y, (float)tex },
{ uvs[2].x, uvs[2].y, (float)tex },
{ uvs[3].x, uvs[3].y, (float)tex },
{ uvs[4].x, uvs[4].y, (float)tex },
{ uvs[5].x, uvs[5].y, (float)tex },
};
m_uvs.insert(m_uvs.end(), uvws.begin(), uvws.end());
}
void Voxel::GetMesh(std::vector<glm::vec3>& verts, std::vector<glm::vec3>& uvs) {
verts = m_vertices;
uvs = m_uvs;
}
void Voxel::Clear() {
m_vertices.clear();
m_uvs.clear();
}
std::vector<glm::vec3> Voxel::m_translateIntoChunk(std::vector<glm::vec3> verts, glm::vec3 trans) {
for (int i = 0; i < verts.size(); i++) {
verts[i].x += trans.x;
verts[i].y += trans.y;
verts[i].z += trans.z;
}
return verts;
}

View File

@@ -1,33 +0,0 @@
#ifndef MINECRAFT_RENDERER_VOXEL_H_
#define MINECRAFT_RENDERER_VOXEL_H_
#include "../../common.hpp"
#include "face.hpp"
class Camera;
class Shader;
class Voxel {
public:
Voxel(glm::vec3 coordsInChunk, uint8_t block);
void AddFace(EFaceType::Face face);
void GetMesh(std::vector<glm::vec3>& verts, std::vector<glm::vec3>& uvs);
void Clear();
uint8_t Block;
private:
glm::vec3 m_coordsInChunk;
std::vector<glm::vec3> m_translateIntoChunk(std::vector<glm::vec3> verts, glm::vec3 trans);
std::vector<glm::vec3> m_vertices;
std::vector<glm::vec3> m_uvs;
};
#endif

View File

@@ -1,59 +0,0 @@
#include "entity.hpp"
#include "../renderer/camera.hpp"
Entity::Entity(glm::vec3 postion, glm::vec3 direction, std::shared_ptr<Camera> camera)
: Position(Position)
, Direction(direction)
, EntityCamera(camera)
{
if (EntityCamera) {
EntityCamera->UpdateView();
}
}
Player::Player(glm::vec3 position, glm::vec3 direction, std::shared_ptr<Camera> 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);
}

View File

@@ -1,51 +0,0 @@
#ifndef MINECRAFT_WORLD_ENTITY_H_
#define MINECRAFT_WORLD_ENTITY_H_
#include "../common.hpp"
class Camera;
class Collider;
class Entity {
public:
Entity(glm::vec3 position, glm::vec3 direction = { 0.0f, 0.0f, 0.0f }, std::shared_ptr<Camera> camera = std::make_shared<Camera>());
// World position, 1.7 units below the
// camera position.
glm::vec3 Position;
// Look direction of the camera
glm::vec3 Direction;
// Velocity in direction
// of movement
glm::vec3 Velocity;
// Can be null
std::shared_ptr<Camera> EntityCamera;
// Collider
// std::unique_ptr<Collider> EntityCollider;
// Mesh (or reference to)
};
class Player : public Entity {
public:
Player(glm::vec3 position, glm::vec3 direction, std::shared_ptr<Camera> 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);
};
#endif

View File

@@ -1,14 +0,0 @@
#include "../../util/fastnoise.hpp"
void dp() {
FastNoise noise;
noise.SetSeed(121212);
noise.SetNoiseType(FastNoise::SimplexFractal);
noise.SetFractalOctaves(3);
}

View File

@@ -1,2 +0,0 @@

View File

@@ -1,158 +0,0 @@
#include "world.hpp"
#include "chunk/chunk.hpp"
#include "../renderer/shader.hpp"
#include "../util/fastnoise.hpp"
#include "../config.hpp"
#include "entity.hpp"
World::World() {
}
void World::LoadWorld() {
m_shaders["Basic"] = std::make_shared<Shader>();
m_shaders["Basic"]->Load(GameConfig.ResourceBase + "shaders/simple");
m_shaders["Basic"]->Link();
srand(time(NULL));
m_noiseGenerator = std::make_shared<FastNoise>();
m_noiseGenerator->SetSeed(rand());
m_noiseGenerator->SetNoiseType(FastNoise::Perlin);
m_noiseGenerator->SetFractalOctaves(8);
for (int x = -4; x < 5; x++)
for (int y = -5; y < 4; y++) {
m_chunkLoaderQueue.push({ x, y });
}
// Spawn generator threads
for (int i = 0; i < 6; i++) {
m_generatorThreads.push_back(std::thread([&]() {
m_loadChunks();
}));
}
m_generatorRunning = true;
}
void World::SetTextureMap(GLuint map) {
m_textureMapID = map;
}
glm::vec2 World::GetChunkCoords(glm::vec3 wordCoords) {
return { wordCoords.x / CHUNK_WIDTH, wordCoords.z / CHUNK_DEPTH };
}
std::vector<std::shared_ptr<Chunk>> World::GetRenderableChunks() {
std::vector<std::shared_ptr<Chunk>> chunks;
for (auto& chunk : m_chunks) {
// Should the chunk be rendererd ?
if (chunk.second->ShouldRender) {
m_chunkMutex.lock();
if (chunk.second->MeshReady)
chunk.second->UploadMesh();
m_chunkMutex.unlock();
// If not, add it
chunks.push_back(chunk.second);
}
}
return chunks;
}
void World::Update(std::shared_ptr<Entity> player) {
}
void World::Render(std::shared_ptr<Entity> player) {
glBindTexture(GL_TEXTURE_2D_ARRAY, m_textureMapID);
std::vector<std::shared_ptr<Chunk>> chunks = GetRenderableChunks();
for (int i = 0; i < chunks.size(); i++) {
chunks[i]->Render(player->EntityCamera, m_shaders["Basic"]);
}
}
World::~World() {
m_generatorRunning = false;
for (int i = 0; i < m_generatorThreads.size(); i++) {
m_generatorThreads[i].join();
}
}
void World::m_loadChunks() {
while (m_generatorRunning) {
m_chunkMutex.lock();
glm::vec2 coords = m_chunkLoaderQueue.front();
m_chunkLoaderQueue.pop();
m_chunkMutex.unlock();
std::shared_ptr<Chunk> loadingChunk = std::make_shared<Chunk>(coords.x, coords.y, m_noiseGenerator);
std::cout << "Loaded chunk " << coords.x << ":" << coords.y << std::endl;
m_chunkMutex.lock();
m_chunks[coords] = loadingChunk;
m_chunks[coords]->ShouldRender = true;
m_chunkMutex.unlock();
while (m_chunkLoaderQueue.empty()) {
if (!m_generatorRunning) break;
static std::chrono::milliseconds dura(1);
std::this_thread::sleep_for(dura);
}
}
}

View File

@@ -1,75 +0,0 @@
#ifndef MINECRAFT_WORLD_WORLD_H_
#define MINECRAFT_WORLD_WORLD_H_
#include "../common.hpp"
#include "../renderer/camera.hpp"
#include "chunk/chunk.hpp"
#include <unordered_map>
#include <thread>
#include <mutex>
#include <queue>
class FastNoise;
class Shader;
class Entity;
class World {
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);
std::vector<std::shared_ptr<Chunk>> GetRenderableChunks();
void Update(std::shared_ptr<Entity> player);
void Render(std::shared_ptr<Entity> player);
~World();
private:
// GL stuff
// Main texture map id
GLuint m_textureMapID;
// Shaders indexed by name
std::map<std::string, std::shared_ptr<Shader>> m_shaders;
// Threads used for chunk generation
std::vector<std::thread> m_generatorThreads;
bool m_generatorRunning = false;
// Chuks
// Indexed by chunk coorinates
std::unordered_map<glm::vec2, std::shared_ptr<Chunk>> m_chunks;
std::queue<glm::vec2> m_chunkUpdatesQueue;
std::queue<glm::vec2> m_chunkLoaderQueue;
std::mutex m_chunkMutex;
// Generator
std::shared_ptr<FastNoise> m_noiseGenerator;
void m_loadChunks();
};
#endif