Compare commits
17 Commits
working_ve
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aefe55e314 | ||
|
|
ae8b69b96d | ||
|
|
9c40baacb6 | ||
|
|
6e42ac9e8b | ||
|
|
9f9daa3a6e | ||
|
|
fb75f6b8d6 | ||
|
|
2872ac6268 | ||
|
|
e4dbfa672c | ||
|
|
24d95d1ad4 | ||
|
|
05ff8543bb | ||
|
|
4e5a1bec24 | ||
|
|
72a359bce7 | ||
|
|
8f9318c83a | ||
|
|
1ce214bf7f | ||
|
|
a81d6bd00f | ||
|
|
7e859edd8e | ||
|
|
b2ac1f3757 |
@@ -1,10 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(OpenGLPlayground)
|
||||
project(MingeCraft)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CMakeModules/)
|
||||
cmake_policy(SET CMP0037 OLD)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
# set(CMAKE_BUILD_TYPE Debug)
|
||||
set(CMAKE_CXX_FLAGS "-Ofast")
|
||||
|
||||
set(executable output)
|
||||
@@ -16,6 +15,7 @@ add_definitions(-DMC_RESOURCES="${CMAKE_SOURCE_DIR}/resources/")
|
||||
message(${CMAKE_SOURCE_DIR}/resources)
|
||||
|
||||
if (UNIX)
|
||||
find_package(glm REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
endif(UNIX)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -43,23 +46,23 @@ include_directories(${executable}
|
||||
|
||||
file(GLOB SourceFiles
|
||||
${SrcDIR}/*
|
||||
${SrcDIR}/util/*
|
||||
${SrcDIR}/game/*
|
||||
${SrcDIR}/world/*
|
||||
${SrcDIR}/world/chunk/*
|
||||
${SrcDIR}/renderer/*
|
||||
${SrcDIR}/ThirdParty/*
|
||||
${SrcDIR}/Rendering/*
|
||||
${SrcDIR}/Rendering/Platform/*
|
||||
${SrcDIR}/World/*
|
||||
)
|
||||
|
||||
add_executable(${executable} ${SourceFiles})
|
||||
|
||||
set_target_properties(${executable} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_EXTENSIONS OFF
|
||||
CXX_STANDARD 20
|
||||
CXX_EXTENSIONS ON
|
||||
)
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(${executable}
|
||||
SDL2
|
||||
glm
|
||||
OpenGL::OpenGL
|
||||
OpenGL::GL
|
||||
Threads::Threads
|
||||
|
||||
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 |
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;
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ std::shared_ptr<CBlockDictionary> CBlockDictionary::GetInstance() {
|
||||
|
||||
void CBlockDictionary::Build() {
|
||||
|
||||
// Order matters !
|
||||
RegisterTexture("stone.png");
|
||||
RegisterTexture("dirt.png");
|
||||
RegisterTexture("grass_side.png");
|
||||
@@ -53,7 +53,7 @@ Chunk::Chunk(int x, int z, std::shared_ptr<FastNoise> terrainGenerator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pow(y / (float)CHUNK_HEIGHT, 1.1024f) + terrainGenerator->GetNoise(x + (Z * CHUNK_WIDTH), y, z + (X * CHUNK_DEPTH)) * 0.60f < 0.5f) {
|
||||
if (pow((y / (float)CHUNK_HEIGHT), 1.1024f) + terrainGenerator->GetNoise(x + (Z * CHUNK_WIDTH), y, z + (X * CHUNK_DEPTH)) * 0.40f < 0.5f) {
|
||||
|
||||
Voxels.push_back((uint8_t)EBlockType::Grass);
|
||||
continue;
|
||||
@@ -149,9 +149,23 @@ void Chunk::Load() {
|
||||
|
||||
}
|
||||
|
||||
void Chunk::Unload() {
|
||||
|
||||
m_vertices.clear();
|
||||
m_uvs.clear();
|
||||
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
glDeleteBuffers(1, &m_vbo);
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
|
||||
Loaded = false;
|
||||
|
||||
}
|
||||
|
||||
void Chunk::UploadMesh() {
|
||||
|
||||
if (!MeshReady)
|
||||
if (!MeshReady || !Loaded)
|
||||
return;
|
||||
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
@@ -187,7 +201,7 @@ void Chunk::UploadMesh() {
|
||||
|
||||
void Chunk::Render(std::shared_ptr<Camera> camera, std::shared_ptr<Shader> shader) {
|
||||
|
||||
if (!Loaded)
|
||||
if (!MeshReady || !Loaded)
|
||||
return;
|
||||
|
||||
shader->Use();
|
||||
@@ -276,4 +290,6 @@ void Chunk::m_mesh() {
|
||||
|
||||
Chunk::~Chunk() {
|
||||
|
||||
Unload();
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
Chunk(int x, int z, std::shared_ptr<FastNoise> terrainGenerator);
|
||||
|
||||
void Load();
|
||||
void Unload();
|
||||
|
||||
void UploadMesh();
|
||||
bool MeshReady = false;
|
||||
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
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "world.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "chunk/chunk.hpp"
|
||||
|
||||
#include "../renderer/shader.hpp"
|
||||
@@ -24,10 +27,11 @@ void World::LoadWorld() {
|
||||
m_noiseGenerator = std::make_shared<FastNoise>();
|
||||
m_noiseGenerator->SetSeed(rand());
|
||||
|
||||
m_noiseGenerator->SetNoiseType(FastNoise::Perlin);
|
||||
m_noiseGenerator->SetNoiseType(FastNoise::ValueFractal);
|
||||
|
||||
m_noiseGenerator->SetFractalOctaves(8);
|
||||
m_noiseGenerator->SetFractalOctaves(5);
|
||||
|
||||
// Generate a 54x54 chunk world
|
||||
for (int x = -4; x < 50; x++)
|
||||
for (int y = -50; y < 4; y++) {
|
||||
|
||||
@@ -56,9 +60,17 @@ void World::SetTextureMap(GLuint map) {
|
||||
|
||||
}
|
||||
|
||||
glm::vec2 World::GetChunkCoords(glm::vec3 wordCoords) {
|
||||
glm::vec3 World::GetChunkCoords(glm::vec3 worldCoords) {
|
||||
|
||||
return { wordCoords.x / CHUNK_WIDTH, wordCoords.z / CHUNK_DEPTH };
|
||||
return { worldCoords.x / static_cast<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) };
|
||||
|
||||
}
|
||||
|
||||
@@ -71,12 +83,12 @@ std::vector<std::shared_ptr<Chunk>> World::GetRenderableChunks() {
|
||||
// Should the chunk be rendererd ?
|
||||
if (chunk.second->ShouldRender) {
|
||||
|
||||
m_chunkMutex.lock();
|
||||
m_chunkLoderMutex.lock();
|
||||
|
||||
if (chunk.second->MeshReady)
|
||||
chunk.second->UploadMesh();
|
||||
|
||||
m_chunkMutex.unlock();
|
||||
m_chunkLoderMutex.unlock();
|
||||
|
||||
// If not, add it
|
||||
chunks.push_back(chunk.second);
|
||||
@@ -91,6 +103,21 @@ std::vector<std::shared_ptr<Chunk>> World::GetRenderableChunks() {
|
||||
|
||||
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) {
|
||||
@@ -118,30 +145,36 @@ World::~World() {
|
||||
|
||||
}
|
||||
|
||||
for (auto& chunk : m_chunks) {
|
||||
|
||||
chunk.second->Unload();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void World::m_loadChunks() {
|
||||
|
||||
while (m_generatorRunning) {
|
||||
|
||||
m_chunkMutex.lock();
|
||||
m_chunkLoderMutex.lock();
|
||||
|
||||
glm::vec2 coords = m_chunkLoaderQueue.front();
|
||||
m_chunkLoaderQueue.pop();
|
||||
|
||||
m_chunkMutex.unlock();
|
||||
m_chunkLoderMutex.unlock();
|
||||
|
||||
|
||||
std::shared_ptr<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_chunkMutex.lock();
|
||||
m_chunkLoderMutex.lock();
|
||||
|
||||
m_chunks[coords] = loadingChunk;
|
||||
m_chunks[coords]->ShouldRender = true;
|
||||
|
||||
m_chunkMutex.unlock();
|
||||
m_chunkLoderMutex.unlock();
|
||||
|
||||
|
||||
while (m_chunkLoaderQueue.empty()) {
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "../renderer/camera.hpp"
|
||||
|
||||
#include "generator/chunkmanager.hpp"
|
||||
#include "chunk/chunk.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
@@ -23,14 +24,17 @@ public:
|
||||
// Default constructor
|
||||
World();
|
||||
|
||||
|
||||
// Preps the render threads and loads all of the shaders
|
||||
void LoadWorld();
|
||||
|
||||
void SetTextureMap(GLuint map);
|
||||
|
||||
// Takes world coordinates and gets a chunks coordinates
|
||||
glm::vec2 GetChunkCoords(glm::vec3 wordCoords);
|
||||
glm::vec3 GetChunkCoords(glm::vec3 wordCoords);
|
||||
|
||||
// Takes world coordinates and gets the chunk those coorinates
|
||||
// fall in
|
||||
glm::vec2 GetChunk(glm::vec3 worldCoords);
|
||||
|
||||
std::vector<std::shared_ptr<Chunk>> GetRenderableChunks();
|
||||
|
||||
@@ -59,10 +63,11 @@ private:
|
||||
// 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::queue<glm::vec2> m_chunkLoaderQueue;
|
||||
|
||||
std::mutex m_chunkMutex;
|
||||
std::mutex m_chunkLoderMutex;
|
||||
std::queue<glm::vec2> m_chunkLoaderQueue;
|
||||
|
||||
// Generator
|
||||
std::shared_ptr<FastNoise> m_noiseGenerator;
|
||||
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();
|
||||
|
||||
}
|
||||
@@ -1,7 +1,17 @@
|
||||
#ifndef MINECRAFT_RENDERER_CAMERA_H_
|
||||
#define MINECRAFT_RENDERER_CAMERA_H_
|
||||
#ifndef MINECRAFT_RENDERING_CAMERA_H_
|
||||
#define MINECRAFT_RENDERING_CAMERA_H_
|
||||
|
||||
#include "../common.hpp"
|
||||
#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:
|
||||
@@ -20,8 +30,10 @@ public:
|
||||
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;
|
||||
|
||||
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
|
||||
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
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
#include <logger.h>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../settings.hpp"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../util/stb_image.hpp"
|
||||
#include "../ThirdParty/stb_image.hpp"
|
||||
|
||||
GLuint Texture::LoadTextures(std::vector<std::string> textures) {
|
||||
|
||||
Logger logger;
|
||||
|
||||
std::string basePath = GameConfig.ResourceBase + "textures/";
|
||||
std::string basePath = ResourceBase + "textures/";
|
||||
|
||||
int x = 16;
|
||||
int y = 16;
|
||||
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
|
||||
0
src/util/glad.c → src/ThirdParty/glad.c
vendored
0
src/util/glad.c → src/ThirdParty/glad.c
vendored
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/hash.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
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
|
||||
88
src/main.cpp
88
src/main.cpp
@@ -1,14 +1,90 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "game.hpp"
|
||||
#define LOGGER_DEFINITION
|
||||
#include <logger.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
#include "display.hpp"
|
||||
#include "settings.hpp"
|
||||
|
||||
#include "Rendering/rendermaster.hpp"
|
||||
#include "Rendering/texture.hpp"
|
||||
#include "Rendering/camera.hpp"
|
||||
#include "Rendering/mesh.hpp"
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
#define __DEBUG
|
||||
|
||||
Game game;
|
||||
game.Setup(1080, 720);
|
||||
game.Run();
|
||||
static const int VERSION_MAJOR = 0;
|
||||
static const int VERSION_MINOR = 0;
|
||||
static const int VERSION_PATCH = 1;
|
||||
|
||||
return 0;
|
||||
void version()
|
||||
{
|
||||
std::stringstream version;
|
||||
|
||||
const auto& container = []( std::string s ) { std::string r = ""; for ( auto& c : s ) { r += "-"; } return r; };
|
||||
|
||||
version << "Minecraft ";
|
||||
version << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH;
|
||||
|
||||
std::cout << container( version.str() ) << std::endl;
|
||||
std::cout << version.str() << std::endl;
|
||||
std::cout << container( version.str() ) << std::endl;
|
||||
}
|
||||
|
||||
void Loop( Display* display )
|
||||
{
|
||||
SDL_Event e;
|
||||
|
||||
|
||||
|
||||
|
||||
while ( display->IsWindowOpen )
|
||||
{
|
||||
display->PrepareFrame();
|
||||
|
||||
// make framerate agnostic
|
||||
display->Input( &e );
|
||||
|
||||
// rendering here
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
display->NextFrame();
|
||||
}
|
||||
|
||||
// cleanup
|
||||
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
version();
|
||||
|
||||
Logger mLogger;
|
||||
|
||||
#ifdef __DEBUG
|
||||
mLogger << LOGGER_DEBUG << "Debug mode enabled" << LOGGER_ENDL;
|
||||
#endif
|
||||
|
||||
// settup display
|
||||
|
||||
std::stringstream version;
|
||||
version << "Minecraft ";
|
||||
version << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH;
|
||||
|
||||
Display display { WindowWidth, WindowHeight, version.str() };
|
||||
|
||||
Loop( &display );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
#include "camera.hpp"
|
||||
|
||||
Camera::Camera() {
|
||||
|
||||
projMatrix = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 1000.0f);
|
||||
|
||||
Roll = 0.0f;
|
||||
Pitch = 0.0f;
|
||||
Yaw = 0.0f;
|
||||
|
||||
Position = {};
|
||||
LookDirection = {};
|
||||
|
||||
viewMatrix = {};
|
||||
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
|
||||
Camera::Camera(int w, int h) {
|
||||
|
||||
projMatrix = glm::perspective(glm::radians(45.0f), (float)w / float(h), 0.1f, 1000.0f);
|
||||
|
||||
Roll = 0.0f;
|
||||
Pitch = 0.0f;
|
||||
Yaw = 0.0f;
|
||||
|
||||
Position = {};
|
||||
LookDirection = {};
|
||||
|
||||
viewMatrix = {};
|
||||
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
|
||||
void Camera::UpdateView() {
|
||||
|
||||
// roll can be removed
|
||||
glm::mat4 matRoll = glm::mat4(1.0f); //identity matrix;
|
||||
glm::mat4 matPitch = glm::mat4(1.0f);//identity matrix
|
||||
glm::mat4 matYaw = glm::mat4(1.0f); //identity matrix
|
||||
|
||||
// roll, pitch and yaw
|
||||
matRoll = glm::rotate(matRoll, Roll, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
matPitch = glm::rotate(matPitch, Pitch, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
matYaw = glm::rotate(matYaw, Yaw, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
glm::mat4 rotate = matRoll * matPitch * matYaw;
|
||||
|
||||
glm::mat4 translate = glm::mat4(1.0f);
|
||||
translate = glm::translate(translate, -Position);
|
||||
|
||||
viewMatrix = rotate * translate;
|
||||
|
||||
// Work out Look Vector
|
||||
glm::mat4 inverseView = glm::inverse(viewMatrix);
|
||||
|
||||
LookDirection.x = inverseView[2][0];
|
||||
LookDirection.y = inverseView[2][1];
|
||||
LookDirection.z = inverseView[2][2];
|
||||
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetViewMatrix() {
|
||||
|
||||
return viewMatrix;
|
||||
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetProjectionMatrix() {
|
||||
|
||||
return projMatrix;
|
||||
|
||||
}
|
||||
|
||||
void Camera::UpdateProjection(int width, int height) {
|
||||
|
||||
projMatrix = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 1000.0f);
|
||||
|
||||
}
|
||||
|
||||
void Camera::HandleMouse(SDL_Event e) {
|
||||
|
||||
if (e.type != SDL_MOUSEMOTION)
|
||||
return;
|
||||
|
||||
|
||||
float mouseDX = e.motion.xrel;
|
||||
float mouseDY = e.motion.yrel;
|
||||
|
||||
glm::vec2 mouseDelta{ mouseDX, mouseDY };
|
||||
|
||||
MouseMoved(mouseDelta);
|
||||
|
||||
}
|
||||
|
||||
void Camera::MoveCamera(Uint8* state) {
|
||||
|
||||
float dx = 0;
|
||||
float dz = 0;
|
||||
float dy = 0;
|
||||
|
||||
// Rotate by camera direction
|
||||
glm::mat2 rotate {
|
||||
cos(Yaw), -sin(Yaw),
|
||||
sin(Yaw), cos(Yaw)
|
||||
};
|
||||
|
||||
glm::vec2 f(0.0, 1.0);
|
||||
f = f * rotate;
|
||||
|
||||
if (state[SDL_SCANCODE_W]) {
|
||||
dz -= f.y;
|
||||
dx -= f.x;
|
||||
}
|
||||
if (state[SDL_SCANCODE_S]) {
|
||||
dz += f.y;
|
||||
dx += f.x;
|
||||
}
|
||||
if (state[SDL_SCANCODE_A]) {
|
||||
dz += f.x;
|
||||
dx += -f.y;
|
||||
}
|
||||
if (state[SDL_SCANCODE_D]) {
|
||||
dz -= f.x;
|
||||
dx -= -f.y;
|
||||
}
|
||||
if (state[SDL_SCANCODE_SPACE]) {
|
||||
dy += 1;
|
||||
}
|
||||
if (state[SDL_SCANCODE_LSHIFT]) {
|
||||
dy -= 1;
|
||||
}
|
||||
|
||||
// get current view matrix
|
||||
glm::mat4 mat = GetViewMatrix();
|
||||
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
|
||||
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
|
||||
|
||||
// forward vector must be negative to look forward.
|
||||
// read :http://in2gpu.com/2015/05/17/view-matrix/
|
||||
Position.x += dx * CameraSpeed;
|
||||
Position.z += dz * CameraSpeed;
|
||||
Position.y += dy * CameraSpeed;
|
||||
|
||||
// update the view matrix
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
|
||||
void Camera::MouseMoved(glm::vec2 mouseDelta) {
|
||||
|
||||
// note that yaw and pitch must be converted to radians.
|
||||
// this is done in UpdateView() by glm::rotate
|
||||
Yaw += MouseSensitivity * (mouseDelta.x/100);
|
||||
Pitch += MouseSensitivity * (mouseDelta.y/100);
|
||||
Pitch = glm::clamp<float>(Pitch, -M_PI/2, M_PI/2);
|
||||
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
|
||||
void Camera::UpdatePosition(glm::vec3 position) {
|
||||
|
||||
Position = position;
|
||||
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
|
||||
void Camera::UpdateEulerLookDirection(float roll, float pitch, float yaw) {
|
||||
|
||||
Roll = roll; Pitch = pitch; Yaw = yaw;
|
||||
LookDirection.x = cos(Yaw) * cos(Pitch);
|
||||
LookDirection.y = sin(Yaw) * cos(Pitch);
|
||||
LookDirection.z = sin(Pitch);
|
||||
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
|
||||
void Camera::UpdateLookDirection(glm::vec3 lookDirection) {
|
||||
|
||||
LookDirection = lookDirection;
|
||||
Pitch = asin(-lookDirection.y);
|
||||
Yaw = atan2(lookDirection.x, lookDirection.z);
|
||||
|
||||
UpdateView();
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifndef MINECRAFT_RENDERER_FRUSTRUM_H_
|
||||
#define MINECRAFT_RENDERER_FRUSTRUM_H_
|
||||
|
||||
#include "../common.hpp"
|
||||
|
||||
namespace EFrustrumPlanes {
|
||||
|
||||
enum Planes {
|
||||
|
||||
Right,
|
||||
Left,
|
||||
Top,
|
||||
Bottom,
|
||||
Far,
|
||||
Near
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class FrustrumPlane {
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
class Frustrum {
|
||||
public:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,109 +0,0 @@
|
||||
#include "shader.hpp"
|
||||
|
||||
Shader::Shader()
|
||||
: m_fileReader() {
|
||||
|
||||
Program = 0;
|
||||
m_frag = 0;
|
||||
m_vert = 0;
|
||||
|
||||
m_logger = std::make_shared<Logger>();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Shader::Load(std::string path) {
|
||||
|
||||
std::string vertexLocation = path + ".vert";
|
||||
Load(vertexLocation, GL_VERTEX_SHADER);
|
||||
*m_logger << LOGGER_INFO << "Vertex shader at '" << vertexLocation << "' loaded..." << LOGGER_ENDL;
|
||||
|
||||
|
||||
std::string fragmentLocation = path + ".frag";
|
||||
Load(fragmentLocation, GL_FRAGMENT_SHADER);
|
||||
*m_logger << LOGGER_INFO << "Fragment shader at '" << fragmentLocation << "' loaded..." << LOGGER_ENDL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Shader::Load(std::string path, GLenum type) {
|
||||
|
||||
GLuint activeShader = 0;
|
||||
|
||||
if (type == GL_VERTEX_SHADER)
|
||||
m_vert = activeShader = glCreateShader(type);
|
||||
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
m_frag = activeShader = glCreateShader(type);
|
||||
|
||||
std::string loadedShaderSource = m_fileReader.LoadTextFromFile(path);
|
||||
const char* shaderSource = loadedShaderSource.c_str();
|
||||
int shaderSourceLength = loadedShaderSource.length();
|
||||
|
||||
glShaderSource(activeShader, 1, &shaderSource, &shaderSourceLength);
|
||||
|
||||
}
|
||||
|
||||
void Shader::Link() {
|
||||
|
||||
if (m_vert == 0 || m_frag == 0) {
|
||||
*m_logger << LOGGER_ERROR << "Failed to link programs: Both programs not present" << LOGGER_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
glCompileShader(m_vert);
|
||||
if (m_CheckShader(m_vert)) {
|
||||
*m_logger << LOGGER_INFO << "Vertex shader '" << m_vert << "' compiled..." << LOGGER_ENDL;
|
||||
}
|
||||
|
||||
glCompileShader(m_frag);
|
||||
if (m_CheckShader(m_frag)) {
|
||||
*m_logger << LOGGER_INFO << "Fragment shader '" << m_frag << "' compiled..." << LOGGER_ENDL;
|
||||
}
|
||||
|
||||
Program = glCreateProgram();
|
||||
|
||||
glAttachShader(Program, m_vert);
|
||||
glAttachShader(Program, m_frag);
|
||||
|
||||
glLinkProgram(Program);
|
||||
|
||||
glDeleteShader(m_vert);
|
||||
glDeleteShader(m_frag);
|
||||
|
||||
*m_logger << LOGGER_INFO << "Program '" << Program << "' loaded..." << LOGGER_ENDL;
|
||||
|
||||
}
|
||||
|
||||
void Shader::Use() {
|
||||
|
||||
glUseProgram(Program);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Shader::m_CheckShader(GLuint uid) {
|
||||
|
||||
GLint status = GL_TRUE;
|
||||
|
||||
glGetShaderiv(uid, GL_COMPILE_STATUS, &status);
|
||||
|
||||
if (status == GL_FALSE) {
|
||||
char buf[512];
|
||||
glGetShaderInfoLog(uid, 512, NULL, buf);
|
||||
*m_logger << LOGGER_ERROR << buf << LOGGER_ENDL;
|
||||
delete buf;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Shader::~Shader() {
|
||||
|
||||
glDeleteProgram(Program);
|
||||
glDeleteShader(m_vert);
|
||||
glDeleteShader(m_frag);
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef MINECRAFT_RENDERER_SHADER_H_
|
||||
#define MINECRAFT_RENDERER_SHADER_H_
|
||||
|
||||
#include <logger.h>
|
||||
|
||||
#include "../util/filereader.hpp"
|
||||
#include "../common.hpp"
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader();
|
||||
|
||||
void Load(std::string path);
|
||||
void Load(std::string path, GLenum type);
|
||||
|
||||
GLuint Program;
|
||||
void Link();
|
||||
|
||||
void Use();
|
||||
|
||||
~Shader();
|
||||
private:
|
||||
std::shared_ptr<Logger> m_logger;
|
||||
|
||||
bool m_CheckShader(GLuint uid);
|
||||
|
||||
FileReader m_fileReader;
|
||||
|
||||
GLuint m_vert;
|
||||
GLuint m_frag;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef MINECRAFT_RENDERER_TEXTURE_H_
|
||||
#define MINECRAFT_RENDERER_TEXTURE_H_
|
||||
|
||||
#include "../common.hpp"
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
GLuint LoadTextures(std::vector<std::string> textures);
|
||||
};
|
||||
|
||||
#endif
|
||||
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 = 1000;
|
||||
static const int WindowHeight = 600;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
|
||||
Reference in New Issue
Block a user