diff options
author | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2017-11-06 14:01:19 +0100 |
---|---|---|
committer | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2018-01-13 03:39:33 +0100 |
commit | 95c85382030af78854a42d457fbb259e6078402b (patch) | |
tree | 9ed941e9ee88cc77ece824c3c7bb872a37ec7d9b | |
parent | Minor shader optimization (diff) | |
download | AltCraft-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 |
Diffstat (limited to '')
-rw-r--r-- | src/RendererSection.cpp | 300 | ||||
-rw-r--r-- | src/RendererSection.hpp | 41 | ||||
-rw-r--r-- | src/RendererSectionData.cpp | 300 | ||||
-rw-r--r-- | src/RendererSectionData.hpp | 46 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 29 | ||||
-rw-r--r-- | src/RendererWorld.hpp | 3 |
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 §ion = 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> §ionsList, 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> §ionsList, 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 §ion = 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> §ionsList, 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> §ionsList, 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; |