Compare commits
2 Commits
e690652b03
...
d6f12162a9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6f12162a9 | ||
|
|
4740c9a85c |
@@ -28,6 +28,9 @@ if (WIN32)
|
||||
endif (WIN32)
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAD ON)
|
||||
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal 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.
|
||||
27
legacy/resources/shaders/simple.frag
Normal file
27
legacy/resources/shaders/simple.frag
Normal 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);
|
||||
|
||||
}
|
||||
26
legacy/resources/shaders/simple.vert
Normal file
26
legacy/resources/shaders/simple.vert
Normal 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
|
||||
);
|
||||
|
||||
}
|
||||
BIN
legacy/resources/textures/bedrock.png
Normal file
BIN
legacy/resources/textures/bedrock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 225 B |
BIN
legacy/resources/textures/cobblestone.png
Normal file
BIN
legacy/resources/textures/cobblestone.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 568 B |
BIN
legacy/resources/textures/dirt.png
Normal file
BIN
legacy/resources/textures/dirt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 266 B |
BIN
legacy/resources/textures/grass_side.png
Normal file
BIN
legacy/resources/textures/grass_side.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 660 B |
BIN
legacy/resources/textures/grass_top.png
Normal file
BIN
legacy/resources/textures/grass_top.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 766 B |
BIN
legacy/resources/textures/stone.png
Normal file
BIN
legacy/resources/textures/stone.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 223 B |
16
legacy/src/config.hpp
Normal file
16
legacy/src/config.hpp
Normal 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
184
legacy/src/game.cpp
Normal 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
55
legacy/src/game.hpp
Normal 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
13
legacy/src/main.cpp
Normal 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;
|
||||
|
||||
}
|
||||
35
legacy/src/physics/collider.cpp
Normal file
35
legacy/src/physics/collider.cpp
Normal 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) {
|
||||
|
||||
}
|
||||
39
legacy/src/physics/collider.hpp
Normal file
39
legacy/src/physics/collider.hpp
Normal 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
|
||||
16
legacy/src/renderer/renderer.cpp
Normal file
16
legacy/src/renderer/renderer.cpp
Normal 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);
|
||||
|
||||
}
|
||||
18
legacy/src/renderer/renderer.hpp
Normal file
18
legacy/src/renderer/renderer.hpp
Normal 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
|
||||
15
legacy/src/util/filereader.cpp
Normal file
15
legacy/src/util/filereader.cpp
Normal 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;
|
||||
}
|
||||
|
||||
14
legacy/src/util/filereader.hpp
Normal file
14
legacy/src/util/filereader.hpp
Normal 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
|
||||
52
legacy/src/world/block.cpp
Normal file
52
legacy/src/world/block.cpp
Normal 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);
|
||||
|
||||
}
|
||||
86
legacy/src/world/block.hpp
Normal file
86
legacy/src/world/block.hpp
Normal 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
|
||||
295
legacy/src/world/chunk/chunk.cpp
Normal file
295
legacy/src/world/chunk/chunk.cpp
Normal 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();
|
||||
|
||||
}
|
||||
70
legacy/src/world/chunk/chunk.hpp
Normal file
70
legacy/src/world/chunk/chunk.hpp
Normal 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
|
||||
127
legacy/src/world/chunk/face.hpp
Normal file
127
legacy/src/world/chunk/face.hpp
Normal 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
|
||||
132
legacy/src/world/chunk/voxel.cpp
Normal file
132
legacy/src/world/chunk/voxel.cpp
Normal 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;
|
||||
|
||||
}
|
||||
33
legacy/src/world/chunk/voxel.hpp
Normal file
33
legacy/src/world/chunk/voxel.hpp
Normal 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
|
||||
59
legacy/src/world/entity.cpp
Normal file
59
legacy/src/world/entity.cpp
Normal 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);
|
||||
|
||||
}
|
||||
51
legacy/src/world/entity.hpp
Normal file
51
legacy/src/world/entity.hpp
Normal 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
|
||||
14
legacy/src/world/generator/chunkgenerator.cpp
Normal file
14
legacy/src/world/generator/chunkgenerator.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "../../util/fastnoise.hpp"
|
||||
|
||||
|
||||
void dp() {
|
||||
|
||||
FastNoise noise;
|
||||
noise.SetSeed(121212);
|
||||
|
||||
noise.SetNoiseType(FastNoise::SimplexFractal);
|
||||
|
||||
noise.SetFractalOctaves(3);
|
||||
|
||||
}
|
||||
|
||||
6
legacy/src/world/generator/chunkgenerator.hpp
Normal file
6
legacy/src/world/generator/chunkgenerator.hpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef MINECRAFT_WORLD_GENERATOR_CHUNKGENERATOR_H_
|
||||
#define MINECRAFT_WORLD_GENERATOR_CHUNKGENERATOR_H_
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
28
legacy/src/world/generator/chunkmanager.hpp
Normal file
28
legacy/src/world/generator/chunkmanager.hpp
Normal 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
191
legacy/src/world/world.cpp
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
80
legacy/src/world/world.hpp
Normal file
80
legacy/src/world/world.hpp
Normal 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
209
src/Rendering/camera.cpp
Normal 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
55
src/Rendering/camera.hpp
Normal 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
128
src/Rendering/face.hpp
Normal 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
|
||||
3
src/Rendering/frustrum.cpp
Normal file
3
src/Rendering/frustrum.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "frustrum.hpp"
|
||||
|
||||
|
||||
29
src/Rendering/frustrum.hpp
Normal file
29
src/Rendering/frustrum.hpp
Normal 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
6
src/Rendering/mesh.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "mesh.hpp"
|
||||
|
||||
Mesh::Mesh()
|
||||
{
|
||||
|
||||
}
|
||||
27
src/Rendering/mesh.hpp
Normal file
27
src/Rendering/mesh.hpp
Normal 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
|
||||
66
src/Rendering/renderable.cpp
Normal file
66
src/Rendering/renderable.cpp
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
45
src/Rendering/renderable.hpp
Normal file
45
src/Rendering/renderable.hpp
Normal 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
|
||||
11
src/Rendering/rendermaster.cpp
Normal file
11
src/Rendering/rendermaster.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "rendermaster.hpp"
|
||||
|
||||
RenderMaster::RenderMaster()
|
||||
: mWorldRenderer(),
|
||||
mMeshRenderer()
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
41
src/Rendering/rendermaster.hpp
Normal file
41
src/Rendering/rendermaster.hpp
Normal 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
121
src/Rendering/shader.cpp
Normal 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
30
src/Rendering/shader.hpp
Normal 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
60
src/Rendering/texture.cpp
Normal 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
14
src/Rendering/texture.hpp
Normal 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
|
||||
23
src/Rendering/voxelmesh.hpp
Normal file
23
src/Rendering/voxelmesh.hpp
Normal 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
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
311
src/ThirdParty/fastnoise.hpp
vendored
Normal 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
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
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
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
120
src/display.cpp
Normal 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
42
src/display.hpp
Normal 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
14
src/settings.hpp
Normal 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 = 1920;
|
||||
static const int WindowHeight = 1080;
|
||||
|
||||
static const std::string ResourceBase = MC_RESOURCES;
|
||||
|
||||
#endif
|
||||
3
src/threadpool.hpp
Normal file
3
src/threadpool.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
// Threadpool for asset management and other such tasks
|
||||
|
||||
|
||||
10
src/utilities.hpp
Normal file
10
src/utilities.hpp
Normal 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;
|
||||
}
|
||||
@@ -28,8 +28,8 @@ void World::LoadWorld() {
|
||||
|
||||
m_noiseGenerator->SetFractalOctaves(8);
|
||||
|
||||
for (int x = -4; x < 50; x++)
|
||||
for (int y = -50; y < 4; y++) {
|
||||
for (int x = -4; x < 5; x++)
|
||||
for (int y = -5; y < 4; y++) {
|
||||
|
||||
m_chunkLoaderQueue.push({ x, y });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user