WOrking version

This commit is contained in:
benkyd
2022-05-11 13:44:34 +00:00
parent e690652b03
commit 4740c9a85c
59 changed files with 22300 additions and 0 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Benjamin Kyd
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.

View File

@@ -0,0 +1,27 @@
#version 450
vec3 SkyColour = vec3(186.0f / 255.0f, 214.0f / 255.0f, 254.0f / 255.0f);
in vec3 TexCoord;
in float Distance;
out vec4 outColour;
uniform sampler2DArray tex;
void main() {
outColour = texture(tex, TexCoord);
//outColour = vec4(.9, .9, .9, 1);
if (outColour.w == .0)
discard;
float fogMax = 60000;
vec3 colour = mix(outColour.xyz, SkyColour, min(1.0f, Distance / fogMax));
// Retain fragment transparency
outColour = vec4(colour, outColour.w);
}

View File

@@ -0,0 +1,26 @@
#version 450
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 texcoord;
out vec3 TexCoord;
out float Distance;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
void main() {
TexCoord = texcoord;
gl_Position = proj * view * model * vec4(position, 1.0);
// Makes no sense but it works
Distance = (
gl_Position.x * gl_Position.x +
gl_Position.y * gl_Position.y +
gl_Position.z * gl_Position.z
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

16
legacy/src/config.hpp Normal file
View File

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

184
legacy/src/game.cpp Normal file
View File

@@ -0,0 +1,184 @@
#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);
}
}

55
legacy/src/game.hpp Normal file
View File

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

13
legacy/src/main.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include <iostream>
#include "game.hpp"
int main(int argc, char** argv) {
Game game;
game.Setup(1080, 720);
game.Run();
return 0;
}

View File

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

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

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

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

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

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

View File

@@ -0,0 +1,52 @@
#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() {
// Order matters !
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

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

@@ -0,0 +1,295 @@
#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.40f < 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::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 || !Loaded)
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 (!MeshReady || !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() {
Unload();
}

View File

@@ -0,0 +1,70 @@
#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 Unload();
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

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

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

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

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

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

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

View File

@@ -0,0 +1,6 @@
#ifndef MINECRAFT_WORLD_GENERATOR_CHUNKGENERATOR_H_
#define MINECRAFT_WORLD_GENERATOR_CHUNKGENERATOR_H_
#endif

View File

@@ -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

191
legacy/src/world/world.cpp Normal file
View File

@@ -0,0 +1,191 @@
#include "world.hpp"
#include <algorithm>
#include <iterator>
#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::ValueFractal);
m_noiseGenerator->SetFractalOctaves(5);
// Generate a 54x54 chunk world
for (int x = -4; x < 50; x++)
for (int y = -50; 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::vec3 World::GetChunkCoords(glm::vec3 worldCoords) {
return { worldCoords.x / static_cast<float>(CHUNK_WIDTH),
worldCoords.y / static_cast<float>(CHUNK_HEIGHT),
worldCoords.z / static_cast<float>(CHUNK_DEPTH) };
}
glm::vec2 World::GetChunk(glm::vec3 worldCoords) {
return { static_cast<int>(worldCoords.x / CHUNK_WIDTH), static_cast<int>(worldCoords.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_chunkLoderMutex.lock();
if (chunk.second->MeshReady)
chunk.second->UploadMesh();
m_chunkLoderMutex.unlock();
// If not, add it
chunks.push_back(chunk.second);
}
}
return chunks;
}
void World::Update(std::shared_ptr<Entity> 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<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();
}
for (auto& chunk : m_chunks) {
chunk.second->Unload();
}
}
void World::m_loadChunks() {
while (m_generatorRunning) {
m_chunkLoderMutex.lock();
glm::vec2 coords = m_chunkLoaderQueue.front();
m_chunkLoaderQueue.pop();
m_chunkLoderMutex.unlock();
std::shared_ptr<Chunk> loadingChunk = std::make_shared<Chunk>(coords.x, coords.y, m_noiseGenerator);
loadingChunk->ShouldRender = true;
std::cout << "Loaded chunk " << coords.x << ":" << coords.y << std::endl;
m_chunkLoderMutex.lock();
m_chunks[coords] = loadingChunk;
m_chunkLoderMutex.unlock();
while (m_chunkLoaderQueue.empty()) {
if (!m_generatorRunning) break;
static std::chrono::milliseconds dura(1);
std::this_thread::sleep_for(dura);
}
}
}

View File

@@ -0,0 +1,80 @@
#ifndef MINECRAFT_WORLD_WORLD_H_
#define MINECRAFT_WORLD_WORLD_H_
#include "../common.hpp"
#include "../renderer/camera.hpp"
#include "generator/chunkmanager.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::vec3 GetChunkCoords(glm::vec3 wordCoords);
// Takes world coordinates and gets the chunk those coorinates
// fall in
glm::vec2 GetChunk(glm::vec3 worldCoords);
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::mutex m_chunkUpdaterMutex;
std::queue<glm::vec2> m_chunkUpdatesQueue;
std::mutex m_chunkLoderMutex;
std::queue<glm::vec2> m_chunkLoaderQueue;
// Generator
std::shared_ptr<FastNoise> m_noiseGenerator;
void m_loadChunks();
};
#endif

209
src/Rendering/camera.cpp Normal file
View File

@@ -0,0 +1,209 @@
#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();
}

55
src/Rendering/camera.hpp Normal file
View File

@@ -0,0 +1,55 @@
#ifndef MINECRAFT_RENDERING_CAMERA_H_
#define MINECRAFT_RENDERING_CAMERA_H_
#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>
#if _WIN32
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
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);
// 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:
glm::mat4 viewMatrix = {};
glm::mat4 projMatrix = {};
};
#endif

128
src/Rendering/face.hpp Normal file
View File

@@ -0,0 +1,128 @@
#ifndef MINECRAFT_RENDERING_FACE_H_
#define MINECRAFT_RENDERING_FACE_H_
#include <vector>
#include <glm/glm.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

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

View File

@@ -0,0 +1,29 @@
#ifndef MINECRAFT_RENDERING_FRUSTRUM_H_
#define MINECRAFT_RENDERING_FRUSTRUM_H_
namespace EFrustrumPlanes
{
enum Planes
{
Right,
Left,
Top,
Bottom,
Far,
Near
};
};
class FrustrumPlane
{
public:
};
class Frustrum
{
public:
};
#endif

6
src/Rendering/mesh.cpp Normal file
View File

@@ -0,0 +1,6 @@
#include "mesh.hpp"
Mesh::Mesh()
{
}

27
src/Rendering/mesh.hpp Normal file
View File

@@ -0,0 +1,27 @@
#ifndef MINECRAFT_RENDERING_MESH_H_
#define MINECRAFT_RENDERING_MESH_H_
#include "../common.hpp"
class Vertex
{
public:
glm::vec3 Position;
glm::vec3 SurfaceNormal;
};
class Mesh
{
public:
Mesh();
private:
GLuint mVAO;
GLuint mVBO;
};
#endif

View File

@@ -0,0 +1,66 @@
#include "renderable.hpp"
#include <algorithm>
Renderable::Renderable()
{
}
void Renderable::Init()
{
}
void Renderable::AddMesh( Mesh* mesh )
{
if (mesh == nullptr) return;
mMeshs.push_back( mesh );
}
void Renderable::RemoveMesh( Mesh* mesh )
{
// Renderable does not include mesh
if (std::find( mMeshs.begin(), mMeshs.end(), mesh ) == mMeshs.end())
return;
std::remove( mMeshs.begin(), mMeshs.end(), mesh );
}
void Renderable::SetActiveMesh( Mesh* mesh )
{
// Renderable does not include mesh
if (std::find( mMeshs.begin(), mMeshs.end(), mesh ) == mMeshs.end())
return;
mActiveMesh = mesh;
}
Mesh* Renderable::GetActiveMesh()
{
return mActiveMesh;
}
void Renderable::UpdateBuffer()
{
}
void Renderable::Load()
{
}
void Renderable::Unload()
{
}
Renderable::~Renderable()
{
Unload();
}

View File

@@ -0,0 +1,45 @@
#ifndef MINECRAFT_RENDERING_RENDERABLE_H_
#define MINECRAFT_RENDERING_RENDERABLE_H_
#include "../common.hpp"
class Mesh;
// Basically a model but thats effort
// perhaps sub-class?
class Renderable
{
public:
Renderable();
void Init();
// DOES NOT OWN MESH
void AddMesh( Mesh* );
void RemoveMesh( Mesh* );
void SetActiveMesh( Mesh* );
Mesh* GetActiveMesh();
void UpdateBuffer();
// GPU Load methods
void Load();
void Unload();
~Renderable();
private:
std::vector<glm::vec3> mBuff;
std::vector<Mesh*> mMeshs;
Mesh* mActiveMesh;
// Meshes have uniform uniforms
GLuint mUBO;
glm::mat4 mModelMatrix;
};
#endif

View File

@@ -0,0 +1,11 @@
#include "rendermaster.hpp"
RenderMaster::RenderMaster()
: mWorldRenderer(),
mMeshRenderer()
{
}

View File

@@ -0,0 +1,41 @@
#ifndef MINECRAFT_RENDERING_RENDERMASTER_H_
#define MINECRAFT_RENDERING_RENDERMASTER_H_
/**
* Renderer Structure
*
* Mesh -> Renderable
* Mesh -> VoxelMesh
* Renderable -> Model
* Renderable -> World (static(?))
* Renderable -> Entity (dynamic)
* Renderable -> Particle (dynamic)
*
* Kinda just winging it ngl
*/
class WorldRenderer
{
};
class MeshRenderer
{
};
class RenderMaster
{
public:
RenderMaster();
WorldRenderer mWorldRenderer;
MeshRenderer mMeshRenderer;
};
#endif

121
src/Rendering/shader.cpp Normal file
View File

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

30
src/Rendering/shader.hpp Normal file
View File

@@ -0,0 +1,30 @@
#ifndef MINECRAFT_RENDERING_SHADER_H_
#define MINECRAFT_RENDERING_SHADER_H_
#include <logger.h>
#include <glad/glad.h>
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> mLogger;
bool mCheckShader(GLuint uid);
GLuint mVert;
GLuint mFrag;
};
#endif

60
src/Rendering/texture.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "texture.hpp"
#include <logger.h>
#include "../settings.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "../ThirdParty/stb_image.hpp"
GLuint Texture::LoadTextures(std::vector<std::string> textures) {
Logger logger;
std::string basePath = 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;
}

14
src/Rendering/texture.hpp Normal file
View File

@@ -0,0 +1,14 @@
#ifndef MINECRAFT_RENDERING_TEXTURE_H_
#define MINECRAFT_RENDERING_TEXTURE_H_
#include <vector>
#include <string>
#include <glad/glad.h>
class Texture {
public:
GLuint LoadTextures(std::vector<std::string> textures);
};
#endif

View File

@@ -0,0 +1,23 @@
#ifndef MINECRAFT_RENDERER_VOXELMESH_H_
#define MINECRAFT_RENDERER_VOXELMESH_H_
#include "mesh.hpp"
class VoxelMesh : public Mesh
{
public:
VoxelMesh();
int Width;
int Height;
int Depth;
// Size is w*h*d
std::vector<uint8_t> Voxels;
};
#endif

2250
src/ThirdParty/fastnoise.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

311
src/ThirdParty/fastnoise.hpp vendored Normal file
View File

@@ -0,0 +1,311 @@
// 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

1843
src/ThirdParty/glad.c vendored Normal file

File diff suppressed because it is too large Load Diff

7568
src/ThirdParty/stb_image.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

7568
src/ThirdParty/stb_image_write.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

120
src/display.cpp Normal file
View File

@@ -0,0 +1,120 @@
#include "display.hpp"
Display::Display( int w, int h, std::string title )
: mLogger()
{
mLogger << 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
mLogger << LOGGER_INFO << "Creating window" << LOGGER_ENDL;
mWindow = SDL_CreateWindow( title.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, w, h,
SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE );
// Create GL context
mLogger << LOGGER_INFO << "Creating OpenGL context" << LOGGER_ENDL;
mGlContext = SDL_GL_CreateContext( mWindow );
SDL_SetRelativeMouseMode( SDL_TRUE );
// Set VSYNC swap interval
SDL_GL_SetSwapInterval( 1 );
mLogger << 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);
mLogger << LOGGER_INFO << "Loaded OpenGL" << LOGGER_ENDL;
mLogger << LOGGER_ENDL;
IsWindowOpen = true;
}
void Display::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 )
{
mW = e->window.data1; mH = e->window.data2;
// CameraUpdateProjection( mW, mH );
glViewport( 0, 0, mW, mH );
}
break;
}
case SDL_QUIT:
{
IsWindowOpen = false;
break;
}
}
// if ( IsMouseActive ) HandleMouseSDL( *e );
}
// m_player->MoveSDL( state );
}
void Display::PrepareFrame()
{
static const float clear[] = { 186.0f / 255.0f, 214.0f / 255.0f, 254.0f / 255.0f };
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearBufferfv( GL_COLOR, 0, clear );
}
void Display::NextFrame()
{
SDL_GL_SwapWindow( mWindow );
}

42
src/display.hpp Normal file
View File

@@ -0,0 +1,42 @@
#ifndef MINECRAFT_DISPLAY_H_
#define MINECRAFT_DISPLAY_H_
#include <string>
#include <logger.h>
#if _WIN32
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
#include <glad/glad.h>
#include <KHR/khrplatform.h>
class Display
{
public:
Display( int w, int h, std::string title );
void Input( SDL_Event* e );
void PrepareFrame();
void NextFrame();
bool IsWindowOpen = false;
bool IsMouseActive = true;
private:
Logger mLogger;
SDL_Window* mWindow = nullptr;
SDL_GLContext mGlContext = nullptr;
int mW, mH;
};
#endif

14
src/settings.hpp Normal file
View File

@@ -0,0 +1,14 @@
#ifndef MINECRAFT_SETTINGS_H_
#define MINECRAFT_SETTINGS_H_
#include <string>
// TODO: import settings and stuff
// for now this works
static const int WindowWidth = 1000;
static const int WindowHeight = 600;
static const std::string ResourceBase = MC_RESOURCES;
#endif

3
src/threadpool.hpp Normal file
View File

@@ -0,0 +1,3 @@
// Threadpool for asset management and other such tasks

10
src/utilities.hpp Normal file
View File

@@ -0,0 +1,10 @@
#include <fstream>
#include <string>
inline std::string LoadTextFromFile( std::string file )
{
std::ifstream t( file );
std::string text( (std::istreambuf_iterator<char>( t )),
std::istreambuf_iterator<char>() );
return text;
}