summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/AssetManager.cpp169
-rw-r--r--src/core/Core.cpp1146
-rw-r--r--src/core/Core.hpp87
-rw-r--r--src/graphics/Frustrum.cpp111
-rw-r--r--src/graphics/Frustrum.hpp24
-rw-r--r--src/network/Network.cpp144
-rw-r--r--src/utility/Vector.hpp215
7 files changed, 1122 insertions, 774 deletions
diff --git a/src/core/AssetManager.cpp b/src/core/AssetManager.cpp
index bcf50bc..4fb5388 100644
--- a/src/core/AssetManager.cpp
+++ b/src/core/AssetManager.cpp
@@ -10,76 +10,131 @@ const std::string pathToAssetsList = "./items.json";
const std::string pathToTextureIndex = "./textures.json";
AssetManager::AssetManager() {
- LoadIds();
- LoadTextureResources();
+ LoadIds();
+ LoadTextureResources();
}
void AssetManager::LoadIds() {
- std::ifstream in(pathToAssetsList);
- nlohmann::json index;
- in >> index;
- for (auto &it:index) {
- int id = it["type"].get<int>();
- int state = it["meta"].get<int>();
- std::string blockName = it["text_type"].get<std::string>();
- assetIds[blockName] = Block(id, state);
- }
- LOG(INFO) << "Loaded " << assetIds.size() << " ids";
+ std::ifstream in(pathToAssetsList);
+ nlohmann::json index;
+ in >> index;
+ for (auto &it:index) {
+ int id = it["type"].get<int>();
+ int state = it["meta"].get<int>();
+ std::string blockName = it["text_type"].get<std::string>();
+ assetIds[blockName] = Block(id, state);
+ }
+ LOG(INFO) << "Loaded " << assetIds.size() << " ids";
}
AssetManager::~AssetManager() {
- delete textureAtlas;
+ delete textureAtlas;
}
//TODO: This function must be replaced with runtime texture atlas generating
void AssetManager::LoadTextureResources() {
- std::ifstream in(pathToTextureIndex);
- nlohmann::json index;
- in >> index;
- std::string filename = index["meta"]["image"].get<std::string>();
- float textureWidth = index["meta"]["size"]["w"].get<int>();
- float textureHeight = index["meta"]["size"]["h"].get<int>();
- for (auto &it:index["frames"]) {
- auto frame = it["frame"];
- TextureCoordinates coord;
- coord.x = frame["x"].get<int>() / textureWidth;
- coord.y = frame["y"].get<int>() / textureHeight;
- coord.w = frame["w"].get<int>() / textureWidth;
- coord.h = frame["h"].get<int>() / textureHeight;
- std::string assetName = it["filename"].get<std::string>();
- assetName.insert(0, "minecraft/textures/");
- assetName.erase(assetName.length() - 4);
- assetTextures[assetName] = coord;
- }
-
- textureAtlas = new Texture(filename);
- LOG(INFO) << "Texture atlas id is " << textureAtlas->texture;
+ std::ifstream in(pathToTextureIndex);
+ nlohmann::json index;
+ in >> index;
+ std::string filename = index["meta"]["image"].get<std::string>();
+ float textureWidth = index["meta"]["size"]["w"].get<int>();
+ float textureHeight = index["meta"]["size"]["h"].get<int>();
+ for (auto &it:index["frames"]) {
+ auto frame = it["frame"];
+ TextureCoordinates coord;
+ coord.x = frame["x"].get<int>() / textureWidth;
+ coord.y = frame["y"].get<int>() / textureHeight;
+ coord.w = frame["w"].get<int>() / textureWidth;
+ coord.h = frame["h"].get<int>() / textureHeight;
+ std::string assetName = it["filename"].get<std::string>();
+ assetName.insert(0, "minecraft/textures/");
+ assetName.erase(assetName.length() - 4);
+ assetTextures[assetName] = coord;
+ }
+
+ textureAtlas = new Texture(filename);
+ LOG(INFO) << "Texture atlas id is " << textureAtlas->texture;
}
TextureCoordinates AssetManager::GetTextureByAssetName(std::string AssetName) {
- if (assetTextures.find(AssetName) != assetTextures.end())
- return assetTextures[AssetName];
- else
- return TextureCoordinates{-1, -1, -1, -1};
+ if (assetTextures.find(AssetName) != assetTextures.end())
+ return assetTextures[AssetName];
+ else
+ return TextureCoordinates{-1, -1, -1, -1};
}
std::string AssetManager::GetTextureAssetNameByBlockId(BlockTextureId block) {
- //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side
- const std::map<BlockTextureId, std::string> lookupTable = {
- {BlockTextureId(0, 0), "minecraft/textures/blocks/air"},
- {BlockTextureId(1, 0), "minecraft/textures/blocks/stone"},
- {BlockTextureId(1, 1), "minecraft/textures/blocks/stone_granite"},
-
- {BlockTextureId(2, 0, 0), "minecraft/textures/blocks/dirt"},
- {BlockTextureId(2, 0, 1), "minecraft/textures/blocks/grass_top"},
- {BlockTextureId(2, 0, 2), "minecraft/textures/blocks/grass_side"},
- {BlockTextureId(2, 0, 3), "minecraft/textures/blocks/grass_side"},
- {BlockTextureId(2, 0, 4), "minecraft/textures/blocks/grass_side"},
- {BlockTextureId(2, 0, 5), "minecraft/textures/blocks/grass_side"},
-
- {BlockTextureId(3, 0), "minecraft/textures/blocks/dirt"},
- {BlockTextureId(4, 0), "minecraft/textures/blocks/cobblestone"},
- };
+ //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side
+ const std::map<BlockTextureId, std::string> lookupTable = {
+ {BlockTextureId(0, 0), "minecraft/textures/blocks/air"},
+ {BlockTextureId(1, 0), "minecraft/textures/blocks/stone"},
+ {BlockTextureId(1, 1), "minecraft/textures/blocks/stone_granite"},
+
+ {BlockTextureId(2, 0, 0), "minecraft/textures/blocks/dirt"},
+ {BlockTextureId(2, 0, 1), "minecraft/textures/blocks/grass_top"},
+ {BlockTextureId(2, 0, 2), "minecraft/textures/blocks/grass_side"},
+ {BlockTextureId(2, 0, 3), "minecraft/textures/blocks/grass_side"},
+ {BlockTextureId(2, 0, 4), "minecraft/textures/blocks/grass_side"},
+ {BlockTextureId(2, 0, 5), "minecraft/textures/blocks/grass_side"},
+
+ {BlockTextureId(3, 0), "minecraft/textures/blocks/dirt"},
+ {BlockTextureId(4, 0), "minecraft/textures/blocks/cobblestone"},
+ {BlockTextureId(5, 0), "minecraft/textures/blocks/planks"},
+
+ {BlockTextureId(7, 0), "minecraft/textures/blocks/bedrock"},
+
+ {BlockTextureId(17, 0, 0), "minecraft/textures/blocks/log_oak_top"},
+ {BlockTextureId(17, 0, 1), "minecraft/textures/blocks/log_oak_top"},
+ {BlockTextureId(17, 0, 2), "minecraft/textures/blocks/log_oak"},
+ {BlockTextureId(17, 0, 3), "minecraft/textures/blocks/log_oak"},
+ {BlockTextureId(17, 0, 4), "minecraft/textures/blocks/log_oak"},
+ {BlockTextureId(17, 0, 5), "minecraft/textures/blocks/log_oak"},
+
+ {BlockTextureId(17, 1, 0), "minecraft/textures/blocks/log_spruce_top"},
+ {BlockTextureId(17, 1, 1), "minecraft/textures/blocks/log_spruce_top"},
+ {BlockTextureId(17, 1, 2), "minecraft/textures/blocks/log_spruce"},
+ {BlockTextureId(17, 1, 3), "minecraft/textures/blocks/log_spruce"},
+ {BlockTextureId(17, 1, 4), "minecraft/textures/blocks/log_spruce"},
+ {BlockTextureId(17, 1, 5), "minecraft/textures/blocks/log_spruce"},
+
+ {BlockTextureId(17, 2, 0), "minecraft/textures/blocks/log_birch_top"},
+ {BlockTextureId(17, 2, 1), "minecraft/textures/blocks/log_birch_top"},
+ {BlockTextureId(17, 2, 2), "minecraft/textures/blocks/log_birch"},
+ {BlockTextureId(17, 2, 3), "minecraft/textures/blocks/log_birch"},
+ {BlockTextureId(17, 2, 4), "minecraft/textures/blocks/log_birch"},
+ {BlockTextureId(17, 2, 5), "minecraft/textures/blocks/log_birch"},
+
+ {BlockTextureId(17, 3, 0), "minecraft/textures/blocks/log_jungle_top"},
+ {BlockTextureId(17, 3, 1), "minecraft/textures/blocks/log_jungle_top"},
+ {BlockTextureId(17, 3, 2), "minecraft/textures/blocks/log_jungle"},
+ {BlockTextureId(17, 3, 3), "minecraft/textures/blocks/log_jungle"},
+ {BlockTextureId(17, 3, 4), "minecraft/textures/blocks/log_jungle"},
+ {BlockTextureId(17, 3, 5), "minecraft/textures/blocks/log_jungle"},
+
+ {BlockTextureId(18, 0), "minecraft/textures/blocks/leaves_oak"},
+ {BlockTextureId(18, 1), "minecraft/textures/blocks/leaves_spruce"},
+ {BlockTextureId(18, 2), "minecraft/textures/blocks/leaves_birch"},
+ {BlockTextureId(18, 3), "minecraft/textures/blocks/leaves_jungle"},
+
+ {BlockTextureId(61, 0, 0), "minecraft/textures/blocks/furnace_side"},
+ {BlockTextureId(61, 0, 1), "minecraft/textures/blocks/furnace_top"},
+ {BlockTextureId(61, 0, 2), "minecraft/textures/blocks/furnace_front_off"},
+ {BlockTextureId(61, 0, 3), "minecraft/textures/blocks/furnace_side"},
+ {BlockTextureId(61, 0, 4), "minecraft/textures/blocks/furnace_side"},
+ {BlockTextureId(61, 0, 5), "minecraft/textures/blocks/furnace_side"},
+
+ {BlockTextureId(62, 0, 0), "minecraft/textures/blocks/furnace_side"},
+ {BlockTextureId(62, 0, 1), "minecraft/textures/blocks/furnace_top"},
+ {BlockTextureId(62, 0, 2), "minecraft/textures/blocks/furnace_front_on"},
+ {BlockTextureId(62, 0, 3), "minecraft/textures/blocks/furnace_side"},
+ {BlockTextureId(62, 0, 4), "minecraft/textures/blocks/furnace_side"},
+ {BlockTextureId(62, 0, 5), "minecraft/textures/blocks/furnace_side"},
+
+
+ {BlockTextureId(31, 0), "minecraft/textures/blocks/deadbush"},
+ {BlockTextureId(31, 1), "minecraft/textures/blocks/tallgrass"},
+ {BlockTextureId(31, 2), "minecraft/textures/blocks/fern"},
+ };
auto ret = lookupTable.find(block);
if (ret == lookupTable.end())
return "";
@@ -88,10 +143,10 @@ std::string AssetManager::GetTextureAssetNameByBlockId(BlockTextureId block) {
}
GLuint AssetManager::GetTextureAtlas() {
- return textureAtlas->texture;
+ return textureAtlas->texture;
}
TextureCoordinates AssetManager::GetTextureByBlock(BlockTextureId block) {
- std::string assetName = this->GetTextureAssetNameByBlockId(block);
- return this->GetTextureByAssetName(assetName);
+ std::string assetName = this->GetTextureAssetNameByBlockId(block);
+ return this->GetTextureByAssetName(assetName);
}
diff --git a/src/core/Core.cpp b/src/core/Core.cpp
index 3257cb6..9ad36ba 100644
--- a/src/core/Core.cpp
+++ b/src/core/Core.cpp
@@ -1,574 +1,692 @@
#include "Core.hpp"
GLenum glCheckError_(const char *file, int line) {
- GLenum errorCode;
- while ((errorCode = glGetError()) != GL_NO_ERROR) {
- std::string error;
- switch (errorCode) {
- case GL_INVALID_ENUM:
- error = "INVALID_ENUM";
- break;
- case GL_INVALID_VALUE:
- error = "INVALID_VALUE";
- break;
- case GL_INVALID_OPERATION:
- error = "INVALID_OPERATION";
- break;
- case GL_STACK_OVERFLOW:
- error = "STACK_OVERFLOW";
- break;
- case GL_STACK_UNDERFLOW:
- error = "STACK_UNDERFLOW";
- break;
- case GL_OUT_OF_MEMORY:
- error = "OUT_OF_MEMORY";
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- error = "INVALID_FRAMEBUFFER_OPERATION";
- break;
- }
- LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line;
- }
- return errorCode;
+ GLenum errorCode;
+ while ((errorCode = glGetError()) != GL_NO_ERROR) {
+ std::string error;
+ switch (errorCode) {
+ case GL_INVALID_ENUM:
+ error = "INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ error = "INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ error = "INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ error = "STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ error = "STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ error = "OUT_OF_MEMORY";
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ error = "INVALID_FRAMEBUFFER_OPERATION";
+ break;
+ }
+ LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line;
+ }
+ return errorCode;
}
#define glCheckError() glCheckError_(__FILE__, __LINE__)
const GLfloat vertices[] = {
- //Z+ edge
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
-
- //Z- edge
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- //X+ edge
- -0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
-
- //X- edge
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- //Y+ edge
- 0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, 0.5f,
-
- //Y- edge
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
+ //Z+ edge
+ -0.5f, 0.5f, 0.5f,
+ -0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+
+ //Z- edge
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f,
+
+ //X+ edge
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f,
+
+ //X- edge
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f,
+
+ //Y+ edge
+ 0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, 0.5f,
+
+ //Y- edge
+ -0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, 0.5f,
+ -0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
};
-/*const GLfloat vertices[] = {
- //Z+ edge
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
-
- //Z- edge
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- //X+ edge
- -0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
-
- //X- edge
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- //Y+ edge
- 0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, 0.5f,
-
- //Y- edge
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
-};*/
const GLfloat uv_coords[] = {
- //Z+
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 0.0f,
- 1.0f, 1.0f,
-
- //Z-
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 1.0f,
-
- //X+
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 0.0f, 1.0f,
- 1.0f, 0.0f,
- 1.0f, 1.0f,
-
- //X-
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 1.0f, 1.0f,
-
- //Y+
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 1.0f, 1.0f,
-
- //Y-
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 1.0f,
- 1.0f, 0.0f,
+ //Z+
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+
+ //Z-
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 0.0f,
+ 0.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+
+ //X+
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 0.0f, 1.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+
+ //X-
+ 0.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+
+ //Y+
+ 0.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+
+ //Y-
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 1.0f, 0.0f,
};
Core::Core() {
- LOG(INFO) << "Core initializing...";
- InitSfml(900, 450, "AltCraft");
- glCheckError();
- InitGlew();
- glCheckError();
- client = new NetworkClient("127.0.0.1", 25565, "HelloOne");
- gameState = new GameState(client);
- std::thread loop = std::thread(&Core::UpdateGameState, this);
- std::swap(loop, gameStateLoopThread);
- assetManager = new AssetManager;
- PrepareToWorldRendering();
- LOG(INFO) << "Core is initialized";
- glCheckError();
+ LOG(INFO) << "Core initializing...";
+ InitSfml(900, 450, "AltCraft");
+ glCheckError();
+ InitGlew();
+ glCheckError();
+ client = new NetworkClient("127.0.0.1", 25565, "HelloOne");
+ gameState = new GameState(client);
+ std::thread loop = std::thread(&Core::UpdateGameState, this);
+ std::swap(loop, gameStateLoopThread);
+ assetManager = new AssetManager;
+ PrepareToWorldRendering();
+ LOG(INFO) << "Core is initialized";
+ glCheckError();
}
Core::~Core() {
- LOG(INFO) << "Core stopping...";
- gameStateLoopThread.join();
- delete shader;
- delete gameState;
- delete client;
- delete assetManager;
- delete window;
- LOG(INFO) << "Core is stopped";
+ LOG(INFO) << "Core stopping...";
+ gameStateLoopThread.join();
+ delete shader;
+ delete gameState;
+ delete client;
+ delete assetManager;
+ delete window;
+ LOG(INFO) << "Core is stopped";
}
void Core::Exec() {
- LOG(INFO) << "Main loop is executing!";
- isRunning = true;
- while (isRunning) {
- static sf::Clock clock, clock1;
- deltaTime = clock.getElapsedTime().asSeconds();
- absTime = clock1.getElapsedTime().asSeconds();
- clock.restart();
-
- static bool alreadyDone = false;
- if (gameState->g_IsGameStarted && !alreadyDone) {
- alreadyDone = true;
- UpdateChunksToRender();
- }
-
- std::ostringstream toWindow;
- glm::highp_vec3 camPos(camera.Position);
- toWindow << std::setprecision(2) << std::fixed;
- toWindow << "Pos: " << camPos.x << ", " << camPos.y << ", " << camPos.z << "; ";
- toWindow << "FPS: " << (1.0f / deltaTime) << " ";
- window->setTitle(toWindow.str());
-
- HandleEvents();
- if (isMouseCaptured)
- HandleMouseCapture();
- glCheckError();
-
- RenderFrame();
-
- }
+ LOG(INFO) << "Main loop is executing!";
+ isRunning = true;
+ while (isRunning) {
+ static sf::Clock clock, clock1;
+ deltaTime = clock.getElapsedTime().asSeconds();
+ absTime = clock1.getElapsedTime().asSeconds();
+ clock.restart();
+
+ static bool alreadyDone = false;
+ if (gameState->g_IsGameStarted && !alreadyDone) {
+ alreadyDone = true;
+ UpdateChunksToRender();
+ }
+
+ std::ostringstream toWindow;
+ glm::highp_vec3 camPos(camera.Position);
+ toWindow << std::setprecision(2) << std::fixed;
+ toWindow << "Pos: " << camPos.x << ", " << camPos.y << ", " << camPos.z << "; ";
+ toWindow << "FPS: " << (1.0f / deltaTime) << " ";
+ toWindow << " (" << deltaTime * 1000 << "ms) ";
+ window->setTitle(toWindow.str());
+
+ HandleEvents();
+ if (isMouseCaptured)
+ HandleMouseCapture();
+ glCheckError();
+
+ RenderFrame();
+
+ }
}
void Core::RenderFrame() {
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- switch (currentState) {
- case MainMenu:
- //RenderGui(MenuScreen);
- break;
- case Loading:
- //RenderGui(LoadingScreen);
- break;
- case Playing:
- RenderWorld();
- //RenderGui(HUD);
- break;
- case PauseMenu:
- RenderWorld();
- //RenderGui(PauseGui);
- break;
- }
-
- window->display();
+ glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ switch (currentState) {
+ case MainMenu:
+ //RenderGui(MenuScreen);
+ break;
+ case Loading:
+ //RenderGui(LoadingScreen);
+ break;
+ case Playing:
+ RenderWorld();
+ //RenderGui(HUD);
+ break;
+ case PauseMenu:
+ RenderWorld();
+ //RenderGui(PauseGui);
+ break;
+ }
+
+ window->display();
}
void Core::InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle) {
- LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\"";
- sf::ContextSettings contextSetting;
- contextSetting.majorVersion = 3;
- contextSetting.minorVersion = 3;
- contextSetting.attributeFlags = contextSetting.Core;
- contextSetting.depthBits = 24;
- window = new sf::Window(sf::VideoMode(WinWidth, WinHeight), WinTitle, sf::Style::Default, contextSetting);
- glCheckError();
- //window->setVerticalSyncEnabled(true);
- //window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2, sf::VideoMode::getDesktopMode().height / 2));
- window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2 - window->getSize().x / 2,
- sf::VideoMode::getDesktopMode().height / 2 - window->getSize().y / 2));
-
- SetMouseCapture(false);
+ LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\"";
+ sf::ContextSettings contextSetting;
+ contextSetting.majorVersion = 3;
+ contextSetting.minorVersion = 3;
+ contextSetting.attributeFlags = contextSetting.Core;
+ contextSetting.depthBits = 24;
+ window = new sf::Window(sf::VideoMode(WinWidth, WinHeight), WinTitle, sf::Style::Default, contextSetting);
+ glCheckError();
+ //window->setVerticalSyncEnabled(true);
+ //window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2, sf::VideoMode::getDesktopMode().height / 2));
+ window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2 - window->getSize().x / 2,
+ sf::VideoMode::getDesktopMode().height / 2 - window->getSize().y / 2));
+
+ SetMouseCapture(false);
}
void Core::InitGlew() {
- LOG(INFO) << "Initializing GLEW";
- glewExperimental = GL_TRUE;
- GLenum glewStatus = glewInit();
- glCheckError();
- if (glewStatus != GLEW_OK) {
- LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus);
- }
- glViewport(0, 0, width(), height());
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- glFrontFace(GL_CCW);
- glCheckError();
+ LOG(INFO) << "Initializing GLEW";
+ glewExperimental = GL_TRUE;
+ GLenum glewStatus = glewInit();
+ glCheckError();
+ if (glewStatus != GLEW_OK) {
+ LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus);
+ }
+ glViewport(0, 0, width(), height());
+ glEnable(GL_DEPTH_TEST);
+ //glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ glFrontFace(GL_CCW);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glCheckError();
}
unsigned int Core::width() {
- return window->getSize().x;
+ return window->getSize().x;
}
unsigned int Core::height() {
- return window->getSize().y;
+ return window->getSize().y;
}
void Core::HandleEvents() {
- sf::Event event;
- while (window->pollEvent(event)) {
- switch (event.type) {
- case sf::Event::Closed:
- LOG(INFO) << "Received close event by window closing";
- isRunning = false;
- break;
- case sf::Event::Resized:
- glViewport(0, 0, width(), height());
- break;
- case sf::Event::KeyPressed:
- if (!window->hasFocus())
- break;
- switch (event.key.code) {
- case sf::Keyboard::Escape:
- LOG(INFO) << "Received close event by esc";
- isRunning = false;
- break;
- case sf::Keyboard::T:
- SetMouseCapture(!isMouseCaptured);
- break;
- case sf::Keyboard::Z:
- camera.MovementSpeed /= 2;
- break;
- case sf::Keyboard::X:
- camera.MovementSpeed *= 2;
- break;
- default:
- break;
- }
- case sf::Event::MouseWheelScrolled:
- if (!window->hasFocus())
- break;
- camera.ProcessMouseScroll(event.mouseWheelScroll.delta);
- break;
- default:
- break;
- }
- }
- if (window->hasFocus()) {
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
- camera.ProcessKeyboard(Camera_Movement::FORWARD, deltaTime);
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
- camera.ProcessKeyboard(Camera_Movement::BACKWARD, deltaTime);
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
- camera.ProcessKeyboard(Camera_Movement::LEFT, deltaTime);
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
- camera.ProcessKeyboard(Camera_Movement::RIGHT, deltaTime);
- }
+ sf::Event event;
+ while (window->pollEvent(event)) {
+ switch (event.type) {
+ case sf::Event::Closed:
+ LOG(INFO) << "Received close event by window closing";
+ isRunning = false;
+ break;
+ case sf::Event::Resized:
+ glViewport(0, 0, width(), height());
+ break;
+ case sf::Event::KeyPressed:
+ if (!window->hasFocus())
+ break;
+ switch (event.key.code) {
+ case sf::Keyboard::Escape:
+ LOG(INFO) << "Received close event by esc";
+ isRunning = false;
+ break;
+ case sf::Keyboard::T:
+ SetMouseCapture(!isMouseCaptured);
+ break;
+ case sf::Keyboard::Z:
+ camera.MovementSpeed /= 2;
+ break;
+ case sf::Keyboard::X:
+ camera.MovementSpeed *= 2;
+ break;
+ case sf::Keyboard::M:
+ std::sort(toRender.begin(), toRender.end(), [this](const Vector &lhs, const Vector &rhs) {
+ return glm::length((glm::vec3) lhs - camera.Position) <
+ glm::length((glm::vec3) rhs - camera.Position);
+ });
+ LOG(WARNING) << "Render list is optimized";
+ break;
+ case sf::Keyboard::K:
+ ChunkDistance++;
+ LOG(INFO)<<"Increased render distance: "<<ChunkDistance;
+ break;
+ case sf::Keyboard::L:
+ ChunkDistance--;
+ LOG(INFO)<<"Decreased render distance: "<<ChunkDistance;
+ break;
+ case sf::Keyboard::O:
+ UpdateChunksToRender();
+ LOG(INFO)<<"Render list is updated";
+ break;
+ default:
+ break;
+ }
+ case sf::Event::MouseWheelScrolled:
+ if (!window->hasFocus())
+ break;
+ camera.ProcessMouseScroll(event.mouseWheelScroll.delta);
+ break;
+ default:
+ break;
+ }
+ }
+ if (window->hasFocus()) {
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
+ camera.ProcessKeyboard(Camera_Movement::FORWARD, deltaTime);
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
+ camera.ProcessKeyboard(Camera_Movement::BACKWARD, deltaTime);
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
+ camera.ProcessKeyboard(Camera_Movement::LEFT, deltaTime);
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
+ camera.ProcessKeyboard(Camera_Movement::RIGHT, deltaTime);
+ }
}
void Core::HandleMouseCapture() {
- sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
- sf::Vector2i center = sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2);
- sf::Mouse::setPosition(center, *window);
- mouseXDelta = (mousePos - center).x, mouseYDelta = (center - mousePos).y;
- camera.ProcessMouseMovement(mouseXDelta, mouseYDelta);
+ sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
+ sf::Vector2i center = sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2);
+ sf::Mouse::setPosition(center, *window);
+ mouseXDelta = (mousePos - center).x, mouseYDelta = (center - mousePos).y;
+ camera.ProcessMouseMovement(mouseXDelta, mouseYDelta);
}
void Core::RenderGui(Gui &Target) {
- Target.WHY++;
+ Target.WHY++;
}
void Core::RenderWorld() {
- shader->Use();
- glCheckError();
-
- GLint modelLoc = glGetUniformLocation(shader->Program, "model");
- GLint projectionLoc = glGetUniformLocation(shader->Program, "projection");
- GLint viewLoc = glGetUniformLocation(shader->Program, "view");
- GLint blockLoc = glGetUniformLocation(shader->Program, "Block");
- GLint stateLoc = glGetUniformLocation(shader->Program, "State");
- GLint timeLoc = glGetUniformLocation(shader->Program, "time");
- glm::mat4 projection = glm::perspective(camera.Zoom, (float) width() / (float) height(), 0.1f, 10000000.0f);
- glm::mat4 view = camera.GetViewMatrix();
- glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
- glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
- glUniform1f(timeLoc, absTime);
-
- glCheckError();
-
- glBindVertexArray(VAO);
-
- for (auto &sectionPos : toRender) {
- Section &section = gameState->world.m_sections.find(sectionPos)->second;
- for (int y = 0; y < 16; y++) {
- for (int z = 0; z < 16; z++) {
- for (int x = 0; x < 16; x++) {
- Block block = section.GetBlock(Vector(x, y, z));
- if (block.id == 0)
- continue;
-
- glm::mat4 model;
- model = glm::translate(model, glm::vec3(sectionPos.GetX() * 16, sectionPos.GetY() * 16,
- sectionPos.GetZ() * 16));
- model = glm::translate(model, glm::vec3(x, y, z));
-
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
- glUniform1i(blockLoc, block.id);
- glUniform1i(stateLoc, block.state);
-
- glDrawArrays(GL_TRIANGLES, 0, 36);
- }
- }
- }
- }
- glBindVertexArray(0);
- glCheckError();
+ shader->Use();
+ glCheckError();
+
+ GLint modelLoc = glGetUniformLocation(shader->Program, "model");
+ GLint projectionLoc = glGetUniformLocation(shader->Program, "projection");
+ GLint viewLoc = glGetUniformLocation(shader->Program, "view");
+ GLint blockLoc = glGetUniformLocation(shader->Program, "Block");
+ GLint stateLoc = glGetUniformLocation(shader->Program, "State");
+ GLint timeLoc = glGetUniformLocation(shader->Program, "time");
+ glm::mat4 projection = glm::perspective(camera.Zoom, (float) width() / (float) height(), 0.1f, 10000000.0f);
+ glm::mat4 view = camera.GetViewMatrix();
+ glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
+ glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
+ glUniform1f(timeLoc, absTime);
+ glUniform2f(glGetUniformLocation(shader->Program, "windowSize"), width(), height());
+
+ glCheckError();
+
+ glBindVertexArray(VAO);
+ for (auto &sectionPos : toRender) {
+ Section &section = gameState->world.m_sections.find(sectionPos)->second;
+
+ std::vector<Vector> sectionCorners = {
+ Vector(0, 0, 0),
+ Vector(0, 0, 16),
+ Vector(0, 16, 0),
+ Vector(0, 16, 16),
+ Vector(16, 0, 0),
+ Vector(16, 0, 16),
+ Vector(16, 16, 0),
+ Vector(16, 16, 16),
+ };
+ bool isBreak = true;
+ for (auto &it:sectionCorners) {
+ glm::mat4 vp = projection * view;
+ glm::vec3 point(sectionPos.GetX() * 16 + it.GetX(), sectionPos.GetY() * 16 + it.GetY(),
+ sectionPos.GetZ() * 16 + it.GetZ());
+ glm::vec4 p = vp * glm::vec4(point, 1);
+ glm::vec3 res = glm::vec3(p) / p.w;
+ if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) {
+ isBreak = false;
+ break;
+ }
+ }
+ if (isBreak && glm::length(
+ camera.Position - glm::vec3(sectionPos.GetX() * 16, sectionPos.GetY() * 16, sectionPos.GetZ() * 16)) >
+ 30) {
+ //zLOG(ERROR)<<"CULL";
+ continue;
+ }
+
+ std::vector<glm::mat4> &arrOfModels = toRenderModels[sectionPos];
+ std::vector<glm::vec2> &arrOfBlocks = toRenderBlocks[sectionPos];
+
+ glBindBuffer(GL_ARRAY_BUFFER, VBO3);
+ glBufferData(GL_ARRAY_BUFFER, arrOfModels.size() * sizeof(glm::mat4), arrOfModels.data(), GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, VBO4);
+ glBufferData(GL_ARRAY_BUFFER, arrOfBlocks.size() * sizeof(glm::vec2), arrOfBlocks.data(), GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDrawArraysInstanced(GL_TRIANGLES, 0, 36, arrOfModels.size());
+ }
+ glBindVertexArray(0);
+ glCheckError();
}
void Core::SetMouseCapture(bool IsCaptured) {
- window->setMouseCursorVisible(!isMouseCaptured);
- sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), *window);
- isMouseCaptured = IsCaptured;
- window->setMouseCursorVisible(!IsCaptured);
+ window->setMouseCursorVisible(!isMouseCaptured);
+ sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), *window);
+ isMouseCaptured = IsCaptured;
+ window->setMouseCursorVisible(!IsCaptured);
}
void Core::PrepareToWorldRendering() {
- //Cube-rendering data
- glGenBuffers(1, &VBO);
- glGenBuffers(1, &VBO2);
- glGenVertexArrays(1, &VAO);
-
- glBindVertexArray(VAO);
- {
- glBindBuffer(GL_ARRAY_BUFFER, VBO2);
- glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
- glEnableVertexAttribArray(2);
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
- glEnableVertexAttribArray(0);
- }
- glBindVertexArray(0);
-
- glCheckError();
-
- shader = new Shader("./shaders/block.vs", "./shaders/block.fs");
- shader->Use();
-
- LOG(INFO) << "Initializing texture atlas...";
- //TextureAtlas texture
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, assetManager->GetTextureAtlas());
- glUniform1i(glGetUniformLocation(shader->Program, "textureAtlas"), 0);
-
- //TextureAtlas coordinates
- std::vector<glm::vec4> textureCoordinates;
- std::vector<GLint> indexes;
- GLint totalTextures;
- for (int id = 1; id < 4096; id++) {
- bool isReachedEnd = true;
- for (int state = 0; state < 16; state++) {
- BlockTextureId blockTextureId(id, state, 6);
- if (!assetManager->GetTextureByBlock(blockTextureId) &&
- !assetManager->GetTextureByBlock(BlockTextureId(id, state, 0))) {
- continue;
- }
- isReachedEnd = false;
- int side = assetManager->GetTextureByBlock(blockTextureId) ? 6 : 0;
- do {
- int index = (side << 16) | (id << 4) | state;
- TextureCoordinates tc = assetManager->GetTextureByBlock(BlockTextureId(id, state, side));
- textureCoordinates.push_back(glm::vec4(tc.x, tc.y, tc.w, tc.h));
- indexes.push_back(index);
- /*LOG(ERROR) << "Encoded texture (" << id << " " << state << " " << side << ") as " << index << " ("
- << std::bitset<19>(index) << ")" << " = " << tc.x << "," << tc.y << "," << tc.w << ","
- << tc.h;*/
- /*LOG(FATAL)<<std::bitset<18>(index);
- side = 0x7;
- id = 0xFFF;
- state = 0xF;
- LOG(WARNING) << "side: " << side << " id: " << id << " state: " << state;
- int i, si, st, index = 0;
- si = side << 15;
- i = id<<3;
- st = state;
- index = i | si | st;
- LOG(FATAL) << std::bitset<18>(index) << " (" << index << "): " << std::bitset<18>(si) << " "
- << std::bitset<18>(i) << " " << std::bitset<18>(st);*/
- /*if (rand() == 73) //Almost impossible(Almost==1/32768)
- {
- int index = 393233;
- LOG(WARNING) << std::bitset<20>(index) << "(" << index << ")";
- int side = (index & 0xE0000) >> 16;
- int id = (index & 0xFF0) >> 4;
- int state = index & 0xF;
- LOG(WARNING) << std::bitset<20>(side) << " " << std::bitset<20>(id) << " "
- << std::bitset<20>(state);
- LOG(FATAL) << side << " " << id << " " << state;
- }*/
- side++;
- } while (side < 6);
- }
- if (isReachedEnd)
- break;
-
- }
- totalTextures = indexes.size();
- LOG(INFO) << "Created " << totalTextures << " texture indexes";
- CHECK_EQ(indexes.size(), textureCoordinates.size()) << "Arrays of textureCoordinates and of indexes is not equals";
- CHECK_LE(totalTextures, 1023) << "There is more texture indexes, than GLSL buffer allows";
-
- GLuint bp1 = 0;
- GLuint ubo = glGetUniformBlockIndex(shader->Program, "TextureIndexes");
- glUniformBlockBinding(shader->Program, ubo, bp1);
- glGenBuffers(1, &UBO);
- glBindBuffer(GL_UNIFORM_BUFFER, UBO);
- glBindBufferBase(GL_UNIFORM_BUFFER, bp1, UBO);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) + sizeof(glm::vec4) * 1023, NULL, GL_STATIC_DRAW);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GLint), &totalTextures); //copy totalTextures
- for (int i = 0; i < indexes.size(); i++) {
- size_t baseOffset = sizeof(glm::vec4);
- size_t itemOffset = sizeof(glm::vec4);
- size_t offset = baseOffset + i * itemOffset;
- /*int index = indexes[i];
- int side = (index & 0x70000) >> 16;
- int id = (index & 0xFF0) >> 4;
- int state = index & 0xF;
- LOG(WARNING) << "Copying " << indexes[i] << " at " << offset<<" side is "<<side;*/
- glBufferSubData(GL_UNIFORM_BUFFER, offset, sizeof(GLint), &indexes[i]); //copy indexes' item
- }
- glCheckError();
-
- GLuint bp2 = 1;
- GLuint ubo2_index = glGetUniformBlockIndex(shader->Program, "TextureData");
- glUniformBlockBinding(shader->Program, ubo2_index, bp2);
- glGenBuffers(1, &UBO2);
- glBindBuffer(GL_UNIFORM_BUFFER, UBO2);
- glBindBufferBase(GL_UNIFORM_BUFFER, bp2, UBO2);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) * 1024, NULL, GL_STATIC_DRAW);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::vec4) * textureCoordinates.size(), textureCoordinates.data());
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
- glCheckError();
+ //Cube-rendering data
+ glGenBuffers(1, &VBO);
+ glGenBuffers(1, &VBO2);
+ glGenBuffers(1, &VBO3);
+ glGenBuffers(1, &VBO4);
+ glGenVertexArrays(1, &VAO);
+
+ glBindVertexArray(VAO);
+ {
+ //Cube vertices
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
+ glEnableVertexAttribArray(0);
+
+ //Cube UVs
+ glBindBuffer(GL_ARRAY_BUFFER, VBO2);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW);
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
+ glEnableVertexAttribArray(2);
+
+ //Blocks ids
+ glBindBuffer(GL_ARRAY_BUFFER, VBO4);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 16 * 16 * 16, NULL, GL_DYNAMIC_DRAW);
+ glVertexAttribPointer(7, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
+ glEnableVertexAttribArray(7);
+ glVertexAttribDivisor(7, 1);
+ glCheckError();
+
+ //Blocks models
+ glBindBuffer(GL_ARRAY_BUFFER, VBO3);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * 16 * 16 * 16, NULL, GL_DYNAMIC_DRAW);
+ glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), 0);
+ glEnableVertexAttribArray(8);
+ glVertexAttribPointer(8 + 1, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat),
+ (void *) (1 * 4 * sizeof(GLfloat)));
+ glEnableVertexAttribArray(8 + 1);
+ glVertexAttribPointer(8 + 2, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat),
+ (void *) (2 * 4 * sizeof(GLfloat)));
+ glEnableVertexAttribArray(8 + 2);
+ glVertexAttribPointer(8 + 3, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat),
+ (void *) (3 * 4 * sizeof(GLfloat)));
+ glEnableVertexAttribArray(8 + 3);
+ glVertexAttribDivisor(8, 1);
+ glVertexAttribDivisor(8 + 1, 1);
+ glVertexAttribDivisor(8 + 2, 1);
+ glVertexAttribDivisor(8 + 3, 1);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ glBindVertexArray(0);
+
+ glCheckError();
+
+ shader = new Shader("./shaders/block.vs", "./shaders/block.fs");
+ shader->Use();
+
+ shader2 = new Shader("./shaders/simple.vs", "./shaders/simple.fs");
+
+ LOG(INFO) << "Initializing texture atlas...";
+ //TextureAtlas texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, assetManager->GetTextureAtlas());
+ glUniform1i(glGetUniformLocation(shader->Program, "textureAtlas"), 0);
+
+ //TextureAtlas coordinates
+ std::vector<glm::vec4> textureCoordinates;
+ std::vector<GLint> indexes;
+ GLint totalTextures;
+ for (int id = 1; id < 128; id++) {
+ for (int state = 0; state < 16; state++) {
+ BlockTextureId blockTextureId(id, state, 6);
+ if (!assetManager->GetTextureByBlock(blockTextureId) &&
+ !assetManager->GetTextureByBlock(BlockTextureId(id, state, 0))) {
+ continue;
+ }
+ int side = assetManager->GetTextureByBlock(blockTextureId) ? 6 : 0;
+ do {
+ int index = (side << 16) | (id << 4) | state;
+ TextureCoordinates tc = assetManager->GetTextureByBlock(BlockTextureId(id, state, side));
+ textureCoordinates.push_back(glm::vec4(tc.x, tc.y, tc.w, tc.h));
+ indexes.push_back(index);
+ /*LOG(ERROR) << "Encoded texture (" << id << " " << state << " " << side << ") as " << index << " ("
+ << std::bitset<19>(index) << ")" << " = " << tc.x << "," << tc.y << "," << tc.w << ","
+ << tc.h;*/
+ /*LOG(FATAL)<<std::bitset<18>(index);
+ side = 0x7;
+ id = 0xFFF;
+ state = 0xF;
+ LOG(WARNING) << "side: " << side << " id: " << id << " state: " << state;
+ int i, si, st, index = 0;
+ si = side << 15;
+ i = id<<3;
+ st = state;
+ index = i | si | st;
+ LOG(FATAL) << std::bitset<18>(index) << " (" << index << "): " << std::bitset<18>(si) << " "
+ << std::bitset<18>(i) << " " << std::bitset<18>(st);*/
+ /*if (rand() == 73) //Almost impossible(Almost==1/32768)
+ {
+ int index = 393233;
+ LOG(WARNING) << std::bitset<20>(index) << "(" << index << ")";
+ int side = (index & 0xE0000) >> 16;
+ int id = (index & 0xFF0) >> 4;
+ int state = index & 0xF;
+ LOG(WARNING) << std::bitset<20>(side) << " " << std::bitset<20>(id) << " "
+ << std::bitset<20>(state);
+ LOG(FATAL) << side << " " << id << " " << state;
+ }*/
+ side++;
+ } while (side < 6);
+ }
+ }
+ totalTextures = indexes.size();
+ LOG(INFO) << "Created " << totalTextures << " texture indexes";
+ CHECK_EQ(indexes.size(), textureCoordinates.size())
+ << "Arrays of textureCoordinates and of indexes is not equals";
+ CHECK_LE(totalTextures, 1023) << "There is more texture indexes, than GLSL buffer allows";
+
+ GLuint bp1 = 0;
+ GLuint ubo = glGetUniformBlockIndex(shader->Program, "TextureIndexes");
+ glUniformBlockBinding(shader->Program, ubo, bp1);
+ glGenBuffers(1, &UBO);
+ glBindBuffer(GL_UNIFORM_BUFFER, UBO);
+ glBindBufferBase(GL_UNIFORM_BUFFER, bp1, UBO);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) + sizeof(glm::vec4) * 1023, NULL, GL_STATIC_DRAW);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GLint), &totalTextures); //copy totalTextures
+ for (int i = 0; i < indexes.size(); i++) {
+ size_t baseOffset = sizeof(glm::vec4);
+ size_t itemOffset = sizeof(glm::vec4);
+ size_t offset = baseOffset + i * itemOffset;
+ /*int index = indexes[i];
+ int side = (index & 0x70000) >> 16;
+ int id = (index & 0xFF0) >> 4;
+ int state = index & 0xF;
+ LOG(WARNING) << "Copying " << indexes[i] << " at " << offset<<" side is "<<side;*/
+ glBufferSubData(GL_UNIFORM_BUFFER, offset, sizeof(GLint), &indexes[i]); //copy indexes' item
+ }
+ glCheckError();
+
+ GLuint bp2 = 1;
+ GLuint ubo2_index = glGetUniformBlockIndex(shader->Program, "TextureData");
+ glUniformBlockBinding(shader->Program, ubo2_index, bp2);
+ glGenBuffers(1, &UBO2);
+ glBindBuffer(GL_UNIFORM_BUFFER, UBO2);
+ glBindBufferBase(GL_UNIFORM_BUFFER, bp2, UBO2);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) * 1024, NULL, GL_STATIC_DRAW);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::vec4) * textureCoordinates.size(), textureCoordinates.data());
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ glCheckError();
+
+ //Draw Lines preparing
+ glGenBuffers(1, &VBO5);
+ glGenVertexArrays(1, &VAO2);
+ glBindVertexArray(VAO2);
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, VBO5);
+ glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ glBindVertexArray(0);
}
void Core::UpdateChunksToRender() {
- camera.Position = glm::vec3(gameState->g_PlayerX, gameState->g_PlayerY, gameState->g_PlayerZ);
- toRender.clear();
- const float ChunkDistance = 2;
- Vector playerChunk = Vector(floor(gameState->g_PlayerX / 16.0f), floor(gameState->g_PlayerY / 16.0f),
- floor(gameState->g_PlayerZ / 16.0f));
- for (auto &it:gameState->world.m_sections) {
- Vector chunkPosition = it.first;
- Vector delta = chunkPosition - playerChunk;
- if (delta.GetDistance() > ChunkDistance)
- continue;
- toRender.push_back(chunkPosition);
- }
- LOG(INFO) << "Chunks to render: " << toRender.size();
+ camera.Position = glm::vec3(gameState->g_PlayerX, gameState->g_PlayerY, gameState->g_PlayerZ);
+ toRender.clear();
+ Vector playerChunk = Vector(floor(gameState->g_PlayerX / 16.0f), 0, floor(gameState->g_PlayerZ / 16.0f));
+ for (auto &it:gameState->world.m_sections) {
+ Vector chunkPosition = it.first;
+ chunkPosition.SetY(0);
+ Vector delta = chunkPosition - playerChunk;
+ if (delta.GetMagnitude() > ChunkDistance)
+ continue;
+ toRender.push_back(it.first);
+ }
+ LOG(INFO) << "Chunks to render: " << toRender.size();
+ for (auto &it:toRender) {
+ Section &section = gameState->world.m_sections.find(it)->second;
+ std::vector<glm::mat4> models;
+ std::vector<glm::vec2> blocks;
+ for (int y = 0; y < 16; y++) {
+ for (int z = 0; z < 16; z++) {
+ for (int x = 0; x < 16; x++) {
+ Block block = section.GetBlock(Vector(x, y, z));
+ if (block.id == 0)
+ continue;
+ unsigned char isVisible = 0;
+ if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) {
+ isVisible = 0;
+ } else {
+ isVisible |= (section.GetBlock(Vector(x + 1, y, z)).id != 0) << 0;
+ isVisible |= (section.GetBlock(Vector(x - 1, y, z)).id != 0) << 1;
+ isVisible |= (section.GetBlock(Vector(x, y + 1, z)).id != 0) << 2;
+ isVisible |= (section.GetBlock(Vector(x, y - 1, z)).id != 0) << 3;
+ isVisible |= (section.GetBlock(Vector(x, y, z + 1)).id != 0) << 4;
+ isVisible |= (section.GetBlock(Vector(x, y, z - 1)).id != 0) << 5;
+ }
+ if (isVisible == 0x3F)
+ continue;
+ glm::vec2 data(block.id, block.state);
+ blocks.push_back(data);
+ glm::mat4 model;
+ model = glm::translate(model, glm::vec3(it.GetX() * 16, it.GetY() * 16, it.GetZ() * 16));
+ model = glm::translate(model, glm::vec3(x, y, z));
+ double size = 0.999;
+ model = glm::scale(model, glm::vec3(size, size, size));
+ models.push_back(model);
+ }
+ }
+ }
+ toRenderBlocks[it] = blocks;
+ toRenderModels[it] = models;
+ }
+ std::sort(toRender.begin(), toRender.end(), [this](const Vector &lhs, const Vector &rhs) {
+ return glm::length((glm::vec3) lhs - camera.Position) < glm::length((glm::vec3) rhs - camera.Position);
+ });
+ LOG(INFO) << "Chunks is prepared to rendering...";
}
void Core::UpdateGameState() {
- el::Helpers::setThreadName("Game");
- LOG(INFO) << "GameState thread is started";
- while (isRunning) {
- gameState->Update();
- if (toRender.size() > 0)
- break;
- }
- LOG(INFO) << "GameState thread is stopped";
+ el::Helpers::setThreadName("Game");
+ LOG(INFO) << "GameState thread is started";
+ while (isRunning) {
+ gameState->Update();
+ if (toRender.size() > 0)
+ break;
+ }
+ LOG(INFO) << "GameState thread is stopped";
+}
+
+void Core::DrawLine(glm::vec3 from, glm::vec3 to, glm::vec3 color) {
+ shader2->Use();
+ glm::mat4 projection = glm::perspective(camera.Zoom, (float) width() / (float) height(), 0.1f, 10000000.0f);
+ glm::mat4 view = camera.GetViewMatrix();
+ glUniformMatrix4fv(glGetUniformLocation(shader2->Program, "projection"), 1, GL_FALSE,
+ glm::value_ptr(projection));
+ glUniformMatrix4fv(glGetUniformLocation(shader2->Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
+
+ /*GLfloat data[6];
+ data[0] = from[0];
+ data[1] = from[1];
+ data[2] = to[2];
+ data[3] = to[0];
+ data[4] = to[1];
+ data[5] = from[2];*/
+ GLfloat data[] = {0.5f, 0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ -0.5f, 0.5f, 0.0f,
+
+ 0.5f, -0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ -0.5f, 0.5f, 0.0f,};
+
+ glUniform3f(glGetUniformLocation(shader2->Program, "color"), color[0], color[1], color[2]);
+
+ glDisable(GL_DEPTH_TEST);
+ glBindVertexArray(VAO2);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO5);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 18, data, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glBindVertexArray(0);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void Core::UpdateOptimizedRender() {
+
+ LOG(INFO) << "Render list is optimized";
}
diff --git a/src/core/Core.hpp b/src/core/Core.hpp
index e5fe315..97a51fd 100644
--- a/src/core/Core.hpp
+++ b/src/core/Core.hpp
@@ -4,6 +4,7 @@
#include <SFML/Window.hpp>
#include <GL/glew.h>
#include <iomanip>
+#include <tuple>
#include <glm/gtc/type_ptr.hpp>
#include "../gamestate/GameState.hpp"
#include "../network/NetworkClient.hpp"
@@ -11,62 +12,74 @@
#include "../graphics/Camera3D.hpp"
#include "../graphics/Shader.hpp"
#include "AssetManager.hpp"
+#include "../graphics/Frustrum.hpp"
class Core {
- GameState *gameState;
- NetworkClient *client;
- sf::Window *window;
- AssetManager *assetManager;
- bool isMouseCaptured = false;
- bool isRunning = true;
- enum {
- MainMenu,
- Loading,
- Playing,
- PauseMenu,
- } currentState = Playing;
- float mouseXDelta, mouseYDelta;
- float deltaTime;
- float absTime;
+ GameState *gameState;
+ NetworkClient *client;
+ sf::Window *window;
+ AssetManager *assetManager;
+ bool isMouseCaptured = false;
+ bool isRunning = true;
+ enum {
+ MainMenu,
+ Loading,
+ Playing,
+ PauseMenu,
+ } currentState = Playing;
+ float mouseXDelta, mouseYDelta;
+ float deltaTime;
+ float absTime;
- void RenderWorld();
+ void RenderWorld();
- void RenderGui(Gui &Target);
+ void RenderGui(Gui &Target);
- void HandleMouseCapture();
+ void HandleMouseCapture();
- void HandleEvents();
+ void HandleEvents();
- void InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle);
+ void InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle);
- void InitGlew();
+ void InitGlew();
- void SetMouseCapture(bool IsCaptured);
+ void SetMouseCapture(bool IsCaptured);
- void PrepareToWorldRendering();
+ void PrepareToWorldRendering();
- void RenderFrame();
+ void RenderFrame();
- unsigned int width();
+ unsigned int width();
- unsigned int height();
+ unsigned int height();
- void UpdateChunksToRender();
+ void UpdateChunksToRender();
- void UpdateGameState();
+ void UpdateGameState();
- std::thread gameStateLoopThread;
+ void DrawLine(glm::vec3 from, glm::vec3 to, glm::vec3 color);
- Camera3D camera;
- Shader *shader;
- //Cube verticies, Cube VAO, Cube UVs, TextureIndexes UBO, TextureData UBO, TextureData2 UBO
- GLuint VBO, VAO, VBO2, UBO,UBO2,UBO3;
- std::vector<Vector> toRender;
+ std::thread gameStateLoopThread;
+
+ Camera3D camera;
+ Shader *shader,*shader2;
+ //Cube verticies, Cube VAO, Cube UVs, TextureIndexes UBO, TextureData UBO, TextureData2 UBO, Blocks VBO, Models VBO, Line VAO, Lines VBO
+ GLuint VBO, VAO, VBO2, UBO, UBO2, VBO3, VBO4, VAO2, VBO5;
+ std::vector<Vector> toRender;
+ std::vector<Vector> optimizedRender;
+
+ void UpdateOptimizedRender();
+
+ int ChunkDistance = 4;
+
+ std::map<Vector, std::vector<glm::mat4>> toRenderModels;
+ std::map<Vector, std::vector<glm::vec2>> toRenderBlocks;
+ //std::map<Vector, std::tuple<std::vector<glm::mat4>, std::vector<glm::vec2> > > sectionsRenderingData;
public:
- Core();
+ Core();
- ~Core();
+ ~Core();
- void Exec();
+ void Exec();
};
diff --git a/src/graphics/Frustrum.cpp b/src/graphics/Frustrum.cpp
new file mode 100644
index 0000000..75f47c5
--- /dev/null
+++ b/src/graphics/Frustrum.cpp
@@ -0,0 +1,111 @@
+#include "Frustrum.hpp"
+
+enum FrustumSide {
+ RIGHT = 0, // The RIGHT side of the frustum
+ LEFT = 1, // The LEFT side of the frustum
+ BOTTOM = 2, // The BOTTOM side of the frustum
+ TOP = 3, // The TOP side of the frustum
+ BACK = 4, // The BACK side of the frustum
+ FRONT = 5 // The FRONT side of the frustum
+};
+
+enum PlaneData {
+ A = 0, // The X value of the plane's normal
+ B = 1, // The Y value of the plane's normal
+ C = 2, // The Z value of the plane's normal
+ D = 3 // The distance the plane is from the origin
+};
+
+void normalizePlane(glm::vec4 &frustum_plane) {
+ float magnitude = (float) sqrt(frustum_plane[A] * frustum_plane[A] + frustum_plane[B] * frustum_plane[B] +
+ frustum_plane[C] * frustum_plane[C]);
+ frustum_plane[A] /= magnitude;
+ frustum_plane[B] /= magnitude;
+ frustum_plane[C] /= magnitude;
+ frustum_plane[D] /= magnitude;
+}
+
+void Frustum::CalculateFrustum(glm::mat4 &view_matrix, glm::mat4 &proj_matrix) {
+ float proj[16];
+ float modl[16];
+ const float *projP = glm::value_ptr(proj_matrix);
+ const float *modlP = glm::value_ptr(view_matrix);
+ for (int i = 0; i < 16; i++) {
+ proj[i]=projP[i];
+ modl[i]=modlP[i];
+ }
+
+ float clip[16]; //clipping planes
+
+ clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + modl[3] * proj[12];
+ clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + modl[3] * proj[13];
+ clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + modl[3] * proj[14];
+ clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + modl[3] * proj[15];
+
+ clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + modl[7] * proj[12];
+ clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + modl[7] * proj[13];
+ clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + modl[7] * proj[14];
+ clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + modl[7] * proj[15];
+
+ clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + modl[11] * proj[12];
+ clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + modl[11] * proj[13];
+ clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + modl[11] * proj[14];
+ clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + modl[11] * proj[15];
+
+ clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + modl[15] * proj[12];
+ clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + modl[15] * proj[13];
+ clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + modl[15] * proj[14];
+ clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + modl[15] * proj[15];
+
+ frustum_planes[RIGHT][A] = clip[3] - clip[0];
+ frustum_planes[RIGHT][B] = clip[7] - clip[4];
+ frustum_planes[RIGHT][C] = clip[11] - clip[8];
+ frustum_planes[RIGHT][D] = clip[15] - clip[12];
+ normalizePlane(frustum_planes[RIGHT]);
+
+ frustum_planes[LEFT][A] = clip[3] + clip[0];
+ frustum_planes[LEFT][B] = clip[7] + clip[4];
+ frustum_planes[LEFT][C] = clip[11] + clip[8];
+ frustum_planes[LEFT][D] = clip[15] + clip[12];
+ normalizePlane(frustum_planes[LEFT]);
+
+ frustum_planes[BOTTOM][A] = clip[3] + clip[1];
+ frustum_planes[BOTTOM][B] = clip[7] + clip[5];
+ frustum_planes[BOTTOM][C] = clip[11] + clip[9];
+ frustum_planes[BOTTOM][D] = clip[15] + clip[13];
+ normalizePlane(frustum_planes[BOTTOM]);
+
+ frustum_planes[TOP][A] = clip[3] - clip[1];
+ frustum_planes[TOP][B] = clip[7] - clip[5];
+ frustum_planes[TOP][C] = clip[11] - clip[9];
+ frustum_planes[TOP][D] = clip[15] - clip[13];
+ normalizePlane(frustum_planes[TOP]);
+
+ frustum_planes[BACK][A] = clip[3] - clip[2];
+ frustum_planes[BACK][B] = clip[7] - clip[6];
+ frustum_planes[BACK][C] = clip[11] - clip[10];
+ frustum_planes[BACK][D] = clip[15] - clip[14];
+ normalizePlane(frustum_planes[BACK]);
+
+ frustum_planes[FRONT][A] = clip[3] + clip[2];
+ frustum_planes[FRONT][B] = clip[7] + clip[6];
+ frustum_planes[FRONT][C] = clip[11] + clip[10];
+ frustum_planes[FRONT][D] = clip[15] + clip[14];
+ normalizePlane(frustum_planes[FRONT]);
+}
+
+bool Frustum::TestInsideFrustrum(glm::vec4 Min, glm::vec4 Max) {
+ bool inside = true;
+ //test all 6 frustum planes
+ for (int i = 0; i < 6; i++) {
+ //pick closest point to plane and check if it behind the plane
+ //if yes - object outside frustum
+ float d = std::max(Min.x * frustum_planes[i].x, Max.x * frustum_planes[i].x)
+ + std::max(Min.y * frustum_planes[i].y, Max.y * frustum_planes[i].y)
+ + std::max(Min.z * frustum_planes[i].z, Max.z * frustum_planes[i].z)
+ + frustum_planes[i].w;
+ inside &= d > 0;
+ //return false; //with flag works faster
+ }
+ return inside;
+}
diff --git a/src/graphics/Frustrum.hpp b/src/graphics/Frustrum.hpp
new file mode 100644
index 0000000..e8a6fd6
--- /dev/null
+++ b/src/graphics/Frustrum.hpp
@@ -0,0 +1,24 @@
+#ifndef _FRUSTUM_H
+#define _FRUSTUM_H
+
+
+#include <cmath>
+#include <algorithm>
+#include <GL/glew.h>
+#include <glm/glm.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+class Frustum {
+public:
+ Frustum() = default;
+
+ ~Frustum() = default;
+
+ void CalculateFrustum(glm::mat4 &view_matrix, glm::mat4 &proj_matrix);
+
+ glm::vec4 frustum_planes[6];
+
+ bool TestInsideFrustrum(glm::vec4 Min, glm::vec4 Max);
+};
+
+#endif \ No newline at end of file
diff --git a/src/network/Network.cpp b/src/network/Network.cpp
index 399ce20..4ce424c 100644
--- a/src/network/Network.cpp
+++ b/src/network/Network.cpp
@@ -1,79 +1,101 @@
#include "Network.hpp"
Network::Network(std::string address, unsigned short port) : m_address(address), m_port(port) {
- LOG(INFO) << "Connecting to server " << m_address << ":" << m_port;
- sf::Socket::Status status = m_socket.connect(sf::IpAddress(m_address), m_port);
- m_socket.setBlocking(true);
- if (status != sf::Socket::Done) {
- if (status == sf::Socket::Error) {
- LOG(ERROR) << "Can't connect to remote server";
- } else {
- LOG(ERROR) << "Connection failed with unknown reason";
+ LOG(INFO) << "Connecting to server " << m_address << ":" << m_port;
+ sf::Socket::Status status = m_socket.connect(sf::IpAddress(m_address), m_port);
+ m_socket.setBlocking(true);
+ if (status != sf::Socket::Done) {
+ if (status == sf::Socket::Error) {
+ LOG(ERROR) << "Can't connect to remote server";
+ } else {
+ LOG(ERROR) << "Connection failed with unknown reason";
throw std::runtime_error("Connection is failed");
- throw 13;
- }
- }
- LOG(INFO) << "Connected to server";
+ throw 13;
+ }
+ }
+ LOG(INFO) << "Connected to server";
}
Network::~Network() {
- m_socket.disconnect();
- LOG(INFO) << "Disconnected";
+ m_socket.disconnect();
+ LOG(INFO) << "Disconnected";
}
void Network::SendHandshake(std::string username) {
- //Handshake packet
- Packet handshakePacket = PacketBuilder::CHandshaking0x00(316, m_address, m_port, 2);
- SendPacket(handshakePacket);
+ //Handshake packet
+ Packet handshakePacket = PacketBuilder::CHandshaking0x00(316, m_address, m_port, 2);
+ SendPacket(handshakePacket);
- //LoginStart packet
- Field fName;
- fName.SetString(username);
- Packet loginPacket(0);
- loginPacket.AddField(fName);
- SendPacket(loginPacket);
+ //LoginStart packet
+ Field fName;
+ fName.SetString(username);
+ Packet loginPacket(0);
+ loginPacket.AddField(fName);
+ SendPacket(loginPacket);
}
+void DumpPacket(Packet &packet, std::string DumpName) {
+ return;
+ byte *buff = new byte[packet.GetLength()];
+ packet.CopyToBuff(buff);
+ std::ofstream fs(DumpName, std::ios::out | std::ios::binary);
+ fs.write(reinterpret_cast<const char *>(buff), packet.GetLength());
+ fs.close();
+ delete buff;
+}
+
+static int pn = 0;
+
void Network::SendPacket(Packet &packet) {
- m_socket.setBlocking(true);
- byte *packetData = new byte[packet.GetLength()];
- packet.CopyToBuff(packetData);
- m_socket.send(packetData, packet.GetLength());
- delete[] packetData;
+ m_socket.setBlocking(true);
+ byte *packetData = new byte[packet.GetLength()];
+ packet.CopyToBuff(packetData);
+ m_socket.send(packetData, packet.GetLength());
+ std::ostringstream out;
+ out << "s" << pn++ << "-";
+ out << "0x" << (packet.GetId() < 15 ? "0" : "") << std::hex << packet.GetId() << std::dec;
+ DumpPacket(packet, out.str());
+
+ delete[] packetData;
}
Packet Network::ReceivePacket() {
- byte bufLen[5] = {0};
- size_t rec = 0;
- for (int i = 0; i < 5; i++) {
- byte buff = 0;
- size_t r = 0;
- m_socket.receive(&buff, 1, r);
- rec += r;
- bufLen[i] = buff;
- if ((buff & 0b10000000) == 0) {
- break;
- }
- }
- Field fLen = FieldParser::Parse(VarIntType, bufLen);
- size_t packetLen = fLen.GetVarInt() + fLen.GetLength();
- if (packetLen > 1024 * 1024 * 15)
- LOG(WARNING)<<"OMG SIZEOF PACKAGE IS "<<packetLen;
- if (packetLen < rec) {
- return Packet(bufLen);
- }
- byte *bufPack = new byte[packetLen];
- std::copy(bufLen, bufLen + rec, bufPack);
- size_t dataLen = rec;
- while (m_socket.receive(bufPack + dataLen, packetLen - dataLen, rec) == sf::Socket::Done && dataLen < packetLen) {
- dataLen += rec;
- }
- if (dataLen < packetLen) {
- LOG(ERROR) << "Received data is "<<dataLen<<" but "<<packetLen<<" is promoted";
- throw std::runtime_error("Data is losted");
- } else {
- Packet p(bufPack);
- delete[] bufPack;
- return p;
- }
+ byte bufLen[5] = {0};
+ size_t rec = 0;
+ for (int i = 0; i < 5; i++) {
+ byte buff = 0;
+ size_t r = 0;
+ m_socket.receive(&buff, 1, r);
+ rec += r;
+ bufLen[i] = buff;
+ if ((buff & 0b10000000) == 0) {
+ break;
+ }
+ }
+ Field fLen = FieldParser::Parse(VarIntType, bufLen);
+ size_t packetLen = fLen.GetVarInt() + fLen.GetLength();
+ if (packetLen > 1024 * 1024 * 15)
+ LOG(WARNING) << "OMG SIZEOF PACKAGE IS " << packetLen;
+ if (packetLen < rec) {
+ return Packet(bufLen);
+ }
+ byte *bufPack = new byte[packetLen];
+ std::copy(bufLen, bufLen + rec, bufPack);
+ size_t dataLen = rec;
+ while (m_socket.receive(bufPack + dataLen, packetLen - dataLen, rec) == sf::Socket::Done && dataLen < packetLen) {
+ dataLen += rec;
+ }
+ if (dataLen < packetLen) {
+ LOG(ERROR) << "Received data is " << dataLen << " but " << packetLen << " is promoted";
+ throw std::runtime_error("Data is losted");
+ } else {
+ Packet p(bufPack);
+ delete[] bufPack;
+
+ std::ostringstream out;
+ out << "r" << pn++ << "-";
+ out << "0x" << (p.GetId() < 15 ? "0" : "") << std::hex << p.GetId() << std::dec;
+ DumpPacket(p, out.str());
+ return p;
+ }
}
diff --git a/src/utility/Vector.hpp b/src/utility/Vector.hpp
index 7b34ac3..9d6c1be 100644
--- a/src/utility/Vector.hpp
+++ b/src/utility/Vector.hpp
@@ -1,117 +1,122 @@
#pragma once
+#include <glm/vec3.hpp>
#include <ostream>
#include <cmath>
#include <tuple>
template<class T>
class Vector3 {
- T x, y, z;
+ T x, y, z;
public:
- Vector3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {}
-
- Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {}
-
- ~Vector3() = default;
-
- void SetX(T X) { x = X; }
-
- void SetY(T Y) { y = Y; }
-
- void setZ(T Z) { z = Z; }
-
- T GetX() const { return x; }
-
- T GetY() const { return y; }
-
- T GetZ() const { return z; }
-
- double GetDistance() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); }
-
- void swap(Vector3 &rhs){
- std::swap(x,rhs.x);
- std::swap(y,rhs.y);
- std::swap(z,rhs.z);
- }
-
- Vector3 &operator=(Vector3 rhs) {
- rhs.swap(*this);
- return *this;
- }
-
- Vector3 operator*(T rhs) const {
- return Vector3<T>(
- x * rhs,
- y * rhs,
- z * rhs
- );
- }
-
- Vector3 operator/(T rhs) const {
- return Vector3<T>(
- x / rhs,
- y / rhs,
- z / rhs
- );
- }
-
- Vector3 operator+(const Vector3 &rhs) const {
- return Vector3<T>(
- x + rhs.x,
- y + rhs.y,
- z + rhs.z
- );
- }
-
- Vector3 operator-(const Vector3 &rhs) const {
- return Vector3<T>(
- x - rhs.x,
- y - rhs.y,
- z - rhs.z
- );
- }
-
- Vector3 operator*(const Vector3 &rhs) const {
- return Vector3<T>(
- x * rhs.x,
- y * rhs.y,
- z * rhs.z
- );
- }
-
- Vector3 operator/(const Vector3 &rhs) const {
- return Vector3<T>(
- x / rhs.x,
- y / rhs.y,
- z / rhs.z
- );
- }
-
- bool operator==(const Vector3 &rhs) const {
- return (x == rhs.x && y == rhs.y && z == rhs.z);
- }
-
- bool operator!=(const Vector3 &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator<(const Vector3 &rhs) const {
- //return (x < rhs.x || y < rhs.y ||z z < rhs.z);
- /*if (x < rhs.x)
- return true;
- else if (z < rhs.z)
- return true;
- else if (y < rhs.y)
- return true;
- return false;*/
- return std::tie(x,y,z)<std::tie(rhs.x,rhs.y,rhs.z);
- }
-
-
- friend std::ostream &operator<<(std::ostream &os, const Vector3 &vector3) {
- os << vector3.x << ", " << vector3.y << ", " << vector3.z;
- return os;
- }
+ Vector3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {}
+
+ Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {}
+
+ ~Vector3() = default;
+
+ void SetX(T X) { x = X; }
+
+ void SetY(T Y) { y = Y; }
+
+ void SetZ(T Z) { z = Z; }
+
+ T GetX() const { return x; }
+
+ T GetY() const { return y; }
+
+ T GetZ() const { return z; }
+
+ double GetMagnitude() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); }
+
+ operator glm::vec3() const {
+ return glm::vec3(x, y, z);
+ }
+
+ void swap(Vector3 &rhs) {
+ std::swap(x, rhs.x);
+ std::swap(y, rhs.y);
+ std::swap(z, rhs.z);
+ }
+
+ Vector3 &operator=(Vector3 rhs) {
+ rhs.swap(*this);
+ return *this;
+ }
+
+ Vector3 operator*(T rhs) const {
+ return Vector3<T>(
+ x * rhs,
+ y * rhs,
+ z * rhs
+ );
+ }
+
+ Vector3 operator/(T rhs) const {
+ return Vector3<T>(
+ x / rhs,
+ y / rhs,
+ z / rhs
+ );
+ }
+
+ Vector3 operator+(const Vector3 &rhs) const {
+ return Vector3<T>(
+ x + rhs.x,
+ y + rhs.y,
+ z + rhs.z
+ );
+ }
+
+ Vector3 operator-(const Vector3 &rhs) const {
+ return Vector3<T>(
+ x - rhs.x,
+ y - rhs.y,
+ z - rhs.z
+ );
+ }
+
+ Vector3 operator*(const Vector3 &rhs) const {
+ return Vector3<T>(
+ x * rhs.x,
+ y * rhs.y,
+ z * rhs.z
+ );
+ }
+
+ Vector3 operator/(const Vector3 &rhs) const {
+ return Vector3<T>(
+ x / rhs.x,
+ y / rhs.y,
+ z / rhs.z
+ );
+ }
+
+ bool operator==(const Vector3 &rhs) const {
+ return (x == rhs.x && y == rhs.y && z == rhs.z);
+ }
+
+ bool operator!=(const Vector3 &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator<(const Vector3 &rhs) const {
+ //return (x < rhs.x || y < rhs.y ||z z < rhs.z);
+ /*if (x < rhs.x)
+ return true;
+ else if (z < rhs.z)
+ return true;
+ else if (y < rhs.y)
+ return true;
+ return false;*/
+ return std::tie(x, y, z) < std::tie(rhs.x, rhs.y, rhs.z);
+ }
+
+
+ friend std::ostream &operator<<(std::ostream &os, const Vector3 &vector3) {
+ os << vector3.x << ", " << vector3.y << ", " << vector3.z;
+ return os;
+ }
};
typedef Vector3<double> VectorF;