summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaG1924 <12997935+LaG1924@users.noreply.github.com>2017-11-06 14:01:19 +0100
committerLaG1924 <12997935+LaG1924@users.noreply.github.com>2018-01-13 03:39:33 +0100
commit95c85382030af78854a42d457fbb259e6078402b (patch)
tree9ed941e9ee88cc77ece824c3c7bb872a37ec7d9b
parentMinor shader optimization (diff)
downloadAltCraft-95c85382030af78854a42d457fbb259e6078402b.tar
AltCraft-95c85382030af78854a42d457fbb259e6078402b.tar.gz
AltCraft-95c85382030af78854a42d457fbb259e6078402b.tar.bz2
AltCraft-95c85382030af78854a42d457fbb259e6078402b.tar.lz
AltCraft-95c85382030af78854a42d457fbb259e6078402b.tar.xz
AltCraft-95c85382030af78854a42d457fbb259e6078402b.tar.zst
AltCraft-95c85382030af78854a42d457fbb259e6078402b.zip
-rw-r--r--src/RendererSection.cpp300
-rw-r--r--src/RendererSection.hpp41
-rw-r--r--src/RendererSectionData.cpp300
-rw-r--r--src/RendererSectionData.hpp46
-rw-r--r--src/RendererWorld.cpp29
-rw-r--r--src/RendererWorld.hpp3
6 files changed, 367 insertions, 352 deletions
diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp
index 6fed06f..23b0a42 100644
--- a/src/RendererSection.cpp
+++ b/src/RendererSection.cpp
@@ -1,12 +1,10 @@
#include "RendererSection.hpp"
#include <easylogging++.h>
-#include <glm/gtc/matrix_transform.hpp>
-#include "AssetManager.hpp"
-#include "World.hpp"
-#include "Section.hpp"
+#include "Utility.hpp"
#include "Renderer.hpp"
+#include "RendererSectionData.hpp"
const GLfloat vertices[] = {
0, 0, 0,
@@ -32,7 +30,7 @@ const GLuint magicUniqueConstant = 88375;
GLuint RendererSection::VboVertices = magicUniqueConstant;
GLuint RendererSection::VboUvs = magicUniqueConstant;
-RendererSection::RendererSection(RendererSectionData data) {
+RendererSection::RendererSection(const RendererSectionData &data) {
if (VboVertices == magicUniqueConstant) {
glGenBuffers(1, &VboVertices);
glGenBuffers(1, &VboUvs);
@@ -172,296 +170,4 @@ Vector RendererSection::GetPosition()
size_t RendererSection::GetHash()
{
return hash;
-}
-
-RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) {
- const std::map<BlockTextureId, glm::vec4> &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes();
- const Section &section = world->GetSection(sectionPosition);
- hash = section.GetHash();
- sectionPos = sectionPosition;
-
- SetBlockIdData(world);
-
- auto blockVisibility = GetBlockVisibilityData(world);
-
- glm::mat4 baseOffset = glm::translate(glm::mat4(), (section.GetPosition() * 16).glm()),transform;
-
- auto sectionsList = world->GetSectionsList();
-
- for (int y = 0; y < 16; y++) {
- for (int z = 0; z < 16; z++) {
- for (int x = 0; x < 16; x++) {
- BlockId block = GetBlockId(x,y,z);
- if (block.id == 0)
- continue;
-
- const bool useNewMethod = true;
-
-
- transform = glm::translate(baseOffset, Vector(x, y, z).glm());
-
- const BlockModel* model = this->GetInternalBlockModel(block);
- if (model) {
- this->AddFacesByBlockModel(sectionsList, world, Vector(x, y, z), *model, transform, section.GetBlockLight(Vector(x, y, z)), section.GetBlockSkyLight(Vector(x, y, z)), blockVisibility);
- }
- else {
- transform = glm::translate(transform, glm::vec3(0, 1, 0));
-
- if (block.id == 8 || block.id == 9) {
- textures.push_back(AssetManager::Instance().GetTextureByAssetName("minecraft/textures/blocks/water_still"));
- textures.back().w /= 32.0f;
- transform = glm::translate(transform, glm::vec3(0, -0.2, 0));
- } else
- textures.push_back(AssetManager::Instance().GetTextureByAssetName("minecraft/textures/blocks/tnt_side"));
-
- models.push_back(transform);
- colors.push_back(glm::vec3(0, 0, 0));
- lights.push_back(glm::vec2(16, 16));
- }
-
- }
- }
- }
- textures.shrink_to_fit();
- models.shrink_to_fit();
- colors.shrink_to_fit();
-}
-
-void RendererSectionData::AddFacesByBlockModel(const std::vector<Vector> &sectionsList, World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight, const std::array<unsigned char, 16 * 16 * 16>& visibility) {
- glm::mat4 elementTransform, faceTransform;
- for (const auto& element : model.Elements) {
- Vector t = element.to - element.from;
- VectorF elementSize(VectorF(t.x,t.y,t.z) / 16.0f);
- VectorF elementOrigin(VectorF(element.from.x,element.from.y,element.from.z) / 16.0f);
- elementTransform = transform;
-
- /*if (element.rotationAngle != 0) {
- const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
- const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
- const glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
- const glm::vec3 *targetAxis = nullptr;
- switch (element.rotationAxis) {
- case BlockModel::ElementData::Axis::x:
- targetAxis = &xAxis;
- break;
- case BlockModel::ElementData::Axis::y:
- targetAxis = &yAxis;
- break;
- case BlockModel::ElementData::Axis::z:
- targetAxis = &zAxis;
- break;
- }
- VectorF rotateOrigin(VectorF(element.rotationOrigin.x, element.rotationOrigin.y, element.rotationOrigin.z) / 16.0f);
- elementTransform = glm::translate(elementTransform, -rotateOrigin.glm());
- elementTransform = glm::rotate(elementTransform, glm::radians(float(45)), yAxis);
- elementTransform = glm::translate(elementTransform, rotateOrigin.glm());
- }*/
- elementTransform = glm::translate(elementTransform, elementOrigin.glm());
- elementTransform = glm::scale(elementTransform, elementSize.glm());
-
- for (const auto& face : element.faces) {
- if (face.second.cullface != BlockModel::ElementData::FaceDirection::none) {
- unsigned char visible = visibility[blockPos.y * 256 + blockPos.z * 16 + blockPos.x];
-
- switch (face.second.cullface) {
- case BlockModel::ElementData::FaceDirection::down:
- if (visible >> 0 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::up:
- if (visible >> 1 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::north:
- if (visible >> 2 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::south:
- if (visible >> 3 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::west:
- if (visible >> 4 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::east:
- if (visible >> 5 & 0x1)
- continue;
- break;
- }
- }
-
- switch (face.first) {
- case BlockModel::ElementData::FaceDirection::down:
- faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 0));
- faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0, 0));
- faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1));
- break;
- case BlockModel::ElementData::FaceDirection::up:
- faceTransform = glm::translate(elementTransform, glm::vec3(0.0f, 1.0f, 0.0f));
- break;
- case BlockModel::ElementData::FaceDirection::north:
- faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 1));
- faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f));
- faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f));
- faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1));
- faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1, 0, 0.0f));
- faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1.0f));
- break;
- case BlockModel::ElementData::FaceDirection::south:
- faceTransform = glm::translate(elementTransform, glm::vec3(1, 0, 0));
- faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f));
- faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f));
- break;
- case BlockModel::ElementData::FaceDirection::west:
- faceTransform = glm::translate(elementTransform, glm::vec3(1, 0, 0));
- faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f));
- faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f));
- faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1));
- break;
- case BlockModel::ElementData::FaceDirection::east:
- faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 0));
- faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f));
- break;
- }
- models.push_back(faceTransform);
- std::string textureName = face.second.texture;
- while (textureName[0] == '#') {
- textureName = model.Textures.find(std::string(textureName.begin()+1,textureName.end()))->second;
- }
- glm::vec4 texture = AssetManager::Instance().GetTextureByAssetName("minecraft/textures/" + textureName);
-
- if (!(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,16,0,16 }) && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,0,0 })
- && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,16,16 })) {
- double x = face.second.uv.x1;
- double y = face.second.uv.x1;
- double w = face.second.uv.x2 - face.second.uv.x1;
- double h = face.second.uv.y2 - face.second.uv.y1;
- x /= 16.0;
- y /= 16.0;
- w /= 16.0;
- h /= 16.0;
- double X = texture.x;
- double Y = texture.y;
- double W = texture.z;
- double H = texture.w;
-
- texture = glm::vec4{ X + x * W, Y + y * H, w * W , h * H };
- }
- textures.push_back(texture);
- if (face.second.tintIndex)
- colors.push_back(glm::vec3(0.275, 0.63, 0.1));
- else
- colors.push_back(glm::vec3(0, 0, 0));
- lights.push_back(glm::vec2(light, skyLight));
- }
- }
-}
-
-std::array<unsigned char, 4096> RendererSectionData::GetBlockVisibilityData(World *world) {
- //const auto& section = world->GetSection(sectionPos);
- const auto& sectionDown = world->GetSection(sectionPos + Vector(0, -1, 0));
- const auto& sectionUp = world->GetSection(sectionPos + Vector(0, +1, 0));
- const auto& sectionNorth = world->GetSection(sectionPos + Vector(0, 0, +1));
- const auto& sectionSouth = world->GetSection(sectionPos + Vector(0, 0, -1));
- const auto& sectionWest = world->GetSection(sectionPos + Vector(+1, 0, 0));
- const auto& sectionEast = world->GetSection(sectionPos + Vector(-1, 0, 0));
-
- std::array<unsigned char, 4096> arr;
- for (int y = 0; y < 16; y++) {
- for (int z = 0; z < 16; z++) {
- for (int x = 0; x < 16; x++) {
- unsigned char value = 0;
- BlockId blockIdDown;
- BlockId blockIdUp;
- BlockId blockIdNorth;
- BlockId blockIdSouth;
- BlockId blockIdWest;
- BlockId blockIdEast;
-
- switch (y) {
- case 0:
- blockIdDown = sectionDown.GetBlockId(Vector(x, 15, z));
- blockIdUp = GetBlockId(x,1,z);
- break;
- case 15:
- blockIdDown = GetBlockId(x,14,z);
- blockIdUp = sectionUp.GetBlockId(Vector(x, 0, z));
- break;
- default:
- blockIdDown = GetBlockId(x, y -1, z);
- blockIdUp = GetBlockId(x, y + 1, z);
- break;
- }
-
- switch (z) {
- case 0:
- blockIdNorth = GetBlockId(x, y, 1);
- blockIdSouth = sectionSouth.GetBlockId(Vector(x, y, 15));
- break;
- case 15:
- blockIdNorth = sectionNorth.GetBlockId(Vector(x, y, 0));
- blockIdSouth = GetBlockId(x, y, 14);
- break;
- default:
- blockIdNorth = GetBlockId(x, y, z + 1);
- blockIdSouth = GetBlockId(x, y, z - 1);
- break;
- }
-
- switch (x) {
- case 0:
- blockIdWest = GetBlockId(1, y, z);
- blockIdEast = sectionEast.GetBlockId(Vector(15, y, z));
- break;
- case 15:
- blockIdWest = sectionWest.GetBlockId(Vector(0, y, z));
- blockIdEast = GetBlockId(14, y, z);
- break;
- default:
- blockIdWest = GetBlockId(x + 1, y, z);
- blockIdEast = GetBlockId(x - 1, y, z);
- break;
- }
-
- auto blockModelDown = GetInternalBlockModel(blockIdDown);
- auto blockModelUp = GetInternalBlockModel(blockIdUp);
- auto blockModelNorth = GetInternalBlockModel(blockIdNorth);
- auto blockModelSouth = GetInternalBlockModel(blockIdSouth);
- auto blockModelWest = GetInternalBlockModel(blockIdWest);
- auto blockModelEast = GetInternalBlockModel(blockIdEast);
-
- value |= (blockIdDown.id != 0 && blockModelDown && blockModelDown->IsBlock) << 0;
- value |= (blockIdUp.id != 0 && blockModelUp && blockModelUp->IsBlock) << 1;
- value |= (blockIdNorth.id != 0 && blockModelNorth && blockModelNorth->IsBlock) << 2;
- value |= (blockIdSouth.id != 0 && blockModelSouth && blockModelSouth->IsBlock) << 3;
- value |= (blockIdWest.id != 0 && blockModelWest && blockModelWest->IsBlock) << 4;
- value |= (blockIdEast.id != 0 && blockModelEast && blockModelEast->IsBlock) << 5;
-
- arr[y * 256 + z * 16 + x] = value;
- }
- }
- }
- return arr;
-}
-
-const BlockModel* RendererSectionData::GetInternalBlockModel(const BlockId& id) {
- for (const auto& it : idModels) {
- if (it.first == id)
- return it.second;
- }
- idModels.push_back(std::make_pair(id, AssetManager::Instance().GetBlockModelByBlockId(id)));
- return idModels.back().second;
-}
-
-void RendererSectionData::SetBlockIdData(World* world) {
- const Section& section = world->GetSection(sectionPos);
-
- for (int y = 0; y < 16; y++) {
- for (int z = 0; z < 16; z++) {
- for (int x = 0; x < 16; x++) {
- blockIdData[y * 256 + z * 16 + x] = section.GetBlockId(Vector(x,y,z));
- }
- }
- }
} \ No newline at end of file
diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp
index 26068e4..c9137ce 100644
--- a/src/RendererSection.hpp
+++ b/src/RendererSection.hpp
@@ -1,49 +1,12 @@
#pragma once
-#include <vector>
-#include <array>
-
#include <glm/mat4x4.hpp>
#include <GL/glew.h>
#include "Vector.hpp"
-#include "Block.hpp"
-class BlockModel;
-class AssetManager;
-class World;
class RenderState;
-
-struct RendererSectionData {
- std::vector<glm::mat4> models;
- std::vector<glm::vec4> textures;
- std::vector<glm::vec3> colors;
- std::vector<glm::vec2> lights;
- size_t hash;
- Vector sectionPos;
-
- RendererSectionData(World *world, Vector sectionPosition);
-private:
-
- void AddFacesByBlockModel(const std::vector<Vector> &sectionsList, World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight, const std::array<unsigned char, 16 * 16 * 16>& visibility);
-
- std::array<unsigned char, 16 * 16 * 16> GetBlockVisibilityData(World *world);
-
- std::vector<std::pair<BlockId, const BlockModel *>> idModels;
- const BlockModel* GetInternalBlockModel(const BlockId& id);
-
- std::array<BlockId, 4096> blockIdData;
- void SetBlockIdData(World *world);
-
- inline const BlockId& GetBlockId(const Vector& pos) {
- return blockIdData[pos.y * 256 + pos.z * 16 + pos.x];
- }
-
- inline const BlockId& GetBlockId(int x, int y, int z) {
- return blockIdData[y * 256 +z * 16 + x];
- }
-};
-
+class RendererSectionData;
class RendererSection {
enum Vbos {
@@ -63,7 +26,7 @@ class RendererSection {
RendererSection(const RendererSection &other) = delete;
public:
- RendererSection(RendererSectionData data);
+ RendererSection(const RendererSectionData &data);
RendererSection(RendererSection &&other);
diff --git a/src/RendererSectionData.cpp b/src/RendererSectionData.cpp
new file mode 100644
index 0000000..9a2b53c
--- /dev/null
+++ b/src/RendererSectionData.cpp
@@ -0,0 +1,300 @@
+#include "RendererSectionData.hpp"
+
+#include <glm/gtc/matrix_transform.hpp>
+
+#include "World.hpp"
+#include "AssetManager.hpp"
+#include "Section.hpp"
+
+RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) {
+ const std::map<BlockTextureId, glm::vec4> &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes();
+ const Section &section = world->GetSection(sectionPosition);
+ hash = section.GetHash();
+ sectionPos = sectionPosition;
+
+ SetBlockIdData(world);
+
+ auto blockVisibility = GetBlockVisibilityData(world);
+
+ glm::mat4 baseOffset = glm::translate(glm::mat4(), (section.GetPosition() * 16).glm()), transform;
+
+ auto sectionsList = world->GetSectionsList();
+
+ for (int y = 0; y < 16; y++) {
+ for (int z = 0; z < 16; z++) {
+ for (int x = 0; x < 16; x++) {
+ BlockId block = GetBlockId(x, y, z);
+ if (block.id == 0)
+ continue;
+
+ const bool useNewMethod = true;
+
+
+ transform = glm::translate(baseOffset, Vector(x, y, z).glm());
+
+ const BlockModel* model = this->GetInternalBlockModel(block);
+ if (model) {
+ this->AddFacesByBlockModel(sectionsList, world, Vector(x, y, z), *model, transform, section.GetBlockLight(Vector(x, y, z)), section.GetBlockSkyLight(Vector(x, y, z)), blockVisibility);
+ }
+ else {
+ transform = glm::translate(transform, glm::vec3(0, 1, 0));
+
+ if (block.id == 8 || block.id == 9) {
+ textures.push_back(AssetManager::Instance().GetTextureByAssetName("minecraft/textures/blocks/water_still"));
+ textures.back().w /= 32.0f;
+ transform = glm::translate(transform, glm::vec3(0, -0.2, 0));
+ }
+ else
+ textures.push_back(AssetManager::Instance().GetTextureByAssetName("minecraft/textures/blocks/tnt_side"));
+
+ models.push_back(transform);
+ colors.push_back(glm::vec3(0, 0, 0));
+ lights.push_back(glm::vec2(16, 16));
+ }
+
+ }
+ }
+ }
+ textures.shrink_to_fit();
+ models.shrink_to_fit();
+ colors.shrink_to_fit();
+}
+
+void RendererSectionData::AddFacesByBlockModel(const std::vector<Vector> &sectionsList, World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight, const std::array<unsigned char, 16 * 16 * 16>& visibility) {
+ glm::mat4 elementTransform, faceTransform;
+ for (const auto& element : model.Elements) {
+ Vector t = element.to - element.from;
+ VectorF elementSize(VectorF(t.x, t.y, t.z) / 16.0f);
+ VectorF elementOrigin(VectorF(element.from.x, element.from.y, element.from.z) / 16.0f);
+ elementTransform = transform;
+
+ /*if (element.rotationAngle != 0) {
+ const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
+ const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
+ const glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
+ const glm::vec3 *targetAxis = nullptr;
+ switch (element.rotationAxis) {
+ case BlockModel::ElementData::Axis::x:
+ targetAxis = &xAxis;
+ break;
+ case BlockModel::ElementData::Axis::y:
+ targetAxis = &yAxis;
+ break;
+ case BlockModel::ElementData::Axis::z:
+ targetAxis = &zAxis;
+ break;
+ }
+ VectorF rotateOrigin(VectorF(element.rotationOrigin.x, element.rotationOrigin.y, element.rotationOrigin.z) / 16.0f);
+ elementTransform = glm::translate(elementTransform, -rotateOrigin.glm());
+ elementTransform = glm::rotate(elementTransform, glm::radians(float(45)), yAxis);
+ elementTransform = glm::translate(elementTransform, rotateOrigin.glm());
+ }*/
+ elementTransform = glm::translate(elementTransform, elementOrigin.glm());
+ elementTransform = glm::scale(elementTransform, elementSize.glm());
+
+ for (const auto& face : element.faces) {
+ if (face.second.cullface != BlockModel::ElementData::FaceDirection::none) {
+ unsigned char visible = visibility[blockPos.y * 256 + blockPos.z * 16 + blockPos.x];
+
+ switch (face.second.cullface) {
+ case BlockModel::ElementData::FaceDirection::down:
+ if (visible >> 0 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::up:
+ if (visible >> 1 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::north:
+ if (visible >> 2 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::south:
+ if (visible >> 3 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::west:
+ if (visible >> 4 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::east:
+ if (visible >> 5 & 0x1)
+ continue;
+ break;
+ }
+ }
+
+ switch (face.first) {
+ case BlockModel::ElementData::FaceDirection::down:
+ faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 0));
+ faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0, 0));
+ faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1));
+ break;
+ case BlockModel::ElementData::FaceDirection::up:
+ faceTransform = glm::translate(elementTransform, glm::vec3(0.0f, 1.0f, 0.0f));
+ break;
+ case BlockModel::ElementData::FaceDirection::north:
+ faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 1));
+ faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f));
+ faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f));
+ faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1));
+ faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1, 0, 0.0f));
+ faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1.0f));
+ break;
+ case BlockModel::ElementData::FaceDirection::south:
+ faceTransform = glm::translate(elementTransform, glm::vec3(1, 0, 0));
+ faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f));
+ faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f));
+ break;
+ case BlockModel::ElementData::FaceDirection::west:
+ faceTransform = glm::translate(elementTransform, glm::vec3(1, 0, 0));
+ faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f));
+ faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f));
+ faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1));
+ break;
+ case BlockModel::ElementData::FaceDirection::east:
+ faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 0));
+ faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f));
+ break;
+ }
+ models.push_back(faceTransform);
+ std::string textureName = face.second.texture;
+ while (textureName[0] == '#') {
+ textureName = model.Textures.find(std::string(textureName.begin() + 1, textureName.end()))->second;
+ }
+ glm::vec4 texture = AssetManager::Instance().GetTextureByAssetName("minecraft/textures/" + textureName);
+
+ if (!(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,16,0,16 }) && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,0,0 })
+ && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,16,16 })) {
+ double x = face.second.uv.x1;
+ double y = face.second.uv.x1;
+ double w = face.second.uv.x2 - face.second.uv.x1;
+ double h = face.second.uv.y2 - face.second.uv.y1;
+ x /= 16.0;
+ y /= 16.0;
+ w /= 16.0;
+ h /= 16.0;
+ double X = texture.x;
+ double Y = texture.y;
+ double W = texture.z;
+ double H = texture.w;
+
+ texture = glm::vec4{ X + x * W, Y + y * H, w * W , h * H };
+ }
+ textures.push_back(texture);
+ if (face.second.tintIndex)
+ colors.push_back(glm::vec3(0.275, 0.63, 0.1));
+ else
+ colors.push_back(glm::vec3(0, 0, 0));
+ lights.push_back(glm::vec2(light, skyLight));
+ }
+ }
+}
+
+std::array<unsigned char, 4096> RendererSectionData::GetBlockVisibilityData(World *world) {
+ //const auto& section = world->GetSection(sectionPos);
+ const auto& sectionDown = world->GetSection(sectionPos + Vector(0, -1, 0));
+ const auto& sectionUp = world->GetSection(sectionPos + Vector(0, +1, 0));
+ const auto& sectionNorth = world->GetSection(sectionPos + Vector(0, 0, +1));
+ const auto& sectionSouth = world->GetSection(sectionPos + Vector(0, 0, -1));
+ const auto& sectionWest = world->GetSection(sectionPos + Vector(+1, 0, 0));
+ const auto& sectionEast = world->GetSection(sectionPos + Vector(-1, 0, 0));
+
+ std::array<unsigned char, 4096> arr;
+ for (int y = 0; y < 16; y++) {
+ for (int z = 0; z < 16; z++) {
+ for (int x = 0; x < 16; x++) {
+ unsigned char value = 0;
+ BlockId blockIdDown;
+ BlockId blockIdUp;
+ BlockId blockIdNorth;
+ BlockId blockIdSouth;
+ BlockId blockIdWest;
+ BlockId blockIdEast;
+
+ switch (y) {
+ case 0:
+ blockIdDown = sectionDown.GetBlockId(Vector(x, 15, z));
+ blockIdUp = GetBlockId(x, 1, z);
+ break;
+ case 15:
+ blockIdDown = GetBlockId(x, 14, z);
+ blockIdUp = sectionUp.GetBlockId(Vector(x, 0, z));
+ break;
+ default:
+ blockIdDown = GetBlockId(x, y - 1, z);
+ blockIdUp = GetBlockId(x, y + 1, z);
+ break;
+ }
+
+ switch (z) {
+ case 0:
+ blockIdNorth = GetBlockId(x, y, 1);
+ blockIdSouth = sectionSouth.GetBlockId(Vector(x, y, 15));
+ break;
+ case 15:
+ blockIdNorth = sectionNorth.GetBlockId(Vector(x, y, 0));
+ blockIdSouth = GetBlockId(x, y, 14);
+ break;
+ default:
+ blockIdNorth = GetBlockId(x, y, z + 1);
+ blockIdSouth = GetBlockId(x, y, z - 1);
+ break;
+ }
+
+ switch (x) {
+ case 0:
+ blockIdWest = GetBlockId(1, y, z);
+ blockIdEast = sectionEast.GetBlockId(Vector(15, y, z));
+ break;
+ case 15:
+ blockIdWest = sectionWest.GetBlockId(Vector(0, y, z));
+ blockIdEast = GetBlockId(14, y, z);
+ break;
+ default:
+ blockIdWest = GetBlockId(x + 1, y, z);
+ blockIdEast = GetBlockId(x - 1, y, z);
+ break;
+ }
+
+ auto blockModelDown = GetInternalBlockModel(blockIdDown);
+ auto blockModelUp = GetInternalBlockModel(blockIdUp);
+ auto blockModelNorth = GetInternalBlockModel(blockIdNorth);
+ auto blockModelSouth = GetInternalBlockModel(blockIdSouth);
+ auto blockModelWest = GetInternalBlockModel(blockIdWest);
+ auto blockModelEast = GetInternalBlockModel(blockIdEast);
+
+ value |= (blockIdDown.id != 0 && blockModelDown && blockModelDown->IsBlock) << 0;
+ value |= (blockIdUp.id != 0 && blockModelUp && blockModelUp->IsBlock) << 1;
+ value |= (blockIdNorth.id != 0 && blockModelNorth && blockModelNorth->IsBlock) << 2;
+ value |= (blockIdSouth.id != 0 && blockModelSouth && blockModelSouth->IsBlock) << 3;
+ value |= (blockIdWest.id != 0 && blockModelWest && blockModelWest->IsBlock) << 4;
+ value |= (blockIdEast.id != 0 && blockModelEast && blockModelEast->IsBlock) << 5;
+
+ arr[y * 256 + z * 16 + x] = value;
+ }
+ }
+ }
+ return arr;
+}
+
+const BlockModel* RendererSectionData::GetInternalBlockModel(const BlockId& id) {
+ for (const auto& it : idModels) {
+ if (it.first == id)
+ return it.second;
+ }
+ idModels.push_back(std::make_pair(id, AssetManager::Instance().GetBlockModelByBlockId(id)));
+ return idModels.back().second;
+}
+
+void RendererSectionData::SetBlockIdData(World* world) {
+ const Section& section = world->GetSection(sectionPos);
+
+ for (int y = 0; y < 16; y++) {
+ for (int z = 0; z < 16; z++) {
+ for (int x = 0; x < 16; x++) {
+ blockIdData[y * 256 + z * 16 + x] = section.GetBlockId(Vector(x, y, z));
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/RendererSectionData.hpp b/src/RendererSectionData.hpp
new file mode 100644
index 0000000..54b6eea
--- /dev/null
+++ b/src/RendererSectionData.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include <vector>
+#include <array>
+
+#include <glm/mat4x4.hpp>
+
+#include "Block.hpp"
+#include "Vector.hpp"
+
+class World;
+class BlockModel;
+
+struct RendererSectionData {
+ std::vector<glm::mat4> models;
+ std::vector<glm::vec4> textures;
+ std::vector<glm::vec3> colors;
+ std::vector<glm::vec2> lights;
+ size_t hash;
+ Vector sectionPos;
+
+ RendererSectionData(World *world, Vector sectionPosition);
+
+ ~RendererSectionData() = default;
+
+ RendererSectionData(RendererSectionData &&other) = default;
+private:
+
+ void AddFacesByBlockModel(const std::vector<Vector> &sectionsList, World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight, const std::array<unsigned char, 16 * 16 * 16>& visibility);
+
+ std::array<unsigned char, 16 * 16 * 16> GetBlockVisibilityData(World *world);
+
+ std::vector<std::pair<BlockId, const BlockModel *>> idModels;
+ const BlockModel* GetInternalBlockModel(const BlockId& id);
+
+ std::array<BlockId, 4096> blockIdData;
+ void SetBlockIdData(World *world);
+
+ inline const BlockId& GetBlockId(const Vector& pos) {
+ return blockIdData[pos.y * 256 + pos.z * 16 + pos.x];
+ }
+
+ inline const BlockId& GetBlockId(int x, int y, int z) {
+ return blockIdData[y * 256 + z * 16 + x];
+ }
+};
diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp
index 0d5a7c7..4f77aca 100644
--- a/src/RendererWorld.cpp
+++ b/src/RendererWorld.cpp
@@ -11,6 +11,7 @@
#include "Shader.hpp"
#include "GameState.hpp"
#include "Section.hpp"
+#include "RendererSectionData.hpp"
void RendererWorld::WorkerFunction(size_t workerId) {
EventListener tasksListener;
@@ -26,9 +27,9 @@ void RendererWorld::WorkerFunction(size_t workerId) {
if (result != sections.end()) {
if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) {
sectionsMutex.unlock();
- RendererSectionData data(&gs->world, vec);
+ auto data = std::make_unique<RendererSectionData>(&gs->world, vec);
renderDataMutex.lock();
- renderData.push(data);
+ renderData.push(std::move(data));
renderDataMutex.unlock();
EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{});
sectionsMutex.lock();
@@ -41,9 +42,9 @@ void RendererWorld::WorkerFunction(size_t workerId) {
}
else {
sectionsMutex.unlock();
- RendererSectionData data(&gs->world, vec);
+ auto data = std::make_unique<RendererSectionData>(&gs->world, vec);
renderDataMutex.lock();
- renderData.push(data);
+ renderData.push(std::move(data));
renderDataMutex.unlock();
EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{});
sectionsMutex.lock();
@@ -123,30 +124,28 @@ RendererWorld::RendererWorld(GameState* ptr) {
renderDataMutex.lock();
int i = 0;
while (!renderData.empty() && i++ < 20) {
- auto &data = renderData.front();
+ auto data = std::move(renderData.front());
+ renderData.pop();
isParsingMutex.lock();
- if (isParsing[data.sectionPos] != true)
+ if (isParsing[data->sectionPos] != true)
LOG(WARNING) << "Generated not parsed data";
- isParsing[data.sectionPos] = false;
+ isParsing[data->sectionPos] = false;
isParsingMutex.unlock();
sectionsMutex.lock();
- if (sections.find(data.sectionPos) != sections.end()) {
- if (sections.find(data.sectionPos)->second.GetHash() == data.hash) {
+ if (sections.find(data->sectionPos) != sections.end()) {
+ if (sections.find(data->sectionPos)->second.GetHash() == data->hash) {
LOG(INFO) << "Generated not necesarry RendererData";
sectionsMutex.unlock();
renderData.pop();
continue;
}
- sections.erase(sections.find(data.sectionPos));
+ sections.erase(sections.find(data->sectionPos));
}
- RendererSection renderer(data);
- sections.insert(std::make_pair(data.sectionPos, std::move(renderer)));
+ RendererSection renderer(*data);
+ sections.insert(std::make_pair(data->sectionPos, std::move(renderer)));
sectionsMutex.unlock();
- renderData.pop();
}
- if (renderData.empty())
- std::queue<RendererSectionData>().swap(renderData);
renderDataMutex.unlock();
});
diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp
index 11a659b..a961a84 100644
--- a/src/RendererWorld.hpp
+++ b/src/RendererWorld.hpp
@@ -16,6 +16,7 @@ class Texture;
class Shader;
class EventListener;
class RenderState;
+class RendererSectionData;
class RendererWorld {
//General
@@ -30,7 +31,7 @@ class RendererWorld {
std::map<Vector, bool> isParsing;
//Blocks
std::mutex renderDataMutex;
- std::queue<RendererSectionData> renderData;
+ std::queue<std::unique_ptr<RendererSectionData>> renderData;
std::vector<Vector> renderList;
std::mutex sectionsMutex;
std::map<Vector, RendererSection> sections;