mirror of
https://github.com/brammie15/VoxelRenderer.git
synced 2025-12-15 09:41:48 +01:00
Add MC
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
[Bb]uild/*
|
||||
!*/.gitkeep
|
||||
|
||||
cmake-build-debug/*
|
||||
|
||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
gloom
|
||||
2
.idea/VoxelEngine.iml
generated
Normal file
2
.idea/VoxelEngine.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/VoxelEngine.iml" filepath="$PROJECT_DIR$/.idea/VoxelEngine.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -4,6 +4,12 @@
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
project (gloom)
|
||||
|
||||
# set c++ 17
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
|
||||
#
|
||||
# CMake setup
|
||||
#
|
||||
@@ -78,3 +84,15 @@ target_link_libraries (${PROJECT_NAME}
|
||||
${GLAD_LIBRARIES})
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PROJECT_NAME})
|
||||
## Copy shaders to build directory with a symlink
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
${CMAKE_SOURCE_DIR}/gloom/shaders
|
||||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/shaders)
|
||||
|
||||
## Copy assets folder to build folder
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/gloom/assets
|
||||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/assets)
|
||||
|
||||
BIN
gloom/assets/dirt.png
Normal file
BIN
gloom/assets/dirt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
@@ -1,8 +1,17 @@
|
||||
#version 430 core
|
||||
#version 460 core
|
||||
precision highp float;
|
||||
|
||||
out vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 ourColor;
|
||||
in vec2 TexCoord;
|
||||
in vec3 pos;
|
||||
|
||||
uniform sampler2D ourTexture;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
FragColor = texture(ourTexture, TexCoord);
|
||||
// FragColor = vec4(1.0f, TexCoord.x, 1.0f, 1.0);
|
||||
// FragColor = vec4(137 / 255, 85 / 255, 95 / 255, 1.0f);
|
||||
}
|
||||
34
gloom/shaders/simple.shader
Normal file
34
gloom/shaders/simple.shader
Normal file
@@ -0,0 +1,34 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aColor;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
out vec3 ourColor;
|
||||
out vec2 TexCoord;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
ourColor = aColor;
|
||||
TexCoord = aTexCoord;
|
||||
}
|
||||
|
||||
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 ourColor;
|
||||
in vec2 TexCoord;
|
||||
|
||||
uniform sampler2D ourTexture;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(ourTexture, TexCoord);
|
||||
// FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0);
|
||||
}
|
||||
@@ -1,8 +1,20 @@
|
||||
#version 430 core
|
||||
#version 460 core
|
||||
precision highp float;
|
||||
|
||||
in vec3 position;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
//layout (location = 1) in vec3 aColor;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
out vec3 pos;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 1.0f);
|
||||
}
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
TexCoord = aTexCoord;
|
||||
pos = aPos;
|
||||
}
|
||||
5
gloom/src/Block.cpp
Normal file
5
gloom/src/Block.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Bram on 26/08/2024.
|
||||
//
|
||||
|
||||
#include "Block.h"
|
||||
26
gloom/src/Block.h
Normal file
26
gloom/src/Block.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by Bram on 26/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_BLOCK_H
|
||||
#define GLOOM_BLOCK_H
|
||||
|
||||
//This will hold all the data of a block, but not the mesh since this is held by the chunk
|
||||
|
||||
|
||||
#include "BlockType.h"
|
||||
|
||||
|
||||
class Block {
|
||||
public:
|
||||
Block(BlockType type) : m_type(type) {}
|
||||
|
||||
BlockType getType() const { return m_type; }
|
||||
|
||||
|
||||
private:
|
||||
BlockType m_type;
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_BLOCK_H
|
||||
17
gloom/src/BlockType.h
Normal file
17
gloom/src/BlockType.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by Bram on 26/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_BLOCKTYPE_H
|
||||
#define GLOOM_BLOCKTYPE_H
|
||||
|
||||
enum class BlockType{
|
||||
AIR = 0,
|
||||
DIRT = 1,
|
||||
STONE = 2,
|
||||
GONCALO = 3,
|
||||
SNOW = 4,
|
||||
GRASS = 5
|
||||
};
|
||||
|
||||
#endif //GLOOM_BLOCKTYPE_H
|
||||
134
gloom/src/Chunk.cpp
Normal file
134
gloom/src/Chunk.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// Created by Bram on 25/08/2024.
|
||||
//
|
||||
|
||||
#include "Chunk.h"
|
||||
#include "gloom/Mesh.h"
|
||||
#include "Cube.h"
|
||||
#include "gloom/Singleton.h"
|
||||
|
||||
#include <vector>
|
||||
#include "World.h"
|
||||
|
||||
|
||||
void Chunk::loadBlocks() {
|
||||
for (int x = 0; x < CHUNK_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
for (int z = 0; z < CHUNK_SIZE; z++) {
|
||||
glm::vec3 actualPos = glm::vec3(x, y, z) + glm::vec3(m_chunkPos.x * CHUNK_SIZE, 0, m_chunkPos.y * CHUNK_SIZE);
|
||||
BlockType blockType = generateTerrain(actualPos);
|
||||
if (m_blocks[x][y][z] != nullptr) {
|
||||
delete m_blocks[x][y][z];
|
||||
}
|
||||
m_blocks[x][y][z] = new Block(blockType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Chunk::loadMesh() {
|
||||
std::vector<Mesh::Vertex> vertexes{};
|
||||
std::vector<unsigned int> indices{};
|
||||
|
||||
for (int x = 0; x < CHUNK_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
for (int z = 0; z < CHUNK_SIZE; z++) {
|
||||
//Check direction and call LoadFace on that direction
|
||||
Block* block = this->getBlock(x, y, z);
|
||||
if (block->getType() != BlockType::AIR) {
|
||||
BlockType type = block->getType();
|
||||
//Get the block in world space using World::GetInstance().getBlock
|
||||
Block* leftBlock = World::GetInstance().getBlock(x - 1 + m_chunkPos.x * CHUNK_SIZE, y, z + m_chunkPos.y * CHUNK_SIZE);
|
||||
Block* rightBlock = World::GetInstance().getBlock(x + 1 + m_chunkPos.x * CHUNK_SIZE, y, z + m_chunkPos.y * CHUNK_SIZE);
|
||||
Block* bottomBlock = World::GetInstance().getBlock(x + m_chunkPos.x * CHUNK_SIZE, y - 1, z + m_chunkPos.y * CHUNK_SIZE);
|
||||
Block* topBlock = World::GetInstance().getBlock(x + m_chunkPos.x * CHUNK_SIZE, y + 1, z + m_chunkPos.y * CHUNK_SIZE);
|
||||
Block* backBlock = World::GetInstance().getBlock(x + m_chunkPos.x * CHUNK_SIZE, y, z - 1 + m_chunkPos.y * CHUNK_SIZE);
|
||||
Block* frontBlock = World::GetInstance().getBlock(x + m_chunkPos.x * CHUNK_SIZE, y, z + 1 + m_chunkPos.y * CHUNK_SIZE);
|
||||
|
||||
|
||||
|
||||
|
||||
if (leftBlock->getType() == BlockType::AIR) {
|
||||
Cube::LoadFace(Face::LEFT, vertexes, indices, glm::vec3(x, y, z), type);
|
||||
}
|
||||
if (rightBlock->getType() == BlockType::AIR) {
|
||||
Cube::LoadFace(Face::RIGHT, vertexes, indices, glm::vec3(x, y, z),type);
|
||||
}
|
||||
if (bottomBlock->getType() == BlockType::AIR) {
|
||||
Cube::LoadFace(Face::BOTTOM, vertexes, indices, glm::vec3(x, y, z), type);
|
||||
}
|
||||
if (topBlock->getType() == BlockType::AIR) {
|
||||
Cube::LoadFace(Face::TOP, vertexes, indices, glm::vec3(x, y, z), type);
|
||||
}
|
||||
if (backBlock->getType() == BlockType::AIR) {
|
||||
Cube::LoadFace(Face::FRONT, vertexes, indices, glm::vec3(x, y, z), type);
|
||||
}
|
||||
if (frontBlock->getType() == BlockType::AIR) {
|
||||
Cube::LoadFace(Face::BACK, vertexes, indices, glm::vec3(x, y, z), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_mesh = Mesh(vertexes, indices);
|
||||
m_mesh.setPosition(glm::vec3(m_chunkPos.x * CHUNK_SIZE, 0, m_chunkPos.y * CHUNK_SIZE));
|
||||
m_mesh.setupMesh();
|
||||
}
|
||||
|
||||
Chunk::Chunk(const glm::vec2 &pos): m_chunkPos(pos) {
|
||||
for (int x = 0; x < CHUNK_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
for (int z = 0; z < CHUNK_SIZE; z++) {
|
||||
m_blocks[x][y][z] = new Block(BlockType::AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BlockType Chunk::generateTerrain(glm::vec3 position) {
|
||||
double noise = perlin.octave2D_01((position.x * 0.01), (position.z * 0.01), 4);
|
||||
noise = pow(noise, 3);
|
||||
int height = noise * 70;
|
||||
if (position.y > height) {
|
||||
return BlockType::AIR;
|
||||
}
|
||||
else if (position.y == height) {
|
||||
//snow
|
||||
int variance = ((float)rand() / RAND_MAX) * 7; //between 0-7
|
||||
if (position.y > 20 + variance)
|
||||
return BlockType::SNOW; //snow
|
||||
return BlockType::GRASS; //grass
|
||||
}
|
||||
else {
|
||||
return BlockType::DIRT; //dirt
|
||||
}
|
||||
}
|
||||
|
||||
Chunk::Chunk() {
|
||||
// m_chunkPos = glm::vec2(0, 0);
|
||||
|
||||
for (int x = 0; x < CHUNK_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
for (int z = 0; z < CHUNK_SIZE; z++) {
|
||||
m_blocks[x][y][z] = new Block(BlockType::AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Chunk::~Chunk() {
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x) {
|
||||
for (int y = 0; y < CHUNK_HEIGHT; ++y) {
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z) {
|
||||
delete m_blocks[x][y][z]; // Delete each dynamically allocated Block
|
||||
m_blocks[x][y][z] = nullptr; // Set the pointer to nullptr to avoid dangling references
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
69
gloom/src/Chunk.h
Normal file
69
gloom/src/Chunk.h
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Created by Bram on 25/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_CHUNK_H
|
||||
#define GLOOM_CHUNK_H
|
||||
|
||||
#include "gloom/config.hpp"
|
||||
#include "gloom/Mesh.h"
|
||||
#include "gloom/PerlinNoise.hpp"
|
||||
#include "BlockType.h"
|
||||
#include "Block.h"
|
||||
|
||||
enum class ChunkLoadStatus{
|
||||
GENERATED,
|
||||
GENERATING,
|
||||
NOT_GENERATED,
|
||||
NOT_AVAILABLE,
|
||||
};
|
||||
|
||||
static const int BLOCK_TYPES_COUNT = 4;
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
Chunk();
|
||||
Chunk(const glm::vec2& pos);
|
||||
|
||||
~Chunk();
|
||||
|
||||
void loadBlocks();
|
||||
void loadMesh();
|
||||
|
||||
void Draw(GLuint shaderProgram) {
|
||||
m_mesh.draw(shaderProgram);
|
||||
}
|
||||
|
||||
Mesh m_mesh;
|
||||
|
||||
BlockType generateTerrain(glm::vec3 position);
|
||||
|
||||
Block* getBlock(int x, int y, int z) {
|
||||
//if out of bounds, return dirt
|
||||
if (x < 0 || x >= CHUNK_SIZE || y < 0 || y >= CHUNK_HEIGHT || z < 0 || z >= CHUNK_SIZE) {
|
||||
return new Block(BlockType::AIR);
|
||||
} else {
|
||||
if(m_blocks[x][y][z] == nullptr) {
|
||||
return new Block(BlockType::AIR);
|
||||
} else {
|
||||
return m_blocks[x][y][z];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setBlock(int x, int y, int z, const Block& block) {
|
||||
m_blocks[x][y][z] = new Block(block.getType());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Block* m_blocks[CHUNK_SIZE][CHUNK_HEIGHT][CHUNK_SIZE]{ nullptr };
|
||||
|
||||
glm::vec3 m_position;
|
||||
glm::vec2 m_chunkPos;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_CHUNK_H
|
||||
140
gloom/src/Cube.cpp
Normal file
140
gloom/src/Cube.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#include "Cube.h"
|
||||
|
||||
glm::vec3 unitVertices[8] = {
|
||||
glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f),
|
||||
glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f),
|
||||
glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(1.0f, 0.0f, 1.0f),
|
||||
glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 1.0f, 1.0f)
|
||||
};
|
||||
|
||||
|
||||
unsigned int faceVertices[6][4] = {
|
||||
{3, 2, 6, 7},
|
||||
{1, 0, 4, 5},
|
||||
{4, 0, 3, 7},
|
||||
{1, 5, 6, 2},
|
||||
// FRONT (0, 1, 2, 3)
|
||||
{0, 1, 2, 3},
|
||||
// BACK (5, 4, 7, 6)
|
||||
{5, 4, 7, 6}
|
||||
};
|
||||
|
||||
static const glm::vec2 DIRTCOORDS = Cube::getTexCoords(0);
|
||||
static const glm::vec2 STONECOORDS = Cube::getTexCoords(1);
|
||||
static const glm::vec2 GONCALOCOORDS = Cube::getTexCoords(2);
|
||||
static const glm::vec2 GRASSCOORDS = Cube::getTexCoords(3);
|
||||
static const glm::vec2 SNOWCOORDS = Cube::getTexCoords(4);
|
||||
|
||||
Cube::Cube(const glm::vec3 &position, BlockType blockType) : position(position), texture("assets/dirt.png"),
|
||||
type(blockType) {
|
||||
// setupCube();
|
||||
}
|
||||
|
||||
void Cube::LoadFace(Face face, std::vector<Mesh::Vertex> &vertices, std::vector<unsigned int> &indices, const glm::vec3 &position, BlockType type) {
|
||||
|
||||
glm::vec3 normal;
|
||||
switch (face) {
|
||||
case Face::TOP:
|
||||
normal = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
case Face::BOTTOM:
|
||||
normal = glm::vec3(0.0f, -1.0f, 0.0f);
|
||||
break;
|
||||
case Face::LEFT:
|
||||
normal = glm::vec3(-1.0f, 0.0f, 0.0f);
|
||||
break;
|
||||
case Face::RIGHT:
|
||||
normal = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||
break;
|
||||
case Face::FRONT:
|
||||
normal = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
case Face::BACK:
|
||||
normal = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
glm::vec2 textureOffset = glm::vec2(0.0f, 0.0f);
|
||||
|
||||
switch(type){
|
||||
case BlockType::STONE:
|
||||
textureOffset = STONECOORDS;
|
||||
break;
|
||||
case BlockType::DIRT:
|
||||
textureOffset = DIRTCOORDS;
|
||||
break;
|
||||
case BlockType::GONCALO:
|
||||
textureOffset = GONCALOCOORDS;
|
||||
break;
|
||||
case BlockType::GRASS:
|
||||
textureOffset = GRASSCOORDS;
|
||||
break;
|
||||
case BlockType::SNOW:
|
||||
textureOffset = SNOWCOORDS;
|
||||
break;
|
||||
}
|
||||
|
||||
glm::vec2 uvCoordinates[4] = {
|
||||
glm::vec2(textureOffset.x, textureOffset.y + CELL_HEIGHT),
|
||||
glm::vec2(textureOffset.x + CELL_WIDTH, textureOffset.y + CELL_HEIGHT),
|
||||
glm::vec2(textureOffset.x + CELL_WIDTH, textureOffset.y),
|
||||
glm::vec2(textureOffset.x, textureOffset.y)
|
||||
};
|
||||
|
||||
unsigned int index = vertices.size();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
unsigned int vertexIndex = faceVertices[faceToIndex(face)][i];
|
||||
Mesh::Vertex v;
|
||||
v.position = unitVertices[vertexIndex] + position;
|
||||
v.texCoords = uvCoordinates[i];
|
||||
vertices.push_back(v);
|
||||
}
|
||||
|
||||
indices.push_back(index);
|
||||
indices.push_back(index + 1);
|
||||
indices.push_back(index + 2);
|
||||
indices.push_back(index);
|
||||
indices.push_back(index + 2);
|
||||
indices.push_back(index + 3);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Cube::LoadAllFaces(std::vector<Mesh::Vertex> &vertices, std::vector<unsigned int> &indices, const glm::vec3 &position, BlockType type) {
|
||||
Cube::LoadFace(Face::TOP, vertices, indices, position, type);
|
||||
Cube::LoadFace(Face::BOTTOM, vertices, indices, position, type);
|
||||
Cube::LoadFace(Face::LEFT, vertices, indices, position, type);
|
||||
Cube::LoadFace(Face::RIGHT, vertices, indices, position, type);
|
||||
Cube::LoadFace(Face::FRONT, vertices, indices, position, type);
|
||||
Cube::LoadFace(Face::BACK, vertices, indices, position, type);
|
||||
}
|
||||
|
||||
int Cube::faceToIndex(Face face) {
|
||||
switch (face) {
|
||||
case Face::TOP:
|
||||
return 0;
|
||||
case Face::BOTTOM:
|
||||
return 1;
|
||||
case Face::LEFT:
|
||||
return 2;
|
||||
case Face::RIGHT:
|
||||
return 3;
|
||||
case Face::FRONT:
|
||||
return 4;
|
||||
case Face::BACK:
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
glm::dvec2 Cube::getTexCoords(int pos) {
|
||||
int x = pos % TEXTURE_WIDTH;
|
||||
int y = pos / 16;
|
||||
return glm::vec2(x * CELL_WIDTH, y * CELL_HEIGHT);
|
||||
}
|
||||
62
gloom/src/Cube.h
Normal file
62
gloom/src/Cube.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_CUBE_H
|
||||
#define GLOOM_CUBE_H
|
||||
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include "glad/glad.h"
|
||||
#include "gloom/Texture.h"
|
||||
#include "gloom/config.hpp"
|
||||
#include "Chunk.h"
|
||||
#include "gloom/Mesh.h"
|
||||
|
||||
struct CubeVertex {
|
||||
CubeVertex(glm::vec3 pos, glm::vec3 color, glm::vec2 texCoords) : position(pos), color(color),
|
||||
texCoords(texCoords) {};
|
||||
|
||||
glm::vec3 position;
|
||||
glm::vec3 color;
|
||||
glm::vec2 texCoords;
|
||||
};
|
||||
|
||||
|
||||
enum Face {
|
||||
TOP = 0x01, // 0000 0001
|
||||
BOTTOM = 0x02, // 0000 0010
|
||||
LEFT = 0x04, // 0000 0100
|
||||
RIGHT = 0x08, // 0000 1000
|
||||
FRONT = 0x10, // 0001 0000
|
||||
BACK = 0x20 // 0010 0000
|
||||
};
|
||||
|
||||
|
||||
class Cube {
|
||||
public:
|
||||
explicit Cube(const glm::vec3 &position, BlockType blockType);
|
||||
|
||||
|
||||
static void LoadFace(Face face, std::vector<Mesh::Vertex>& vertices, std::vector<unsigned int>& indices, const glm::vec3& position, BlockType type);
|
||||
static void LoadAllFaces(std::vector<Mesh::Vertex>& vertices, std::vector<unsigned int>& indices, const glm::vec3& position, BlockType type);
|
||||
|
||||
static int faceToIndex(Face face);
|
||||
|
||||
static glm::dvec2 getTexCoords(int pos);
|
||||
|
||||
Mesh* mesh;
|
||||
private:
|
||||
glm::vec3 position;
|
||||
|
||||
Texture texture;
|
||||
BlockType type{ BlockType::AIR };
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_CUBE_H
|
||||
273
gloom/src/Game.cpp
Normal file
273
gloom/src/Game.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#include "Game.h"
|
||||
#include "gloom/config.hpp"
|
||||
#include "gloom/Camera.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// A callback which allows GLFW to report errors whenever they occur
|
||||
static void glfwErrorCallback(int error, const char *description) {
|
||||
fprintf(stderr, "GLFW returned an error:\n\t%s (%i)\n", description, error);
|
||||
}
|
||||
|
||||
static void mouse_callback(GLFWwindow *window, double xpos, double ypos) {
|
||||
glm::vec2 mousePos((float) xpos, (float) -ypos);
|
||||
|
||||
Camera::getInstance().updateMouse(mousePos);
|
||||
|
||||
}
|
||||
|
||||
Game::Game() {
|
||||
// Initialise GLFW
|
||||
if (!glfwInit()) {
|
||||
fprintf(stderr, "Could not start GLFW\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set core window options (adjust version numbers if needed)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
// Enable the GLFW runtime error callback function defined previously.
|
||||
glfwSetErrorCallback(glfwErrorCallback);
|
||||
// We to good for errors
|
||||
|
||||
// Set additional window options
|
||||
glfwWindowHint(GLFW_RESIZABLE, windowResizable);
|
||||
// glfwWindowHint(GLFW_SAMPLES, windowSamples); // MSAA
|
||||
|
||||
// glDisable(GL_MULTISAMPLE);
|
||||
|
||||
// Create window using GLFW
|
||||
m_window = glfwCreateWindow(windowWidth,
|
||||
windowHeight,
|
||||
windowTitle.c_str(),
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
// Ensure the window is set up correctly
|
||||
if (!m_window) {
|
||||
fprintf(stderr, "Could not open GLFW window\n");
|
||||
//Get the error and print it
|
||||
const char *description;
|
||||
int error = glfwGetError(&description);
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the window be the current OpenGL context and initialise glad
|
||||
glfwMakeContextCurrent(m_window);
|
||||
gladLoadGL();
|
||||
|
||||
// Print various OpenGL information to stdout
|
||||
printf("%s: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
|
||||
printf("GLFW\t %s\n", glfwGetVersionString());
|
||||
printf("OpenGL\t %s\n", glGetString(GL_VERSION));
|
||||
printf("GLSL\t %s\n\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
// Set up the mouse callback
|
||||
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
glfwSetCursorPosCallback(m_window, mouse_callback);
|
||||
|
||||
// Set up the shader
|
||||
m_shader.setShader("shaders/simple.vert", "shaders/simple.frag");
|
||||
|
||||
// Set up the block
|
||||
// // 16 x 16
|
||||
// for (int x = 0; x < CHUNK_SIZE; x+=1) {
|
||||
// for(int y = 0; y < CHUNK_HEIGHT / 4; y+=1) {
|
||||
// for (int z = 0; z < CHUNK_SIZE; z+=1) {
|
||||
// BlockType type = static_cast<BlockType>(rand() % 3);
|
||||
// m_cubes.emplace_back(glm::vec3(x, y, z), type);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// //10 x 10 chunk
|
||||
// for (int i = 0; i < 10; ++i) {
|
||||
// for (int j = 0; j < 10; ++j) {
|
||||
// m_chunks.push_back(new Chunk(glm::vec2(i, j)));
|
||||
// m_chunks[m_chunks.size() - 1]->loadBlocks();
|
||||
// m_chunks[m_chunks.size() - 1]->loadMesh();
|
||||
// }
|
||||
// }
|
||||
|
||||
m_world = &World::GetInstance();
|
||||
m_world->generateChunk(0, 0);
|
||||
// m_world->generateChunk(1, 0);
|
||||
// m_world->getChunk(0, 0)->loadMesh();
|
||||
// m_world->generateChunk(0, 1);
|
||||
// m_world->generateChunk(1, 1);
|
||||
// m_world->getChunk(1, 0)->loadMesh();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void Game::run() {
|
||||
// Enable depth (Z) buffer (accept "closest" fragment)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
// Configure miscellaneous OpenGL settings
|
||||
// glEnable(GL_CULL_FACE);
|
||||
|
||||
// Set default colour after clearing the colour buffer
|
||||
glClearColor(0.3f, 0.5f, 0.8f, 1.0f);
|
||||
|
||||
double lastChunkUpdate = glfwGetTime();
|
||||
|
||||
// Set up your scene here (create Vertex Array Objects, etc.)
|
||||
|
||||
// Rendering Loop
|
||||
while (!glfwWindowShouldClose(this->m_window)) {
|
||||
|
||||
// Calculate delta time
|
||||
double currentTime = glfwGetTime();
|
||||
m_deltaTime = currentTime - m_lastFrameTime;
|
||||
m_lastFrameTime = currentTime;
|
||||
|
||||
// // wait until next frame with fps
|
||||
// while (glfwGetTime() - m_lastFrameTime < 1.0 / MAX_FPS) {
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// Clear colour and depth buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Draw your scene here
|
||||
|
||||
// Set the shader program
|
||||
m_shader.use();
|
||||
glViewport(0, 0, windowWidth, windowHeight);
|
||||
|
||||
m_shader.setMat4("view", Camera::getInstance().getViewMatrix());
|
||||
m_shader.setMat4("projection", Camera::getInstance().projectionMatrix);
|
||||
|
||||
|
||||
// for (auto &chunk: m_chunks) {
|
||||
// chunk->Draw(m_shader.ID);
|
||||
// }
|
||||
//
|
||||
m_world->Draw(m_shader.ID, Camera::getInstance().camPos);
|
||||
//
|
||||
// // if player is above chunk that is not generated, generate it, add a variance of the renderdistance
|
||||
int playerX = (int) Camera::getInstance().camPos.x / CHUNK_SIZE;
|
||||
int playerZ = (int) Camera::getInstance().camPos.z / CHUNK_SIZE;
|
||||
|
||||
if(glfwGetTime() - lastChunkUpdate > 0.5) {
|
||||
lastChunkUpdate = glfwGetTime();
|
||||
for (int x = playerX - RENDER_DISTANCE; x < playerX + RENDER_DISTANCE; x++) {
|
||||
for (int z = playerZ - RENDER_DISTANCE; z < playerZ + RENDER_DISTANCE; z++) {
|
||||
if (m_world->isChunkGenerated(x,z) == ChunkLoadStatus::NOT_GENERATED) {
|
||||
m_world->generateChunk(x, z);
|
||||
//Now take the 4 chunks next to it and update those
|
||||
//
|
||||
if (m_world->isChunkGenerated(x + 1, z) == ChunkLoadStatus::GENERATED) {
|
||||
m_world->getChunk(x + 1, z)->loadMesh();
|
||||
}
|
||||
if (m_world->isChunkGenerated(x - 1, z) == ChunkLoadStatus::GENERATED) {
|
||||
m_world->getChunk(x - 1, z)->loadMesh();
|
||||
}
|
||||
if (m_world->isChunkGenerated(x, z + 1) == ChunkLoadStatus::GENERATED) {
|
||||
m_world->getChunk(x, z + 1)->loadMesh();
|
||||
}
|
||||
if (m_world->isChunkGenerated(x, z - 1) == ChunkLoadStatus::GENERATED) {
|
||||
m_world->getChunk(x, z - 1)->loadMesh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
// Handle other events
|
||||
glfwPollEvents();
|
||||
this->handleKeyboard();
|
||||
|
||||
// Flip buffers
|
||||
glfwSwapBuffers(this->m_window);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Game::handleKeyboard() {
|
||||
if (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(m_window, GL_TRUE);
|
||||
}
|
||||
|
||||
glm::vec3 moveDir(0, 0, 0);
|
||||
|
||||
//movement
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
moveDir.z -= 1; // Move forward
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
moveDir.z += 1; // Move backward
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
moveDir.x -= 1; // Move left
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
moveDir.x += 1; // Move right
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_E) == GLFW_PRESS)
|
||||
moveDir.y += 1;
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_Q) == GLFW_PRESS)
|
||||
moveDir.y -= 1;
|
||||
|
||||
if (length(moveDir) > 0)
|
||||
Camera::getInstance().updatePos(normalize(moveDir), m_deltaTime);
|
||||
|
||||
static bool lastR = false; //Kinda shitty but damm i could not care less
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_R) == GLFW_PRESS && !lastR) {
|
||||
renderWireframe = !renderWireframe;
|
||||
lastR = true;
|
||||
} else if (glfwGetKey(this->m_window, GLFW_KEY_R) == GLFW_RELEASE) {
|
||||
lastR = false;
|
||||
}
|
||||
|
||||
//unlock mouse
|
||||
static bool keyWasPressed = false;
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_T) == GLFW_PRESS) {
|
||||
if (!keyWasPressed) {
|
||||
m_isMouseLocked = !m_isMouseLocked; // Toggle the state
|
||||
glfwSetInputMode(this->m_window, GLFW_CURSOR, m_isMouseLocked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
|
||||
keyWasPressed = true;
|
||||
}
|
||||
} else {
|
||||
keyWasPressed = false;
|
||||
}
|
||||
|
||||
|
||||
static bool balls = false;
|
||||
if (glfwGetKey(this->m_window, GLFW_KEY_F) == GLFW_PRESS) {
|
||||
if (!balls) {
|
||||
//Random number between 1234u and 500u
|
||||
SEED = rand() * 10000u;
|
||||
perlin = siv::PerlinNoise(SEED);
|
||||
m_world->generateChunk(1, 0);
|
||||
m_world->generateChunk(0, 1);
|
||||
m_world->generateChunk(0, 0);
|
||||
m_world->generateChunk(1, 1);
|
||||
std::cout << "Seed: " << SEED << std::endl;
|
||||
balls = true;
|
||||
}
|
||||
} else {
|
||||
balls = false;
|
||||
}
|
||||
|
||||
}
|
||||
43
gloom/src/Game.h
Normal file
43
gloom/src/Game.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_GAME_H
|
||||
#define GLOOM_GAME_H
|
||||
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "gloom/Shader.h"
|
||||
#include "Cube.h"
|
||||
#include "World.h"
|
||||
|
||||
static void glfwErrorCallback(int error, const char *description);
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game();
|
||||
~Game();
|
||||
|
||||
void run();
|
||||
void handleKeyboard();
|
||||
|
||||
|
||||
private:
|
||||
GLFWwindow* m_window;
|
||||
|
||||
bool m_isMouseLocked{ false };
|
||||
|
||||
double m_lastFrameTime{ 0.0 };
|
||||
double m_deltaTime{ 0.0 };
|
||||
|
||||
Shader m_shader;
|
||||
|
||||
// Mesh* m_mesh;
|
||||
// std::vector<Chunk*> m_chunks;
|
||||
// std::vector<Cube> m_cubes;
|
||||
|
||||
World* m_world;
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_GAME_H
|
||||
104
gloom/src/World.cpp
Normal file
104
gloom/src/World.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// Created by Bram on 26/08/2024.
|
||||
//
|
||||
|
||||
#include "World.h"
|
||||
#include <iostream>
|
||||
Chunk * World::getChunk(int x, int z) {
|
||||
return chunks[x][z];
|
||||
}
|
||||
|
||||
void World::generateChunk(int x, int z) {
|
||||
//Calc offset so there is a 1 block space between each chunk
|
||||
// glm::vec2 offset = glm::vec2(x * 2, z * 2);
|
||||
if(chunks[x][z] != nullptr){
|
||||
delete chunks[x][z];
|
||||
}
|
||||
|
||||
chunks[x][z] = new Chunk(glm::vec2(x, z));
|
||||
chunkGenerated[x][z] = ChunkLoadStatus::GENERATING;
|
||||
chunks[x][z]->loadBlocks();
|
||||
chunks[x][z]->loadMesh();
|
||||
chunkGenerated[x][z] = ChunkLoadStatus::GENERATED;
|
||||
|
||||
//Call the sourounding chunks to update their mesh
|
||||
if (x > 0) {
|
||||
if(chunkGenerated[x - 1][z] == ChunkLoadStatus::GENERATED)
|
||||
chunks[x - 1][z]->loadMesh();
|
||||
}
|
||||
if (x < WORLD_WIDTH - 1) {
|
||||
if(chunkGenerated[x + 1][z] == ChunkLoadStatus::GENERATED)
|
||||
chunks[x + 1][z]->loadMesh();
|
||||
}
|
||||
if (z > 0) {
|
||||
if(chunkGenerated[x][z - 1] == ChunkLoadStatus::GENERATED)
|
||||
chunks[x][z - 1]->loadMesh();
|
||||
}
|
||||
if (z < WORLD_HEIGHT - 1) {
|
||||
if(chunkGenerated[x][z + 1] == ChunkLoadStatus::GENERATED)
|
||||
chunks[x][z + 1]->loadMesh();
|
||||
}
|
||||
}
|
||||
|
||||
Block* World::getBlock(int x, int y, int z) {
|
||||
int chunkX = x / CHUNK_SIZE;
|
||||
int chunkZ = z / CHUNK_SIZE;
|
||||
|
||||
int blockX = x % CHUNK_SIZE;
|
||||
int blockZ = z % CHUNK_SIZE;
|
||||
|
||||
Chunk* chunk = chunks[chunkX][chunkZ];
|
||||
ChunkLoadStatus status = isChunkGenerated(chunkX, chunkZ);
|
||||
|
||||
// check if the chunk is generated
|
||||
switch(isChunkGenerated(chunkX, chunkZ)) {
|
||||
case ChunkLoadStatus::NOT_GENERATED:
|
||||
// generateChunk(chunkX, chunkZ);
|
||||
return new Block(BlockType::DIRT);
|
||||
break;
|
||||
case ChunkLoadStatus::NOT_AVAILABLE:
|
||||
return new Block(BlockType::AIR);
|
||||
break;
|
||||
case ChunkLoadStatus::GENERATING:
|
||||
//Prob current chunk is generating
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return chunks[chunkX][chunkZ]->getBlock(blockX, y, blockZ);
|
||||
}
|
||||
|
||||
void World::setBlock(int x, int y, int z, const Block &block) {
|
||||
int chunkX = x / CHUNK_SIZE;
|
||||
int chunkZ = z / CHUNK_SIZE;
|
||||
|
||||
int blockX = x % CHUNK_SIZE;
|
||||
int blockZ = z % CHUNK_SIZE;
|
||||
|
||||
chunks[chunkX][chunkZ]->setBlock(blockX, y, blockZ, block);
|
||||
}
|
||||
|
||||
void World::Draw(GLuint shaderProgram, glm::vec3 playerPos) {
|
||||
for (int x = 0; x < WORLD_WIDTH; x++) {
|
||||
for (int z = 0; z < WORLD_HEIGHT; z++) {
|
||||
//Check if the player is RENDERDISTANCE chunks away from the chunk
|
||||
if (glm::distance(playerPos, glm::vec3(x * CHUNK_SIZE, 0, z * CHUNK_SIZE)) > RENDER_DISTANCE * CHUNK_SIZE) {
|
||||
continue;
|
||||
}
|
||||
if (chunkGenerated[x][z] == ChunkLoadStatus::GENERATED) {
|
||||
chunks[x][z]->Draw(shaderProgram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
World::World() {
|
||||
for (int x = 0; x < WORLD_WIDTH; x++) {
|
||||
for (int z = 0; z < WORLD_HEIGHT; z++) {
|
||||
chunks[x][z] = nullptr;
|
||||
chunkGenerated[x][z] = ChunkLoadStatus::NOT_GENERATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
gloom/src/World.h
Normal file
42
gloom/src/World.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by Bram on 26/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_WORLD_H
|
||||
#define GLOOM_WORLD_H
|
||||
|
||||
#include <vector>
|
||||
#include "Chunk.h"
|
||||
#include "gloom/Singleton.h"
|
||||
|
||||
|
||||
class World: public Singleton<World> {
|
||||
public:
|
||||
World();
|
||||
Chunk * getChunk(int x, int z);
|
||||
void generateChunk(int x, int z);
|
||||
|
||||
//Optional ig
|
||||
Block* getBlock(int x, int y, int z);
|
||||
void setBlock(int x, int y, int z, const Block& block);
|
||||
|
||||
void Draw(GLuint shaderProgram, glm::vec3 playerPos);
|
||||
|
||||
ChunkLoadStatus isChunkGenerated(int x, int z) {
|
||||
//if out of bounds, return true
|
||||
if (x < 0 || x >= WORLD_WIDTH || z < 0 || z >= WORLD_HEIGHT) {
|
||||
return ChunkLoadStatus::NOT_AVAILABLE;
|
||||
} else {
|
||||
return chunkGenerated[x][z];
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//2D array
|
||||
Chunk* chunks[WORLD_HEIGHT][WORLD_WIDTH]{ nullptr };
|
||||
ChunkLoadStatus chunkGenerated[WORLD_HEIGHT][WORLD_WIDTH]{ ChunkLoadStatus::NOT_GENERATED };
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_WORLD_H
|
||||
64
gloom/src/gloom/Camera.cpp
Normal file
64
gloom/src/gloom/Camera.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
const float CAM_SENSITIVITY = .002f;
|
||||
const float CAM_SPEED = 20;
|
||||
|
||||
//projection params
|
||||
|
||||
Camera::Camera() {
|
||||
projectionMatrix = glm::perspective(glm::radians(FOV), (float)SCR_WIDTH / SCR_HEIGHT, NEAR_PLANE, FAR_PLANE);
|
||||
camPos = glm::vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
glm::vec3 Camera::getFrontVector() {
|
||||
glm::vec3 front;
|
||||
front.x = cos(cameraAngle.x) * cos(cameraAngle.y);
|
||||
front.y = sin(cameraAngle.y);
|
||||
front.z = sin(cameraAngle.x) * cos(cameraAngle.y);
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
void Camera::updateMouse(glm::vec2 mousePos) {
|
||||
glm::vec2 offset = mousePos - lastMousePos;
|
||||
lastMousePos = mousePos;
|
||||
cameraAngle += offset * CAM_SENSITIVITY;
|
||||
cameraAngle.y = glm::clamp(cameraAngle.y, glm::radians(-89.0f), glm::radians(89.0f));
|
||||
}
|
||||
|
||||
|
||||
void Camera::updatePos(glm::vec3 moveDirection, double dt) {
|
||||
glm::vec3 up(0.0f, 1.0f, 0.0f);
|
||||
|
||||
glm::vec3 front = glm::normalize(getFrontVector());
|
||||
glm::vec3 right = glm::normalize(glm::cross(front, up));
|
||||
up = glm::normalize(glm::cross(right, front));
|
||||
|
||||
camPos += up * moveDirection.y * CAM_SPEED * (float)dt;
|
||||
camPos += front * moveDirection.z * -CAM_SPEED * (float)dt;
|
||||
camPos += right * moveDirection.x * CAM_SPEED * (float)dt;
|
||||
|
||||
// Camera::print();
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getViewMatrix() {
|
||||
glm::vec3 front = getFrontVector();
|
||||
|
||||
glm::vec3 cameraTarget = camPos + front;
|
||||
|
||||
|
||||
return glm::lookAt(camPos, cameraTarget, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
}
|
||||
|
||||
void Camera::print() {
|
||||
std::cout << "Camera Position: " << camPos.x << ", " << camPos.y << ", " <<camPos.z << std::endl;
|
||||
}
|
||||
|
||||
Camera& Camera::getInstance() {
|
||||
static Camera instance;
|
||||
return instance;
|
||||
}
|
||||
44
gloom/src/gloom/Camera.h
Normal file
44
gloom/src/gloom/Camera.h
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_CAMERA_H
|
||||
#define GLOOM_CAMERA_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <iostream>
|
||||
|
||||
class Camera
|
||||
{
|
||||
private:
|
||||
glm::vec2 cameraAngle; //pitch and yaw
|
||||
glm::vec3 getFrontVector();
|
||||
glm::vec2 lastMousePos = glm::vec2(400.0f, 300.0f);
|
||||
|
||||
|
||||
|
||||
Camera();
|
||||
|
||||
public:
|
||||
|
||||
//constants
|
||||
static constexpr int SCR_WIDTH = 1200;
|
||||
static constexpr int SCR_HEIGHT = 900;
|
||||
static constexpr float FOV = 90;
|
||||
static constexpr float NEAR_PLANE = 0.1f;
|
||||
static constexpr float FAR_PLANE = 200.0f;
|
||||
|
||||
static Camera& getInstance();
|
||||
|
||||
glm::vec3 camPos = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
void updateMouse(glm::vec2 mousePos);
|
||||
void updatePos(glm::vec3 moveDirection, double dt);
|
||||
void print();
|
||||
glm::mat4 getViewMatrix();
|
||||
glm::mat4 projectionMatrix;
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_CAMERA_H
|
||||
89
gloom/src/gloom/Mesh.cpp
Normal file
89
gloom/src/gloom/Mesh.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#include "Mesh.h"
|
||||
#include "glad/glad.h"
|
||||
#include "config.hpp"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <iostream>
|
||||
#include "TextureManager.h"
|
||||
|
||||
Mesh::Mesh() {
|
||||
VAO = 0;
|
||||
VBO = 0;
|
||||
EBO = 0;
|
||||
VAOSIZE = 0;
|
||||
}
|
||||
|
||||
Mesh::~Mesh() {
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &EBO);
|
||||
}
|
||||
|
||||
Mesh::Mesh(const std::vector<Vertex> &vertices, const std::vector<unsigned int> &indices) {
|
||||
this->vertices = vertices;
|
||||
this->indices = indices;
|
||||
m_texture = TextureManager::GetInstance().getTexture("assets/dirt.png");
|
||||
setupMesh();
|
||||
}
|
||||
|
||||
void Mesh::draw(GLuint shaderID) {
|
||||
|
||||
glUseProgram(shaderID);
|
||||
|
||||
GLuint modelLoc = glGetUniformLocation(shaderID, "model");
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
|
||||
model = glm::translate(model, m_position);
|
||||
model = glm::rotate(model, glm::radians(m_rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
model = glm::rotate(model, glm::radians(m_rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
model = glm::rotate(model, glm::radians(m_rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
model = glm::scale(model, m_scale);
|
||||
|
||||
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
|
||||
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
if(renderWireframe) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
} else {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
m_texture->bind(0);
|
||||
|
||||
//Get error
|
||||
glDrawElements(GL_TRIANGLES, VAOSIZE, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::setupMesh() {
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// vertex positions
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, position));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// vertex texture coords
|
||||
glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, texCoords));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Free memory
|
||||
VAOSIZE = indices.size(); // Now using the size of the indices
|
||||
}
|
||||
46
gloom/src/gloom/Mesh.h
Normal file
46
gloom/src/gloom/Mesh.h
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_MESH_H
|
||||
#define GLOOM_MESH_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include "glad/glad.h"
|
||||
#include "Texture.h"
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
struct Vertex{
|
||||
glm::vec3 position;
|
||||
glm::dvec2 texCoords;
|
||||
};
|
||||
|
||||
Mesh();
|
||||
~Mesh();
|
||||
Mesh(const std::vector<Mesh::Vertex>& vertices, const std::vector<unsigned int>& indices);
|
||||
|
||||
|
||||
void draw(GLuint shaderID);
|
||||
void setupMesh();
|
||||
|
||||
void setPosition(glm::vec3 position) { m_position = position; }
|
||||
void setRotation(glm::vec3 rotation) { m_rotation = rotation; }
|
||||
void setScale(glm::vec3 scale) { m_scale = scale; }
|
||||
private:
|
||||
unsigned int VAO, VBO, EBO, VAOSIZE;
|
||||
|
||||
glm::vec3 m_position{ 0.0f, -5.0f, 0.0f };
|
||||
glm::vec3 m_rotation{ 0.0f, 0.0f, 0.0f };
|
||||
glm::vec3 m_scale{ 1.0f, 1.0f, 1.0f };
|
||||
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
Texture* m_texture{ nullptr };
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_MESH_H
|
||||
659
gloom/src/gloom/PerlinNoise.hpp
Normal file
659
gloom/src/gloom/PerlinNoise.hpp
Normal file
@@ -0,0 +1,659 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// siv::PerlinNoise
|
||||
// Perlin noise library for modern C++
|
||||
//
|
||||
// Copyright (C) 2013-2021 Ryo Suzuki <reputeless@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
# pragma once
|
||||
# include <cstdint>
|
||||
# include <algorithm>
|
||||
# include <array>
|
||||
# include <iterator>
|
||||
# include <numeric>
|
||||
# include <random>
|
||||
# include <type_traits>
|
||||
|
||||
# if __has_include(<concepts>) && defined(__cpp_concepts)
|
||||
# include <concepts>
|
||||
# endif
|
||||
|
||||
|
||||
// Library major version
|
||||
# define SIVPERLIN_VERSION_MAJOR 3
|
||||
|
||||
// Library minor version
|
||||
# define SIVPERLIN_VERSION_MINOR 0
|
||||
|
||||
// Library revision version
|
||||
# define SIVPERLIN_VERSION_REVISION 0
|
||||
|
||||
// Library version
|
||||
# define SIVPERLIN_VERSION ((SIVPERLIN_VERSION_MAJOR * 100 * 100) + (SIVPERLIN_VERSION_MINOR * 100) + (SIVPERLIN_VERSION_REVISION))
|
||||
|
||||
|
||||
// [[nodiscard]] for constructors
|
||||
# if (201907L <= __has_cpp_attribute(nodiscard))
|
||||
# define SIVPERLIN_NODISCARD_CXX20 [[nodiscard]]
|
||||
# else
|
||||
# define SIVPERLIN_NODISCARD_CXX20
|
||||
# endif
|
||||
|
||||
|
||||
// std::uniform_random_bit_generator concept
|
||||
# if __cpp_lib_concepts
|
||||
# define SIVPERLIN_CONCEPT_URBG template <std::uniform_random_bit_generator URBG>
|
||||
# define SIVPERLIN_CONCEPT_URBG_ template <std::uniform_random_bit_generator URBG>
|
||||
# else
|
||||
# define SIVPERLIN_CONCEPT_URBG template <class URBG, std::enable_if_t<std::conjunction_v<std::is_invocable<URBG&>, std::is_unsigned<std::invoke_result_t<URBG&>>>>* = nullptr>
|
||||
# define SIVPERLIN_CONCEPT_URBG_ template <class URBG, std::enable_if_t<std::conjunction_v<std::is_invocable<URBG&>, std::is_unsigned<std::invoke_result_t<URBG&>>>>*>
|
||||
# endif
|
||||
|
||||
|
||||
// arbitrary value for increasing entropy
|
||||
# ifndef SIVPERLIN_DEFAULT_Y
|
||||
# define SIVPERLIN_DEFAULT_Y (0.12345)
|
||||
# endif
|
||||
|
||||
// arbitrary value for increasing entropy
|
||||
# ifndef SIVPERLIN_DEFAULT_Z
|
||||
# define SIVPERLIN_DEFAULT_Z (0.34567)
|
||||
# endif
|
||||
|
||||
|
||||
namespace siv
|
||||
{
|
||||
template <class Float>
|
||||
class BasicPerlinNoise
|
||||
{
|
||||
public:
|
||||
|
||||
static_assert(std::is_floating_point_v<Float>);
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Typedefs
|
||||
//
|
||||
|
||||
using state_type = std::array<std::uint8_t, 256>;
|
||||
|
||||
using value_type = Float;
|
||||
|
||||
using default_random_engine = std::mt19937;
|
||||
|
||||
using seed_type = typename default_random_engine::result_type;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
|
||||
SIVPERLIN_NODISCARD_CXX20
|
||||
constexpr BasicPerlinNoise() noexcept;
|
||||
|
||||
SIVPERLIN_NODISCARD_CXX20
|
||||
explicit BasicPerlinNoise(seed_type seed);
|
||||
|
||||
SIVPERLIN_CONCEPT_URBG
|
||||
SIVPERLIN_NODISCARD_CXX20
|
||||
explicit BasicPerlinNoise(URBG&& urbg);
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Reseed
|
||||
//
|
||||
|
||||
void reseed(seed_type seed);
|
||||
|
||||
SIVPERLIN_CONCEPT_URBG
|
||||
void reseed(URBG&& urbg);
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Serialization
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const state_type& serialize() const noexcept;
|
||||
|
||||
constexpr void deserialize(const state_type& state) noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Noise (The result is in the range [-1, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type noise1D(value_type x) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type noise2D(value_type x, value_type y) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type noise3D(value_type x, value_type y, value_type z) const noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Noise (The result is remapped to the range [0, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type noise1D_01(value_type x) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type noise2D_01(value_type x, value_type y) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type noise3D_01(value_type x, value_type y, value_type z) const noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Octave noise (The result can be out of the range [-1, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave1D(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave2D(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave3D(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Octave noise (The result is clamped to the range [-1, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave1D_11(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave2D_11(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave3D_11(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Octave noise (The result is clamped and remapped to the range [0, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave1D_01(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave2D_01(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type octave3D_01(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Octave noise (The result is normalized to the range [-1, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type normalizedOctave1D(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type normalizedOctave2D(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type normalizedOctave3D(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Octave noise (The result is normalized and remapped to the range [0, 1])
|
||||
//
|
||||
|
||||
[[nodiscard]]
|
||||
value_type normalizedOctave1D_01(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type normalizedOctave2D_01(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
value_type normalizedOctave3D_01(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
||||
|
||||
private:
|
||||
|
||||
state_type m_permutation;
|
||||
};
|
||||
|
||||
using PerlinNoise = BasicPerlinNoise<double>;
|
||||
|
||||
namespace perlin_detail
|
||||
{
|
||||
////////////////////////////////////////////////
|
||||
//
|
||||
// These functions are provided for consistency.
|
||||
// You may get different results from std::shuffle() with different standard library implementations.
|
||||
//
|
||||
SIVPERLIN_CONCEPT_URBG
|
||||
[[nodiscard]]
|
||||
inline std::uint64_t Random(const std::uint64_t max, URBG&& urbg)
|
||||
{
|
||||
return (urbg() % (max + 1));
|
||||
}
|
||||
|
||||
template <class RandomIt, class URBG>
|
||||
inline void Shuffle(RandomIt first, RandomIt last, URBG&& urbg)
|
||||
{
|
||||
if (first == last)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using difference_type = typename std::iterator_traits<RandomIt>::difference_type;
|
||||
|
||||
for (RandomIt it = first + 1; it < last; ++it)
|
||||
{
|
||||
const std::uint64_t n = static_cast<std::uint64_t>(it - first);
|
||||
std::iter_swap(it, first + static_cast<difference_type>(Random(n, std::forward<URBG>(urbg))));
|
||||
}
|
||||
}
|
||||
//
|
||||
////////////////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float Fade(const Float t) noexcept
|
||||
{
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float Lerp(const Float a, const Float b, const Float t) noexcept
|
||||
{
|
||||
return (a + (b - a) * t);
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float Grad(const std::uint8_t hash, const Float x, const Float y, const Float z) noexcept
|
||||
{
|
||||
const std::uint8_t h = hash & 15;
|
||||
const Float u = h < 8 ? x : y;
|
||||
const Float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float Remap_01(const Float x) noexcept
|
||||
{
|
||||
return (x * Float(0.5) + Float(0.5));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float Clamp_11(const Float x) noexcept
|
||||
{
|
||||
return std::clamp(x, Float(-1.0), Float(1.0));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float RemapClamp_01(const Float x) noexcept
|
||||
{
|
||||
if (x <= Float(-1.0))
|
||||
{
|
||||
return Float(0.0);
|
||||
}
|
||||
else if (Float(1.0) <= x)
|
||||
{
|
||||
return Float(1.0);
|
||||
}
|
||||
|
||||
return (x * Float(0.5) + Float(0.5));
|
||||
}
|
||||
|
||||
template <class Noise, class Float>
|
||||
[[nodiscard]]
|
||||
inline auto Octave1D(const Noise& noise, Float x, const std::int32_t octaves, const Float persistence) noexcept
|
||||
{
|
||||
using value_type = Float;
|
||||
value_type result = 0;
|
||||
value_type amplitude = 1;
|
||||
|
||||
for (std::int32_t i = 0; i < octaves; ++i)
|
||||
{
|
||||
result += (noise.noise1D(x) * amplitude);
|
||||
x *= 2;
|
||||
amplitude *= persistence;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Noise, class Float>
|
||||
[[nodiscard]]
|
||||
inline auto Octave2D(const Noise& noise, Float x, Float y, const std::int32_t octaves, const Float persistence) noexcept
|
||||
{
|
||||
using value_type = Float;
|
||||
value_type result = 0;
|
||||
value_type amplitude = 1;
|
||||
|
||||
for (std::int32_t i = 0; i < octaves; ++i)
|
||||
{
|
||||
result += (noise.noise2D(x, y) * amplitude);
|
||||
x *= 2;
|
||||
y *= 2;
|
||||
amplitude *= persistence;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Noise, class Float>
|
||||
[[nodiscard]]
|
||||
inline auto Octave3D(const Noise& noise, Float x, Float y, Float z, const std::int32_t octaves, const Float persistence) noexcept
|
||||
{
|
||||
using value_type = Float;
|
||||
value_type result = 0;
|
||||
value_type amplitude = 1;
|
||||
|
||||
for (std::int32_t i = 0; i < octaves; ++i)
|
||||
{
|
||||
result += (noise.noise3D(x, y, z) * amplitude);
|
||||
x *= 2;
|
||||
y *= 2;
|
||||
z *= 2;
|
||||
amplitude *= persistence;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
[[nodiscard]]
|
||||
inline constexpr Float MaxAmplitude(const std::int32_t octaves, const Float persistence) noexcept
|
||||
{
|
||||
using value_type = Float;
|
||||
value_type result = 0;
|
||||
value_type amplitude = 1;
|
||||
|
||||
for (std::int32_t i = 0; i < octaves; ++i)
|
||||
{
|
||||
result += amplitude;
|
||||
amplitude *= persistence;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline constexpr BasicPerlinNoise<Float>::BasicPerlinNoise() noexcept
|
||||
: m_permutation{ 151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 } {}
|
||||
|
||||
template <class Float>
|
||||
inline BasicPerlinNoise<Float>::BasicPerlinNoise(const seed_type seed)
|
||||
{
|
||||
reseed(seed);
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
SIVPERLIN_CONCEPT_URBG_
|
||||
inline BasicPerlinNoise<Float>::BasicPerlinNoise(URBG&& urbg)
|
||||
{
|
||||
reseed(std::forward<URBG>(urbg));
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline void BasicPerlinNoise<Float>::reseed(const seed_type seed)
|
||||
{
|
||||
reseed(default_random_engine{ seed });
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
SIVPERLIN_CONCEPT_URBG_
|
||||
inline void BasicPerlinNoise<Float>::reseed(URBG&& urbg)
|
||||
{
|
||||
std::iota(m_permutation.begin(), m_permutation.end(), uint8_t{ 0 });
|
||||
|
||||
perlin_detail::Shuffle(m_permutation.begin(), m_permutation.end(), std::forward<URBG>(urbg));
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline constexpr const typename BasicPerlinNoise<Float>::state_type& BasicPerlinNoise<Float>::serialize() const noexcept
|
||||
{
|
||||
return m_permutation;
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline constexpr void BasicPerlinNoise<Float>::deserialize(const state_type& state) noexcept
|
||||
{
|
||||
m_permutation = state;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise1D(const value_type x) const noexcept
|
||||
{
|
||||
return noise3D(x,
|
||||
static_cast<value_type>(SIVPERLIN_DEFAULT_Y),
|
||||
static_cast<value_type>(SIVPERLIN_DEFAULT_Z));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise2D(const value_type x, const value_type y) const noexcept
|
||||
{
|
||||
return noise3D(x,
|
||||
y,
|
||||
static_cast<value_type>(SIVPERLIN_DEFAULT_Z));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise3D(const value_type x, const value_type y, const value_type z) const noexcept
|
||||
{
|
||||
const value_type _x = std::floor(x);
|
||||
const value_type _y = std::floor(y);
|
||||
const value_type _z = std::floor(z);
|
||||
|
||||
const std::int32_t ix = static_cast<std::int32_t>(_x) & 255;
|
||||
const std::int32_t iy = static_cast<std::int32_t>(_y) & 255;
|
||||
const std::int32_t iz = static_cast<std::int32_t>(_z) & 255;
|
||||
|
||||
const value_type fx = (x - _x);
|
||||
const value_type fy = (y - _y);
|
||||
const value_type fz = (z - _z);
|
||||
|
||||
const value_type u = perlin_detail::Fade(fx);
|
||||
const value_type v = perlin_detail::Fade(fy);
|
||||
const value_type w = perlin_detail::Fade(fz);
|
||||
|
||||
const std::uint8_t A = (m_permutation[ix & 255] + iy) & 255;
|
||||
const std::uint8_t B = (m_permutation[(ix + 1) & 255] + iy) & 255;
|
||||
|
||||
const std::uint8_t AA = (m_permutation[A] + iz) & 255;
|
||||
const std::uint8_t AB = (m_permutation[(A + 1) & 255] + iz) & 255;
|
||||
|
||||
const std::uint8_t BA = (m_permutation[B] + iz) & 255;
|
||||
const std::uint8_t BB = (m_permutation[(B + 1) & 255] + iz) & 255;
|
||||
|
||||
const value_type p0 = perlin_detail::Grad(m_permutation[AA], fx, fy, fz);
|
||||
const value_type p1 = perlin_detail::Grad(m_permutation[BA], fx - 1, fy, fz);
|
||||
const value_type p2 = perlin_detail::Grad(m_permutation[AB], fx, fy - 1, fz);
|
||||
const value_type p3 = perlin_detail::Grad(m_permutation[BB], fx - 1, fy - 1, fz);
|
||||
const value_type p4 = perlin_detail::Grad(m_permutation[(AA + 1) & 255], fx, fy, fz - 1);
|
||||
const value_type p5 = perlin_detail::Grad(m_permutation[(BA + 1) & 255], fx - 1, fy, fz - 1);
|
||||
const value_type p6 = perlin_detail::Grad(m_permutation[(AB + 1) & 255], fx, fy - 1, fz - 1);
|
||||
const value_type p7 = perlin_detail::Grad(m_permutation[(BB + 1) & 255], fx - 1, fy - 1, fz - 1);
|
||||
|
||||
const value_type q0 = perlin_detail::Lerp(p0, p1, u);
|
||||
const value_type q1 = perlin_detail::Lerp(p2, p3, u);
|
||||
const value_type q2 = perlin_detail::Lerp(p4, p5, u);
|
||||
const value_type q3 = perlin_detail::Lerp(p6, p7, u);
|
||||
|
||||
const value_type r0 = perlin_detail::Lerp(q0, q1, v);
|
||||
const value_type r1 = perlin_detail::Lerp(q2, q3, v);
|
||||
|
||||
return perlin_detail::Lerp(r0, r1, w);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise1D_01(const value_type x) const noexcept
|
||||
{
|
||||
return perlin_detail::Remap_01(noise1D(x));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise2D_01(const value_type x, const value_type y) const noexcept
|
||||
{
|
||||
return perlin_detail::Remap_01(noise2D(x, y));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise3D_01(const value_type x, const value_type y, const value_type z) const noexcept
|
||||
{
|
||||
return perlin_detail::Remap_01(noise3D(x, y, z));
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Octave1D(*this, x, octaves, persistence);
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Octave2D(*this, x, y, octaves, persistence);
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Octave3D(*this, x, y, z, octaves, persistence);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D_11(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Clamp_11(octave1D(x, octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D_11(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Clamp_11(octave2D(x, y, octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D_11(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Clamp_11(octave3D(x, y, z, octaves, persistence));
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D_01(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::RemapClamp_01(octave1D(x, octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D_01(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::RemapClamp_01(octave2D(x, y, octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D_01(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::RemapClamp_01(octave3D(x, y, z, octaves, persistence));
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave1D(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return (octave1D(x, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave2D(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return (octave2D(x, y, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave3D(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return (octave3D(x, y, z, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave1D_01(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Remap_01(normalizedOctave1D(x, octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave2D_01(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Remap_01(normalizedOctave2D(x, y, octaves, persistence));
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave3D_01(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
||||
{
|
||||
return perlin_detail::Remap_01(normalizedOctave3D(x, y, z, octaves, persistence));
|
||||
}
|
||||
}
|
||||
|
||||
# undef SIVPERLIN_NODISCARD_CXX20
|
||||
# undef SIVPERLIN_CONCEPT_URBG
|
||||
# undef SIVPERLIN_CONCEPT_URBG_
|
||||
157
gloom/src/gloom/Shader.cpp
Normal file
157
gloom/src/gloom/Shader.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
|
||||
|
||||
Shader::Shader() {
|
||||
|
||||
}
|
||||
|
||||
void Shader::setShader(const char* vertexPath, const char* fragmentPath) {
|
||||
std::string vertexCode, fragmentCode;
|
||||
std::ifstream vShaderFile, fShaderFile;
|
||||
|
||||
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
try {
|
||||
//open files
|
||||
vShaderFile.open(vertexPath);
|
||||
fShaderFile.open(fragmentPath);
|
||||
std::stringstream vShaderStream, fShaderStream;
|
||||
|
||||
vShaderStream << vShaderFile.rdbuf();
|
||||
fShaderStream << fShaderFile.rdbuf();
|
||||
|
||||
vShaderFile.close();
|
||||
fShaderFile.close();
|
||||
|
||||
vertexCode = vShaderStream.str();
|
||||
fragmentCode = fShaderStream.str();
|
||||
}
|
||||
catch (std::ifstream::failure e) {
|
||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
|
||||
}
|
||||
|
||||
const char* vShaderCode = vertexCode.c_str();
|
||||
const char* fShaderCode = fragmentCode.c_str();
|
||||
|
||||
|
||||
//next, compile shaders
|
||||
unsigned int vertex, fragment;
|
||||
int success;
|
||||
char infoLog[512];
|
||||
//vertex
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
//vertex errors
|
||||
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
//fragment
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
//fragment compile errors
|
||||
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
//setup shader program
|
||||
ID = glCreateProgram();
|
||||
glAttachShader(ID, vertex);
|
||||
glAttachShader(ID, fragment);
|
||||
glLinkProgram(ID);
|
||||
//shader program linking errors
|
||||
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//shadow mapping
|
||||
void Shader::setupShadowMap() {
|
||||
// Create framebuffer to attach depth texture
|
||||
glGenFramebuffers(1, &depthMapFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
|
||||
// Create depth texture
|
||||
glGenTextures(1, &depthMap);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, shadowWidth, shadowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthMap, 0);
|
||||
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
||||
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
std::cout << "Error getting framebuffer" << std::endl;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
}
|
||||
void Shader::renderShadowMap(glm::mat4 lightSpaceMatrix) {
|
||||
glViewport(0, 0, shadowWidth, shadowHeight);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Render the scene
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//enable this shader
|
||||
void Shader::use() {
|
||||
glUseProgram(ID);
|
||||
}
|
||||
|
||||
//uniform set functions
|
||||
void Shader::setBool(const std::string& name, bool value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
||||
}
|
||||
void Shader::setInt(const std::string& name, int value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
void Shader::setFloat(const std::string& name, float value) const
|
||||
{
|
||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
void Shader::setMat4(const std::string& name, glm::mat4 value) const
|
||||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(value));
|
||||
|
||||
}
|
||||
void Shader::setVec3(const std::string& name, glm::vec3 value) const {
|
||||
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, glm::value_ptr(value));
|
||||
}
|
||||
41
gloom/src/gloom/Shader.h
Normal file
41
gloom/src/gloom/Shader.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_SHADER_H
|
||||
#define GLOOM_SHADER_H
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
unsigned int ID;
|
||||
Shader();
|
||||
|
||||
void use();
|
||||
void setShader(const char* vertexPath, const char* fragmentPath);
|
||||
|
||||
void setBool(const std::string& name, bool value) const;
|
||||
void setInt(const std::string& name, int value) const;
|
||||
void setFloat(const std::string& name, float value) const;
|
||||
void setMat4(const std::string& name, glm::mat4 value) const;
|
||||
void setVec3(const std::string& name, glm::vec3 value) const;
|
||||
|
||||
|
||||
//shadow map
|
||||
unsigned int depthMapFBO, depthMap;
|
||||
int shadowWidth = 4096, shadowHeight = 4096; // Adjust the size as needed
|
||||
void setupShadowMap();
|
||||
void renderShadowMap(glm::mat4 lightSpaceMatrix);
|
||||
};
|
||||
#endif //GLOOM_SHADER_H
|
||||
35
gloom/src/gloom/Singleton.h
Normal file
35
gloom/src/gloom/Singleton.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Created by Bram on 25/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_SINGLETON_H
|
||||
#define GLOOM_SINGLETON_H
|
||||
|
||||
#ifndef SINGLETON_H
|
||||
#define SINGLETON_H
|
||||
|
||||
template<typename T>
|
||||
class Singleton {
|
||||
public:
|
||||
static T &GetInstance() {
|
||||
static T instance{};
|
||||
return instance;
|
||||
}
|
||||
|
||||
virtual ~Singleton() = default;
|
||||
|
||||
Singleton(Singleton &&other) = delete;
|
||||
|
||||
Singleton(const Singleton &other) = delete;
|
||||
|
||||
Singleton &operator=(Singleton &&other) = delete;
|
||||
|
||||
Singleton &operator=(const Singleton &other) = delete;
|
||||
|
||||
protected:
|
||||
Singleton() = default;
|
||||
};
|
||||
|
||||
#endif // SINGLETON_H
|
||||
|
||||
#endif //GLOOM_SINGLETON_H
|
||||
52
gloom/src/gloom/Texture.cpp
Normal file
52
gloom/src/gloom/Texture.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#include "Texture.h"
|
||||
#include "glad/glad.h"
|
||||
#include <iostream>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
|
||||
Texture::Texture(const std::string &filename) {
|
||||
// Load the image
|
||||
int width, height, channels;
|
||||
unsigned char* image = stbi_load(filename.c_str(), &width, &height, &channels, 0);
|
||||
|
||||
// Generate a texture
|
||||
glGenTextures(1, &m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
|
||||
// Set the texture wrapping/filtering options
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
//mipmap resizing
|
||||
|
||||
|
||||
|
||||
// Load and generate the texture
|
||||
if (image) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
} else {
|
||||
std::cerr << "Failed to load texture" << std::endl;
|
||||
}
|
||||
|
||||
// Free the image
|
||||
stbi_image_free(image);
|
||||
|
||||
}
|
||||
|
||||
void Texture::bind(unsigned int slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
}
|
||||
|
||||
void Texture::unbind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
24
gloom/src/gloom/Texture.h
Normal file
24
gloom/src/gloom/Texture.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Bram on 23/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_TEXTURE_H
|
||||
#define GLOOM_TEXTURE_H
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
Texture(const std::string& filename);
|
||||
|
||||
void bind(unsigned int slot = 0) const;
|
||||
void unbind() const;
|
||||
|
||||
unsigned int getTexture() const { return m_texture; }
|
||||
private:
|
||||
unsigned int m_texture{ 0 };
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_TEXTURE_H
|
||||
12
gloom/src/gloom/TextureManager.cpp
Normal file
12
gloom/src/gloom/TextureManager.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// Created by Bram on 25/08/2024.
|
||||
//
|
||||
|
||||
#include "TextureManager.h"
|
||||
|
||||
Texture * TextureManager::getTexture(const std::string &path) {
|
||||
if (m_textures.find(path) == m_textures.end()) {
|
||||
m_textures[path] = new Texture(path);
|
||||
}
|
||||
return m_textures[path];
|
||||
}
|
||||
27
gloom/src/gloom/TextureManager.h
Normal file
27
gloom/src/gloom/TextureManager.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by Bram on 25/08/2024.
|
||||
//
|
||||
|
||||
#ifndef GLOOM_TEXTUREMANAGER_H
|
||||
#define GLOOM_TEXTUREMANAGER_H
|
||||
|
||||
|
||||
#include <unordered_map>
|
||||
#include "Singleton.h"
|
||||
#include "Texture.h"
|
||||
#include <string>
|
||||
|
||||
class TextureManager: public Singleton<TextureManager>{
|
||||
public:
|
||||
TextureManager() = default;
|
||||
~TextureManager() override = default;
|
||||
|
||||
Texture * getTexture(const std::string& path);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, Texture*> m_textures;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //GLOOM_TEXTUREMANAGER_H
|
||||
@@ -1,200 +0,0 @@
|
||||
#ifndef CAMERA_HPP
|
||||
#define CAMERA_HPP
|
||||
#pragma once
|
||||
|
||||
// System headers
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
|
||||
namespace Gloom
|
||||
{
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 2.0f),
|
||||
GLfloat movementSpeed = 5.0f,
|
||||
GLfloat mouseSensitivity = 0.005f)
|
||||
{
|
||||
cPosition = position;
|
||||
cMovementSpeed = movementSpeed;
|
||||
cMouseSensitivity = mouseSensitivity;
|
||||
|
||||
// Set up the initial view matrix
|
||||
updateViewMatrix();
|
||||
}
|
||||
|
||||
// Public member functions
|
||||
|
||||
/* Getter for the view matrix */
|
||||
glm::mat4 getViewMatrix() { return matView; }
|
||||
|
||||
|
||||
/* Handle keyboard inputs from a callback mechanism */
|
||||
void handleKeyboardInputs(int key, int action)
|
||||
{
|
||||
// Keep track of pressed/released buttons
|
||||
if (key >= 0 && key < 512)
|
||||
{
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
keysInUse[key] = true;
|
||||
}
|
||||
else if (action == GLFW_RELEASE)
|
||||
{
|
||||
keysInUse[key] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handle mouse button inputs from a callback mechanism */
|
||||
void handleMouseButtonInputs(int button, int action)
|
||||
{
|
||||
// Ensure that the camera only rotates when the left mouse button is
|
||||
// pressed
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
|
||||
{
|
||||
isMousePressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isMousePressed = false;
|
||||
resetMouse = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handle cursor position from a callback mechanism */
|
||||
void handleCursorPosInput(double xpos, double ypos)
|
||||
{
|
||||
// Do nothing if the left mouse button is not pressed
|
||||
if (isMousePressed == false)
|
||||
return;
|
||||
|
||||
// There should be no movement when the mouse button is released
|
||||
if (resetMouse)
|
||||
{
|
||||
lastXPos = xpos;
|
||||
lastYPos = ypos;
|
||||
resetMouse = false;
|
||||
}
|
||||
|
||||
// Keep track of pitch and yaw for the current frame
|
||||
fYaw = xpos - lastXPos;
|
||||
fPitch = ypos - lastYPos;
|
||||
|
||||
// Update last known cursor position
|
||||
lastXPos = xpos;
|
||||
lastYPos = ypos;
|
||||
}
|
||||
|
||||
|
||||
/* Update the camera position and view matrix
|
||||
`deltaTime` is the time between the current and last frame */
|
||||
void updateCamera(GLfloat deltaTime)
|
||||
{
|
||||
// Extract movement information from the view matrix
|
||||
glm::vec3 dirX(matView[0][0], matView[1][0], matView[2][0]);
|
||||
glm::vec3 dirY(matView[0][1], matView[1][1], matView[2][1]);
|
||||
glm::vec3 dirZ(matView[0][2], matView[1][2], matView[2][2]);
|
||||
|
||||
// Alter position in the appropriate direction
|
||||
glm::vec3 fMovement(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (keysInUse[GLFW_KEY_W]) // forward
|
||||
fMovement -= dirZ;
|
||||
|
||||
if (keysInUse[GLFW_KEY_S]) // backward
|
||||
fMovement += dirZ;
|
||||
|
||||
if (keysInUse[GLFW_KEY_A]) // left
|
||||
fMovement -= dirX;
|
||||
|
||||
if (keysInUse[GLFW_KEY_D]) // right
|
||||
fMovement += dirX;
|
||||
|
||||
if (keysInUse[GLFW_KEY_E]) // vertical up
|
||||
fMovement += dirY;
|
||||
|
||||
if (keysInUse[GLFW_KEY_Q]) // vertical down
|
||||
fMovement -= dirY;
|
||||
|
||||
// Trick to balance PC speed with movement
|
||||
GLfloat velocity = cMovementSpeed * deltaTime;
|
||||
|
||||
// Update camera position using the appropriate velocity
|
||||
cPosition += fMovement * velocity;
|
||||
|
||||
// Update the view matrix based on the new information
|
||||
updateViewMatrix();
|
||||
}
|
||||
|
||||
private:
|
||||
// Disable copying and assignment
|
||||
Camera(Camera const &) = delete;
|
||||
Camera & operator =(Camera const &) = delete;
|
||||
|
||||
// Private member function
|
||||
|
||||
/* Update the view matrix based on the current information */
|
||||
void updateViewMatrix()
|
||||
{
|
||||
// Adjust cursor movement using the specified sensitivity
|
||||
fPitch *= cMouseSensitivity;
|
||||
fYaw *= cMouseSensitivity;
|
||||
|
||||
// Create quaternions given the current pitch and yaw
|
||||
glm::quat qPitch = glm::quat(glm::vec3(fPitch, 0.0f, 0.0f));
|
||||
glm::quat qYaw = glm::quat(glm::vec3(0.0f, fYaw, 0.0f));
|
||||
|
||||
// Reset pitch and yaw values for the current rotation
|
||||
fPitch = 0.0f;
|
||||
fYaw = 0.0f;
|
||||
|
||||
// Update camera quaternion and normalise
|
||||
cQuaternion = qYaw * qPitch * cQuaternion;
|
||||
cQuaternion = glm::normalize(cQuaternion);
|
||||
|
||||
// Build rotation matrix using the camera quaternion
|
||||
glm::mat4 matRotation = glm::mat4_cast(cQuaternion);
|
||||
|
||||
// Build translation matrix
|
||||
glm::mat4 matTranslate = glm::translate(glm::mat4(1.0f), -cPosition);
|
||||
|
||||
// Update view matrix
|
||||
matView = matRotation * matTranslate;
|
||||
}
|
||||
|
||||
// Private member variables
|
||||
|
||||
// Camera quaternion and frame pitch and yaw
|
||||
glm::quat cQuaternion;
|
||||
GLfloat fPitch = 0.0f;
|
||||
GLfloat fYaw = 0.0f;
|
||||
|
||||
// Camera position
|
||||
glm::vec3 cPosition;
|
||||
|
||||
// Variables used for bookkeeping
|
||||
GLboolean resetMouse = true;
|
||||
GLboolean isMousePressed = false;
|
||||
GLboolean keysInUse[512];
|
||||
|
||||
// Last cursor position
|
||||
GLfloat lastXPos = 0.0f;
|
||||
GLfloat lastYPos = 0.0f;
|
||||
|
||||
// Camera settings
|
||||
GLfloat cMovementSpeed;
|
||||
GLfloat cMouseSensitivity;
|
||||
|
||||
// View matrix
|
||||
glm::mat4 matView;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
45
gloom/src/gloom/config.hpp
Normal file
45
gloom/src/gloom/config.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Preprocessor directives
|
||||
#ifndef GLOOM_HPP
|
||||
#define GLOOM_HPP
|
||||
#pragma once
|
||||
|
||||
// System Headers
|
||||
#include <glad/glad.h>
|
||||
|
||||
// Standard headers
|
||||
#include <string>
|
||||
#include "PerlinNoise.hpp"
|
||||
|
||||
// Constants
|
||||
const int windowWidth = 1200;
|
||||
const int windowHeight = 900;
|
||||
const std::string windowTitle = "OpenGL";
|
||||
const GLint windowResizable = GL_FALSE;
|
||||
const int windowSamples = 4;
|
||||
|
||||
const int MAX_FPS = 60;
|
||||
|
||||
static bool renderWireframe = false;
|
||||
|
||||
static const int CHUNK_SIZE = 16;
|
||||
static const int CHUNK_HEIGHT = 256;
|
||||
|
||||
static const int TEXTURE_WIDTH = 16;
|
||||
static const int TEXTURE_HEIGHT = 16;
|
||||
|
||||
static const int ATLAS_WIDTH = 128;
|
||||
static const int ATLAS_HEIGHT = 128;
|
||||
|
||||
static const double CELL_WIDTH = 1.0 / ATLAS_WIDTH * TEXTURE_WIDTH;
|
||||
static const double CELL_HEIGHT = 1.0 / ATLAS_HEIGHT * TEXTURE_HEIGHT;
|
||||
|
||||
static const int RENDER_DISTANCE = 10;
|
||||
|
||||
static const int WORLD_WIDTH = 128;
|
||||
static const int WORLD_HEIGHT = 128;
|
||||
|
||||
static int SEED = 1234u;
|
||||
|
||||
static siv::PerlinNoise perlin{ static_cast<unsigned int>(SEED) };
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
// Preprocessor directives
|
||||
#ifndef GLOOM_HPP
|
||||
#define GLOOM_HPP
|
||||
#pragma once
|
||||
|
||||
// System Headers
|
||||
#include <glad/glad.h>
|
||||
|
||||
// Standard headers
|
||||
#include <string>
|
||||
|
||||
// Constants
|
||||
const int windowWidth = 1024;
|
||||
const int windowHeight = 768;
|
||||
const std::string windowTitle = "OpenGL";
|
||||
const GLint windowResizable = GL_FALSE;
|
||||
const int windowSamples = 4;
|
||||
|
||||
#endif
|
||||
175
gloom/src/gloom/old/Cube.cpp
Normal file
175
gloom/src/gloom/old/Cube.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
////
|
||||
//// Created by Bram on 23/08/2024.
|
||||
////
|
||||
//
|
||||
//#include "Cube.h"
|
||||
//
|
||||
//glm::vec3 unitVertices[8] = {
|
||||
// glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f),
|
||||
// glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f),
|
||||
// glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(1.0f, 0.0f, 1.0f),
|
||||
// glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 1.0f, 1.0f)
|
||||
//};
|
||||
//
|
||||
//unsigned int faceVertices[6][6] = {
|
||||
// // TOP (3, 2, 6, 3, 6, 7)
|
||||
// {3, 2, 6, 3, 6, 7},
|
||||
// // BOTTOM (1, 0, 4, 1, 4, 5)
|
||||
// {1, 0, 4, 1, 4, 5},
|
||||
// // LEFT (0, 3, 7, 0, 7, 4)
|
||||
// {0, 3, 7, 0, 7, 4},
|
||||
// // RIGHT (2, 1, 5, 2, 5, 6)
|
||||
// {2, 1, 5, 2, 5, 6},
|
||||
// // FRONT (0, 1, 2, 0, 2, 3)
|
||||
// {0, 1, 2, 0, 2, 3},
|
||||
// // BACK (5, 4, 7, 5, 7, 6)
|
||||
// {5, 4, 7, 5, 7, 6}
|
||||
//};
|
||||
//
|
||||
//
|
||||
//void Cube::Draw(GLuint shaderProgram) {
|
||||
// // Use the shader program
|
||||
// glUseProgram(shaderProgram);
|
||||
//
|
||||
// // Transform the cube
|
||||
// glm::mat4 model = glm::translate(glm::mat4(1.0f), position);
|
||||
// GLuint modelLoc = glGetUniformLocation(shaderProgram, "model");
|
||||
// glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
|
||||
//
|
||||
// if(renderWireframe) {
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
// } else {
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
// }
|
||||
//
|
||||
// // Draw the cube
|
||||
// texture.bind(0);
|
||||
// glBindVertexArray(VAO);
|
||||
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
// glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
|
||||
// glBindVertexArray(0);
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void Cube::setupCube() {
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// std::array<CubeVertex, 24> cubeVertices = {
|
||||
// // Front face (z = 1.0f)
|
||||
// CubeVertex(glm::vec3(-1.0f, -1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f)), // Bottom-left
|
||||
// CubeVertex(glm::vec3( 1.0f, -1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)), // Bottom-right
|
||||
// CubeVertex(glm::vec3( 1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 1.0f)), // Top-right
|
||||
// CubeVertex(glm::vec3(-1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)), // Top-left
|
||||
//
|
||||
// // Back face (z = -1.0f)
|
||||
// CubeVertex(glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec2(0.0f, 0.0f)), // Bottom-left
|
||||
// CubeVertex(glm::vec3( 1.0f, -1.0f, -1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec2(1.0f, 0.0f)), // Bottom-right
|
||||
// CubeVertex(glm::vec3( 1.0f, 1.0f, -1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)), // Top-right
|
||||
// CubeVertex(glm::vec3(-1.0f, 1.0f, -1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec2(0.0f, 1.0f)), // Top-left
|
||||
//
|
||||
// // Left face (x = -1.0f)
|
||||
// CubeVertex(glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f)), // Bottom-left
|
||||
// CubeVertex(glm::vec3(-1.0f, -1.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 0.0f)), // Bottom-right
|
||||
// CubeVertex(glm::vec3(-1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(1.0f, 1.0f)), // Top-right
|
||||
// CubeVertex(glm::vec3(-1.0f, 1.0f, -1.0f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec2(0.0f, 1.0f)), // Top-left
|
||||
//
|
||||
// // Right face (x = 1.0f)
|
||||
// CubeVertex(glm::vec3( 1.0f, -1.0f, -1.0f), glm::vec3(1.0f, 0.0f, 1.0f), glm::vec2(0.0f, 0.0f)), // Bottom-left
|
||||
// CubeVertex(glm::vec3( 1.0f, -1.0f, 1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec2(1.0f, 0.0f)), // Bottom-right
|
||||
// CubeVertex(glm::vec3( 1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)), // Top-right
|
||||
// CubeVertex(glm::vec3( 1.0f, 1.0f, -1.0f), glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f)), // Top-left
|
||||
//
|
||||
// // Bottom face (y = -1.0f)
|
||||
// CubeVertex(glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f)), // Bottom-left
|
||||
// CubeVertex(glm::vec3( 1.0f, -1.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 0.0f)), // Bottom-right
|
||||
// CubeVertex(glm::vec3( 1.0f, -1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(1.0f, 1.0f)), // Top-right
|
||||
// CubeVertex(glm::vec3(-1.0f, -1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec2(0.0f, 1.0f)), // Top-left
|
||||
//
|
||||
// // Top face (y = 1.0f)
|
||||
// CubeVertex(glm::vec3(-1.0f, 1.0f, -1.0f), glm::vec3(1.0f, 0.0f, 1.0f), glm::vec2(0.0f, 0.0f)), // Bottom-left
|
||||
// CubeVertex(glm::vec3( 1.0f, 1.0f, -1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec2(1.0f, 0.0f)), // Bottom-right
|
||||
// CubeVertex(glm::vec3( 1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)), // Top-right
|
||||
// CubeVertex(glm::vec3(-1.0f, 1.0f, 1.0f), glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f)) // Top-left
|
||||
// };
|
||||
//
|
||||
// glGenVertexArrays(1, &VAO);
|
||||
// glGenBuffers(1, &VBO);
|
||||
// glGenBuffers(1, &EBO);
|
||||
//
|
||||
// glBindVertexArray(VAO);
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
// glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices.data(), GL_STATIC_DRAW);
|
||||
//
|
||||
//
|
||||
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices.data(), GL_STATIC_DRAW);
|
||||
//
|
||||
//
|
||||
// // Position attribute
|
||||
// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(CubeVertex), (void *) offsetof(CubeVertex, position));
|
||||
// glEnableVertexAttribArray(0);
|
||||
//
|
||||
// // Color attribute
|
||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(CubeVertex), (void *) offsetof(CubeVertex, color));
|
||||
// glEnableVertexAttribArray(1);
|
||||
//
|
||||
// // Texture Coords
|
||||
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(CubeVertex), (void *) offsetof(CubeVertex, texCoords));
|
||||
// glEnableVertexAttribArray(2);
|
||||
//
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// glBindVertexArray(0);
|
||||
//}
|
||||
//
|
||||
//Cube::Cube(const glm::vec3 &position, BlockType blockType): position(position), texture("assets/dirt.png"), type(blockType) {
|
||||
// setupCube();
|
||||
//}
|
||||
//
|
||||
//void Cube::LoadFace(Face face, std::vector<CubeVertex> &vertices) {
|
||||
//
|
||||
// glm::vec3 normal;
|
||||
// switch (face) {
|
||||
// case Face::TOP:
|
||||
// normal = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
// break;
|
||||
// case Face::BOTTOM:
|
||||
// normal = glm::vec3(0.0f, -1.0f, 0.0f);
|
||||
// break;
|
||||
// case Face::LEFT:
|
||||
// normal = glm::vec3(-1.0f, 0.0f, 0.0f);
|
||||
// break;
|
||||
// case Face::RIGHT:
|
||||
// normal = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||
// break;
|
||||
// case Face::FRONT:
|
||||
// normal = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
// break;
|
||||
// case Face::BACK:
|
||||
// normal = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
// glm::vec2 texCoords = glm::vec2(0.0f, 0.0f);
|
||||
//
|
||||
// for (int i = 0; i < 6; i++) {
|
||||
// CubeVertex vertex = {
|
||||
// unitVertices[faceVertices[face][i]],
|
||||
// color,
|
||||
// texCoords
|
||||
// };
|
||||
// vertices.push_back(vertex);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void Cube::LoadAllFaces(std::vector<CubeVertex> &vertices) {
|
||||
// LoadFace(Face::TOP, vertices);
|
||||
// LoadFace(Face::BOTTOM, vertices);
|
||||
// LoadFace(Face::LEFT, vertices);
|
||||
// LoadFace(Face::RIGHT, vertices);
|
||||
// LoadFace(Face::FRONT, vertices);
|
||||
// LoadFace(Face::BACK, vertices);
|
||||
//}
|
||||
89
gloom/src/gloom/old/Cube.h
Normal file
89
gloom/src/gloom/old/Cube.h
Normal file
@@ -0,0 +1,89 @@
|
||||
////
|
||||
//// Created by Bram on 23/08/2024.
|
||||
////
|
||||
//
|
||||
//#ifndef GLOOM_CUBE_H
|
||||
//#define GLOOM_CUBE_H
|
||||
//
|
||||
//
|
||||
//#include <glm/glm.hpp>
|
||||
//#include <glm/gtc/matrix_transform.hpp>
|
||||
//#include <glm/gtc/type_ptr.hpp>
|
||||
//#include <vector>
|
||||
//#include <iostream>
|
||||
//#include <array>
|
||||
//#include "glad/glad.h"
|
||||
//#include "gloom/Texture.h"
|
||||
//#include "gloom/config.hpp"
|
||||
//#include "Chunk.h"
|
||||
//#include "gloom/Mesh.h"
|
||||
//
|
||||
//struct CubeVertex {
|
||||
// CubeVertex(glm::vec3 pos, glm::vec3 color, glm::vec2 texCoords) : position(pos), color(color),
|
||||
// texCoords(texCoords) {};
|
||||
//
|
||||
// glm::vec3 position;
|
||||
// glm::vec3 color;
|
||||
// glm::vec2 texCoords;
|
||||
//};
|
||||
//
|
||||
//struct CubeFace {
|
||||
//};
|
||||
//
|
||||
//static std::array<unsigned int, 36> cubeIndices = {
|
||||
// // Front face
|
||||
// 0, 1, 2, // First triangle (0, 1, 2)
|
||||
// 0, 2, 3, // Second triangle (0, 2, 3)
|
||||
//
|
||||
// // Back face
|
||||
// 4, 5, 6, // First triangle (4, 5, 6)
|
||||
// 4, 6, 7, // Second triangle (4, 6, 7)
|
||||
//
|
||||
// // Left face
|
||||
// 8, 9, 10, // First triangle (8, 9, 10)
|
||||
// 8, 10, 11,// Second triangle (8, 10, 11)
|
||||
//
|
||||
// // Right face
|
||||
// 12, 13, 14,// First triangle (12, 13, 14)
|
||||
// 12, 14, 15,// Second triangle (12, 14, 15)
|
||||
//
|
||||
// // Bottom face
|
||||
// 16, 17, 18,// First triangle (16, 17, 18)
|
||||
// 16, 18, 19,// Second triangle (16, 18, 19)
|
||||
//
|
||||
// // Top face
|
||||
// 20, 21, 22,// First triangle (20, 21, 22)
|
||||
// 20, 22, 23 // Second triangle (20, 22, 23)
|
||||
//};
|
||||
//
|
||||
//enum Face {
|
||||
// TOP = 0x01, // 0000 0001
|
||||
// BOTTOM = 0x02, // 0000 0010
|
||||
// LEFT = 0x04, // 0000 0100
|
||||
// RIGHT = 0x08, // 0000 1000
|
||||
// FRONT = 0x10, // 0001 0000
|
||||
// BACK = 0x20 // 0010 0000
|
||||
//};
|
||||
//
|
||||
//
|
||||
//class Cube {
|
||||
//public:
|
||||
// explicit Cube(const glm::vec3 &position, BlockType blockType);
|
||||
//
|
||||
// void Draw(GLuint shaderProgram);
|
||||
//
|
||||
// void LoadFace(Face face, std::vector<CubeVertex>& vertices);
|
||||
// void LoadAllFaces(std::vector<CubeVertex>& vertices);
|
||||
//
|
||||
// Mesh mesh;
|
||||
//private:
|
||||
// GLuint VAO{}, VBO{}, EBO{};
|
||||
// glm::vec3 position;
|
||||
//
|
||||
// Texture texture;
|
||||
// BlockType type{ BlockType::AIR };
|
||||
// void setupCube();
|
||||
//};
|
||||
//
|
||||
//
|
||||
//#endif //GLOOM_CUBE_H
|
||||
@@ -1,146 +0,0 @@
|
||||
#ifndef SHADER_HPP
|
||||
#define SHADER_HPP
|
||||
#pragma once
|
||||
|
||||
// System headers
|
||||
#include <glad/glad.h>
|
||||
|
||||
// Standard headers
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Gloom
|
||||
{
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader() { mProgram = glCreateProgram(); }
|
||||
|
||||
// Public member functions
|
||||
void activate() { glUseProgram(mProgram); }
|
||||
void deactivate() { glUseProgram(0); }
|
||||
GLuint get() { return mProgram; }
|
||||
void destroy() { glDeleteProgram(mProgram); }
|
||||
|
||||
/* Attach a shader to the current shader program */
|
||||
void attach(std::string const &filename)
|
||||
{
|
||||
// Load GLSL Shader from source
|
||||
std::ifstream fd(filename.c_str());
|
||||
if (fd.fail())
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Something went wrong when attaching the Shader file at \"%s\".\n"
|
||||
"The file may not exist or is currently inaccessible.\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
}
|
||||
auto src = std::string(std::istreambuf_iterator<char>(fd),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
|
||||
// Create shader object
|
||||
const char * source = src.c_str();
|
||||
auto shader = create(filename);
|
||||
glShaderSource(shader, 1, &source, nullptr);
|
||||
glCompileShader(shader);
|
||||
|
||||
// Display errors
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &mStatus);
|
||||
if (!mStatus)
|
||||
{
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &mLength);
|
||||
std::unique_ptr<char[]> buffer(new char[mLength]);
|
||||
glGetShaderInfoLog(shader, mLength, nullptr, buffer.get());
|
||||
fprintf(stderr, "%s\n%s", filename.c_str(), buffer.get());
|
||||
}
|
||||
|
||||
assert(mStatus);
|
||||
|
||||
// Attach shader and free allocated memory
|
||||
glAttachShader(mProgram, shader);
|
||||
glDeleteShader(shader);
|
||||
}
|
||||
|
||||
|
||||
/* Links all attached shaders together into a shader program */
|
||||
void link()
|
||||
{
|
||||
// Link all attached shaders
|
||||
glLinkProgram(mProgram);
|
||||
|
||||
// Display errors
|
||||
glGetProgramiv(mProgram, GL_LINK_STATUS, &mStatus);
|
||||
if (!mStatus)
|
||||
{
|
||||
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &mLength);
|
||||
std::unique_ptr<char[]> buffer(new char[mLength]);
|
||||
glGetProgramInfoLog(mProgram, mLength, nullptr, buffer.get());
|
||||
fprintf(stderr, "%s\n", buffer.get());
|
||||
}
|
||||
|
||||
assert(mStatus);
|
||||
}
|
||||
|
||||
|
||||
/* Convenience function that attaches and links a vertex and a
|
||||
fragment shader in a shader program */
|
||||
void makeBasicShader(std::string const &vertexFilename,
|
||||
std::string const &fragmentFilename)
|
||||
{
|
||||
attach(vertexFilename);
|
||||
attach(fragmentFilename);
|
||||
link();
|
||||
}
|
||||
|
||||
|
||||
/* Used for debugging shader programs (expensive to run) */
|
||||
bool isValid()
|
||||
{
|
||||
// Validate linked shader program
|
||||
glValidateProgram(mProgram);
|
||||
|
||||
// Display errors
|
||||
glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &mStatus);
|
||||
if (!mStatus)
|
||||
{
|
||||
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &mLength);
|
||||
std::unique_ptr<char[]> buffer(new char[mLength]);
|
||||
glGetProgramInfoLog(mProgram, mLength, nullptr, buffer.get());
|
||||
fprintf(stderr, "%s\n", buffer.get());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function for creating shaders */
|
||||
GLuint create(std::string const &filename)
|
||||
{
|
||||
// Extract file extension and create the correct shader type
|
||||
auto idx = filename.rfind(".");
|
||||
auto ext = filename.substr(idx + 1);
|
||||
if (ext == "comp") return glCreateShader(GL_COMPUTE_SHADER);
|
||||
else if (ext == "frag") return glCreateShader(GL_FRAGMENT_SHADER);
|
||||
else if (ext == "geom") return glCreateShader(GL_GEOMETRY_SHADER);
|
||||
else if (ext == "tcs") return glCreateShader(GL_TESS_CONTROL_SHADER);
|
||||
else if (ext == "tes") return glCreateShader(GL_TESS_EVALUATION_SHADER);
|
||||
else if (ext == "vert") return glCreateShader(GL_VERTEX_SHADER);
|
||||
else return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// Disable copying and assignment
|
||||
Shader(Shader const &) = delete;
|
||||
Shader & operator =(Shader const &) = delete;
|
||||
|
||||
// Private member variables
|
||||
GLuint mProgram;
|
||||
GLint mStatus;
|
||||
GLint mLength;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,82 +1,19 @@
|
||||
// Local headers
|
||||
#include "gloom/gloom.hpp"
|
||||
#include "program.hpp"
|
||||
|
||||
// System headers
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "gloom/config.hpp"
|
||||
#include "Game.h"
|
||||
|
||||
// Standard headers
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
// A callback which allows GLFW to report errors whenever they occur
|
||||
static void glfwErrorCallback(int error, const char *description)
|
||||
{
|
||||
fprintf(stderr, "GLFW returned an error:\n\t%s (%i)\n", description, error);
|
||||
}
|
||||
|
||||
|
||||
GLFWwindow* initialise()
|
||||
{
|
||||
// Initialise GLFW
|
||||
if (!glfwInit())
|
||||
{
|
||||
fprintf(stderr, "Could not start GLFW\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set core window options (adjust version numbers if needed)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
// Enable the GLFW runtime error callback function defined previously.
|
||||
glfwSetErrorCallback(glfwErrorCallback);
|
||||
|
||||
// Set additional window options
|
||||
glfwWindowHint(GLFW_RESIZABLE, windowResizable);
|
||||
glfwWindowHint(GLFW_SAMPLES, windowSamples); // MSAA
|
||||
|
||||
// Create window using GLFW
|
||||
GLFWwindow* window = glfwCreateWindow(windowWidth,
|
||||
windowHeight,
|
||||
windowTitle.c_str(),
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
// Ensure the window is set up correctly
|
||||
if (!window)
|
||||
{
|
||||
fprintf(stderr, "Could not open GLFW window\n");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the window be the current OpenGL context and initialise glad
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL();
|
||||
|
||||
// Print various OpenGL information to stdout
|
||||
printf("%s: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
|
||||
printf("GLFW\t %s\n", glfwGetVersionString());
|
||||
printf("OpenGL\t %s\n", glGetString(GL_VERSION));
|
||||
printf("GLSL\t %s\n\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argb[])
|
||||
{
|
||||
// Initialise window using GLFW
|
||||
GLFWwindow* window = initialise();
|
||||
|
||||
// Run an OpenGL application using this window
|
||||
runProgram(window);
|
||||
|
||||
// Terminate GLFW (no need to call glfwDestroyWindow)
|
||||
glfwTerminate();
|
||||
int main(int argc, char *argb[]) {
|
||||
srand(time(nullptr));
|
||||
std::cout << "Seed: " << SEED << std::endl;
|
||||
Game game;
|
||||
game.run();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// Local headers
|
||||
#include "program.hpp"
|
||||
#include "gloom/gloom.hpp"
|
||||
|
||||
|
||||
void runProgram(GLFWwindow* window)
|
||||
{
|
||||
// Enable depth (Z) buffer (accept "closest" fragment)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
// Configure miscellaneous OpenGL settings
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Set default colour after clearing the colour buffer
|
||||
glClearColor(0.3f, 0.5f, 0.8f, 1.0f);
|
||||
|
||||
// Set up your scene here (create Vertex Array Objects, etc.)
|
||||
|
||||
// Rendering Loop
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
// Clear colour and depth buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Draw your scene here
|
||||
|
||||
// Handle other events
|
||||
glfwPollEvents();
|
||||
handleKeyboardInput(window);
|
||||
|
||||
// Flip buffers
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleKeyboardInput(GLFWwindow* window)
|
||||
{
|
||||
// Use escape key for terminating the GLFW window
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
{
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
#ifndef PROGRAM_HPP
|
||||
#define PROGRAM_HPP
|
||||
#pragma once
|
||||
|
||||
|
||||
// System headers
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glad/glad.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
// Main OpenGL program
|
||||
void runProgram(GLFWwindow* window);
|
||||
|
||||
|
||||
// Function for handling keypresses
|
||||
void handleKeyboardInput(GLFWwindow* window);
|
||||
|
||||
|
||||
// Checks for whether an OpenGL error occurred. If one did,
|
||||
// it prints out the error type and ID
|
||||
inline void printGLError() {
|
||||
int errorID = glGetError();
|
||||
|
||||
if(errorID != GL_NO_ERROR) {
|
||||
std::string errorString;
|
||||
|
||||
switch(errorID) {
|
||||
case GL_INVALID_ENUM:
|
||||
errorString = "GL_INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
errorString = "GL_INVALID_OPERATION";
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
errorString = "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
errorString = "GL_OUT_OF_MEMORY";
|
||||
break;
|
||||
case GL_STACK_UNDERFLOW:
|
||||
errorString = "GL_STACK_UNDERFLOW";
|
||||
break;
|
||||
case GL_STACK_OVERFLOW:
|
||||
errorString = "GL_STACK_OVERFLOW";
|
||||
break;
|
||||
default:
|
||||
errorString = "[Unknown error ID]";
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "An OpenGL error occurred (%i): %s.\n",
|
||||
errorID, errorString.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user