From c71fd5f2312bc70eec960c2785bf26d73334d6c3 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 17 Aug 2017 20:11:52 +0500 Subject: 2017-08-17 --- src/Entity.hpp | 4 +- src/Event.hpp | 7 +- src/GameState.cpp | 2 +- src/Render.cpp | 8 +- src/RendererSection.cpp | 545 +++++++++++++++++++++++------------------------- src/RendererSection.hpp | 42 ++-- src/RendererWorld.cpp | 78 +++---- src/RendererWorld.hpp | 6 +- src/World.cpp | 4 + 9 files changed, 343 insertions(+), 353 deletions(-) diff --git a/src/Entity.hpp b/src/Entity.hpp index c818abe..279f127 100644 --- a/src/Entity.hpp +++ b/src/Entity.hpp @@ -126,8 +126,8 @@ struct Entity { unsigned int entityId = 0; double yaw = 0; double pitch = 0; - double width = 1.0; - double height = 1.0; + double width = 0.1; + double height = 0.1; glm::vec3 renderColor; int entityType=0; bool isMob=false; diff --git a/src/Event.hpp b/src/Event.hpp index f07ed57..23cc58c 100644 --- a/src/Event.hpp +++ b/src/Event.hpp @@ -39,6 +39,7 @@ enum class EventType { PlayerPosChanged, DeleteSectionRender, EntityChanged, + NewRenderDataAvailable, }; struct EchoData { @@ -150,12 +151,16 @@ struct EntityChangedData { unsigned int EntityId; }; +struct NewRenderDataAvailableData { + +}; + using EventData = std::variant; + UpdateSectionsRenderData, DeleteSectionRenderData, EntityChangedData,NewRenderDataAvailableData>; struct Event { EventType type; diff --git a/src/GameState.cpp b/src/GameState.cpp index afe1e26..025eeda 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -107,7 +107,7 @@ void GameState::UpdatePacket() entity.pitch = packet->Pitch / 256.0; entity.renderColor = glm::vec3(1, 0, 0); entity.height = 1.8; - entity.width = 0.5; + entity.width = 0.6; world.entities.push_back(entity); EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; diff --git a/src/Render.cpp b/src/Render.cpp index c44c346..4d0f4b7 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -221,8 +221,12 @@ void Render::ExecuteRenderLoop() { RenderFrame(); while (listener.IsEventsQueueIsNotEmpty()) listener.HandleEvent(); - if (renderWorld) - window->setTitle("FPS: " + std::to_string(1.0 / timer.GetRealDeltaS())); + if (renderWorld) { + world->renderDataMutex.lock(); + size_t size = world->renderData.size(); + world->renderDataMutex.unlock(); + window->setTitle("Size: " + std::to_string(size) + " FPS: " + std::to_string(1.0 / timer.GetRealDeltaS())); + } timer.Update(); } EventAgregator::PushEvent(EventType::Exit, ExitData{}); diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index a2d6825..add2d3d 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -28,102 +28,12 @@ GLuint RendererSection::VboUvs = magicUniqueConstant; std::map RendererSection::refCounterVbo; std::map RendererSection::refCounterVao; - -RendererSection::RendererSection(World *world, Vector position) : sectionPosition(position), world(world) { - if (VboVertices == magicUniqueConstant) { - glGenBuffers(1, &VboVertices); - glGenBuffers(1, &VboUvs); - - //Cube vertices - glBindBuffer(GL_ARRAY_BUFFER, VboVertices); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - //Cube UVs - glBindBuffer(GL_ARRAY_BUFFER, VboUvs); - glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); - - LOG(INFO) << "Created VBOs with vertices (" << VboVertices << ") and UVs (" << VboUvs - << ") for ordinary blocks"; - } - - glGenBuffers(1, &VboTextures); - if (refCounterVbo.find(VboTextures) == refCounterVbo.end()) - refCounterVbo[VboTextures] = 0; - refCounterVbo[VboTextures]++; - - glGenBuffers(1, &VboModels); - if (refCounterVbo.find(VboModels) == refCounterVbo.end()) - refCounterVbo[VboModels] = 0; - refCounterVbo[VboModels]++; - - glGenBuffers(1, &VboColors); - if (refCounterVbo.find(VboColors) == refCounterVbo.end()) - refCounterVbo[VboColors] = 0; - refCounterVbo[VboColors]++; - - glGenVertexArrays(1, &Vao); - if (refCounterVao.find(Vao) == refCounterVao.end()) - refCounterVao[Vao] = 0; - refCounterVao[Vao]++; - - glBindVertexArray(Vao); - { - //Cube vertices - GLuint VertAttribPos = 0; - glBindBuffer(GL_ARRAY_BUFFER, VboVertices); - glVertexAttribPointer(VertAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(VertAttribPos); - - //Cube UVs - GLuint UvAttribPos = 2; - glBindBuffer(GL_ARRAY_BUFFER, VboUvs); - glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(UvAttribPos); - - //Textures - GLuint textureAttribPos = 7; - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); - glVertexAttribPointer(textureAttribPos, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(textureAttribPos); - glVertexAttribDivisor(textureAttribPos, 1); - glCheckError(); - - //Blocks models - GLuint matAttribPos = 8; - size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); - glBindBuffer(GL_ARRAY_BUFFER, VboModels); - glVertexAttribPointer(matAttribPos + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); - glVertexAttribPointer(matAttribPos + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (1 * 4 * sizeof(GLfloat))); - glVertexAttribPointer(matAttribPos + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (2 * 4 * sizeof(GLfloat))); - glVertexAttribPointer(matAttribPos + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (3 * 4 * sizeof(GLfloat))); - glEnableVertexAttribArray(matAttribPos + 0); - glEnableVertexAttribArray(matAttribPos + 1); - glEnableVertexAttribArray(matAttribPos + 2); - glEnableVertexAttribArray(matAttribPos + 3); - glVertexAttribDivisor(matAttribPos + 0, 1); - glVertexAttribDivisor(matAttribPos + 1, 1); - glVertexAttribDivisor(matAttribPos + 2, 1); - glVertexAttribDivisor(matAttribPos + 3, 1); - - //Color - GLuint colorAttribPos = 12; - glBindBuffer(GL_ARRAY_BUFFER, VboColors); - glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(colorAttribPos); - glVertexAttribDivisor(colorAttribPos, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - glBindVertexArray(0); - glCheckError(); -} - RendererSection::~RendererSection() { refCounterVbo[VboTextures]--; refCounterVbo[VboModels]--; refCounterVbo[VboColors]--; refCounterVao[Vao]--; - /*if (refCounterVbo[VboTextures] <= 0) + if (refCounterVbo[VboTextures] <= 0) glDeleteBuffers(1, &VboTextures); if (refCounterVbo[VboModels] <= 0) @@ -132,35 +42,138 @@ RendererSection::~RendererSection() { glDeleteBuffers(1, &VboColors); if (refCounterVao[Vao] <= 0) - glDeleteVertexArrays(1, &Vao);*/ + glDeleteVertexArrays(1, &Vao); } void RendererSection::Render(RenderState &renderState) { - if (!isEnabled) return; - if (!models.empty()) { - LOG(INFO) << "Rendering unready section"; - PrepareRender(); - } renderState.SetActiveVao(Vao); glDrawArraysInstanced(GL_TRIANGLES, 0, 6, numOfFaces); glCheckError(); } -Section *RendererSection::GetSection() { - return &world->GetSection(sectionPosition); +Vector RendererSection::GetPosition() +{ + return sectionPos; +} + +size_t RendererSection::GetHash() +{ + return hash; +} + +RendererSection::RendererSection(RendererSectionData data) { + if (VboVertices == magicUniqueConstant) { + glGenBuffers(1, &VboVertices); + glGenBuffers(1, &VboUvs); + + //Cube vertices + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + //Cube UVs + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); + + LOG(INFO) << "Created VBOs with vertices (" << VboVertices << ") and UVs (" << VboUvs + << ") for faces"; + } + + glGenBuffers(1, &VboTextures); + if (refCounterVbo.find(VboTextures) == refCounterVbo.end()) + refCounterVbo[VboTextures] = 0; + refCounterVbo[VboTextures]++; + + glGenBuffers(1, &VboModels); + if (refCounterVbo.find(VboModels) == refCounterVbo.end()) + refCounterVbo[VboModels] = 0; + refCounterVbo[VboModels]++; + + glGenBuffers(1, &VboColors); + if (refCounterVbo.find(VboColors) == refCounterVbo.end()) + refCounterVbo[VboColors] = 0; + refCounterVbo[VboColors]++; + + glGenVertexArrays(1, &Vao); + if (refCounterVao.find(Vao) == refCounterVao.end()) + refCounterVao[Vao] = 0; + refCounterVao[Vao]++; + + glBindVertexArray(Vao); + { + //Cube vertices + GLuint VertAttribPos = 0; + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glVertexAttribPointer(VertAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(VertAttribPos); + + //Cube UVs + GLuint UvAttribPos = 2; + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(UvAttribPos); + + //Textures + GLuint textureAttribPos = 7; + glBindBuffer(GL_ARRAY_BUFFER, VboTextures); + glVertexAttribPointer(textureAttribPos, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(textureAttribPos); + glVertexAttribDivisor(textureAttribPos, 1); + glCheckError(); + + //Blocks models + GLuint matAttribPos = 8; + size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); + glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glVertexAttribPointer(matAttribPos + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); + glVertexAttribPointer(matAttribPos + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(1 * 4 * sizeof(GLfloat))); + glVertexAttribPointer(matAttribPos + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(2 * 4 * sizeof(GLfloat))); + glVertexAttribPointer(matAttribPos + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(3 * 4 * sizeof(GLfloat))); + glEnableVertexAttribArray(matAttribPos + 0); + glEnableVertexAttribArray(matAttribPos + 1); + glEnableVertexAttribArray(matAttribPos + 2); + glEnableVertexAttribArray(matAttribPos + 3); + glVertexAttribDivisor(matAttribPos + 0, 1); + glVertexAttribDivisor(matAttribPos + 1, 1); + glVertexAttribDivisor(matAttribPos + 2, 1); + glVertexAttribDivisor(matAttribPos + 3, 1); + + //Color + GLuint colorAttribPos = 12; + glBindBuffer(GL_ARRAY_BUFFER, VboColors); + glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(colorAttribPos); + glVertexAttribDivisor(colorAttribPos, 1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + glBindVertexArray(0); + glCheckError(); + + + //Upload data to VRAM + glBindBuffer(GL_ARRAY_BUFFER, VboTextures); + glBufferData(GL_ARRAY_BUFFER, data.textures.size() * sizeof(glm::vec4), data.textures.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glBufferData(GL_ARRAY_BUFFER, data.models.size() * sizeof(glm::mat4), data.models.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, VboColors); + glBufferData(GL_ARRAY_BUFFER, data.colors.size() * sizeof(glm::vec3), data.colors.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + numOfFaces = data.textures.size(); + sectionPos = data.sectionPos; + hash = data.hash; } RendererSection::RendererSection(const RendererSection &other) { - this->world = other.world; this->VboModels = other.VboModels; this->VboTextures = other.VboTextures; this->VboColors = other.VboColors; - this->sectionPosition = other.sectionPosition; + this->sectionPos = other.sectionPos; this->Vao = other.Vao; this->numOfFaces = other.numOfFaces; - this->models = other.models; - this->textures = other.textures; - this->colors = other.colors; this->hash = other.hash; refCounterVbo[VboTextures]++; @@ -169,179 +182,153 @@ RendererSection::RendererSection(const RendererSection &other) { refCounterVao[Vao]++; } -void RendererSection::SetEnabled(bool isEnabled) { - this->isEnabled = isEnabled; -} - -bool RendererSection::IsNeedResourcesPrepare() { - size_t currentHash = world->GetSection(sectionPosition).GetHash(); - bool isNeedUpdate = currentHash != hash; - return isNeedUpdate; -} - -void RendererSection::PrepareResources() { - const std::map &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes(); - Section §ion = world->GetSection(sectionPosition); - models.clear(); - textures.clear(); - colors.clear(); - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - Vector blockPos = Vector(x, y, z) + (sectionPosition * 16u); - Block block = world->GetBlock(blockPos); - if (block.id == 0) - continue; - - auto checkBlockVisibility = [&](Vector block) -> bool { - return section.GetBlock(block).id == 0 || - section.GetBlock(block).id == 31 || - section.GetBlock(block).id == 18; - }; - - unsigned char isVisible = 0; - if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { - isVisible = 0b1111'1111; //All faces is visible - } else { - isVisible |= checkBlockVisibility(Vector(x - 1, y, z)) << 0; - isVisible |= checkBlockVisibility(Vector(x + 1, y, z)) << 1; - isVisible |= checkBlockVisibility(Vector(x, y + 1, z)) << 2; - isVisible |= checkBlockVisibility(Vector(x, y - 1, z)) << 3; - isVisible |= checkBlockVisibility(Vector(x, y, z - 1)) << 4; - isVisible |= checkBlockVisibility(Vector(x, y, z + 1)) << 5; - } - - if (isVisible == 0x00) - continue; - - glm::mat4 transform; - transform = glm::translate(transform, glm::vec3 (sectionPosition * 16u)); - transform = glm::translate(transform, glm::vec3(x, y, z)); - glm::vec3 biomeColor(0.275, 0.63, 0.1); - glm::vec3 color(0.0f, 0.0f, 0.0f); - if (block.id == 31 || block.id == 18) - color = biomeColor; - - if (block.id == 31) { //X-cross like blocks rendering - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 2)); - for (int i = 0; i < 4; i++) { - textures.push_back(texture->second); - colors.push_back(color); - } - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0.15f, 0, 0.15f)); - faceTransform = glm::scale(faceTransform, glm::vec3(1.0f, 0.9f, 1.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0)); - for (int i = 0; i < 4; i++) { - models.push_back(faceTransform); - faceTransform = glm::translate(faceTransform, glm::vec3(0.0f, 0.0f, 0.5f)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - faceTransform = glm::translate(faceTransform, glm::vec3(0.0f, 0.0f, -0.5f)); - } - continue; - } - - if (isVisible >> 0 & 0x1) { //east side of block (X+) - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 0)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 2)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 1 & 0x1) { //west side X- - glm::mat4 faceTransform = glm::translate(transform, 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)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 3)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 2 & 0x1) { //Top side Y+ - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 1, 0)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 1)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - if (block.id != 2) - colors.push_back(color); - else - colors.push_back(biomeColor); - } - if (isVisible >> 3 & 0x1) { //Bottom side Y- - glm::mat4 faceTransform = glm::translate(transform, 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)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 0)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 4 & 0x1) { //south side Z+ - glm::mat4 faceTransform = glm::translate(transform, 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)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 3)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 5 & 0x1) { //north side Z- - glm::mat4 faceTransform = glm::translate(transform, 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)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 4)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - } - } - } - numOfFaces = textures.size(); - hash = section.GetHash(); -} - -void RendererSection::PrepareRender() { - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); - glBufferData(GL_ARRAY_BUFFER, textures.size() * sizeof(glm::vec4), textures.data(), GL_DYNAMIC_DRAW); - std::vector().swap(textures); - - glBindBuffer(GL_ARRAY_BUFFER, VboModels); - glBufferData(GL_ARRAY_BUFFER, models.size() * sizeof(glm::mat4), models.data(), GL_DYNAMIC_DRAW); - std::vector().swap(models); - - glBindBuffer(GL_ARRAY_BUFFER, VboColors); - glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_DYNAMIC_DRAW); - std::vector().swap(colors); - - glBindBuffer(GL_ARRAY_BUFFER, 0); +RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) { + const std::map &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes(); + Section §ion = world->GetSection(sectionPosition); + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + Vector blockPos = Vector(x, y, z) + (sectionPosition * 16u); + Block block = world->GetBlock(blockPos); + if (block.id == 0) + continue; + + auto checkBlockVisibility = [&](Vector block) -> bool { + return section.GetBlock(block).id == 0 || + section.GetBlock(block).id == 31 || + section.GetBlock(block).id == 18; + }; + + unsigned char isVisible = 0; + if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { + isVisible = 0b1111'1111; //All faces is visible + } else { + isVisible |= checkBlockVisibility(Vector(x - 1, y, z)) << 0; + isVisible |= checkBlockVisibility(Vector(x + 1, y, z)) << 1; + isVisible |= checkBlockVisibility(Vector(x, y + 1, z)) << 2; + isVisible |= checkBlockVisibility(Vector(x, y - 1, z)) << 3; + isVisible |= checkBlockVisibility(Vector(x, y, z - 1)) << 4; + isVisible |= checkBlockVisibility(Vector(x, y, z + 1)) << 5; + } + + if (isVisible == 0x00) + continue; + + glm::mat4 transform; + transform = glm::translate(transform, glm::vec3(sectionPosition * 16u)); + transform = glm::translate(transform, glm::vec3(x, y, z)); + glm::vec3 biomeColor(0.275, 0.63, 0.1); + glm::vec3 color(0.0f, 0.0f, 0.0f); + if (block.id == 31 || block.id == 18) + color = biomeColor; + + if (block.id == 31) { //X-cross like blocks rendering + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 2)); + for (int i = 0; i < 4; i++) { + textures.push_back(texture->second); + colors.push_back(color); + } + glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0.15f, 0, 0.15f)); + faceTransform = glm::scale(faceTransform, glm::vec3(1.0f, 0.9f, 1.0f)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); + faceTransform = glm::rotate(faceTransform, glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0)); + for (int i = 0; i < 4; i++) { + models.push_back(faceTransform); + faceTransform = glm::translate(faceTransform, glm::vec3(0.0f, 0.0f, 0.5f)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); + faceTransform = glm::translate(faceTransform, glm::vec3(0.0f, 0.0f, -0.5f)); + } + continue; + } + + if (isVisible >> 0 & 0x1) { //east side of block (X+) + glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 0)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); + models.push_back(faceTransform); + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 2)); + if (texture != textureAtlas.end()) + textures.push_back(texture->second); + else + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, + 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + colors.push_back(color); + } + if (isVisible >> 1 & 0x1) { //west side X- + glm::mat4 faceTransform = glm::translate(transform, 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)); + models.push_back(faceTransform); + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 3)); + if (texture != textureAtlas.end()) + textures.push_back(texture->second); + else + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, + 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + colors.push_back(color); + } + if (isVisible >> 2 & 0x1) { //Top side Y+ + glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 1, 0)); + models.push_back(faceTransform); + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 1)); + if (texture != textureAtlas.end()) + textures.push_back(texture->second); + else + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, + 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + if (block.id != 2) + colors.push_back(color); + else + colors.push_back(biomeColor); + } + if (isVisible >> 3 & 0x1) { //Bottom side Y- + glm::mat4 faceTransform = glm::translate(transform, 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)); + models.push_back(faceTransform); + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 0)); + if (texture != textureAtlas.end()) + textures.push_back(texture->second); + else + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, + 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + colors.push_back(color); + } + if (isVisible >> 4 & 0x1) { //south side Z+ + glm::mat4 faceTransform = glm::translate(transform, 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)); + models.push_back(faceTransform); + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 3)); + if (texture != textureAtlas.end()) + textures.push_back(texture->second); + else + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, + 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + colors.push_back(color); + } + if (isVisible >> 5 & 0x1) { //north side Z- + glm::mat4 faceTransform = glm::translate(transform, 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)); + models.push_back(faceTransform); + auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 4)); + if (texture != textureAtlas.end()) + textures.push_back(texture->second); + else + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, + 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + colors.push_back(color); + } + } + } + } + hash = section.GetHash(); + sectionPos = sectionPosition; + textures.shrink_to_fit(); + models.shrink_to_fit(); + colors.shrink_to_fit(); } diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp index 57d04d5..fe5e96b 100644 --- a/src/RendererSection.hpp +++ b/src/RendererSection.hpp @@ -13,39 +13,35 @@ #include "Vector.hpp" #include "Renderer.hpp" -class RendererSection : Renderer { - Vector sectionPosition; - World *world; - GLuint Vao, VboTextures, VboModels, VboColors; - std::vector models; - std::vector textures; - std::vector colors; +struct RendererSectionData { + std::vector models; + std::vector textures; + std::vector colors; + size_t hash; + Vector sectionPos; + + RendererSectionData(World *world, Vector sectionPosition); +}; +class RendererSection { + GLuint Vao, VboTextures, VboModels, VboColors; + static GLuint VboVertices, VboUvs; static std::map refCounterVbo; static std::map refCounterVao; - - - bool isEnabled = false; - - size_t hash = 0; + size_t hash; + Vector sectionPos; public: - RendererSection(World *world, Vector position); + RendererSection(RendererSectionData data); RendererSection(const RendererSection &other); - ~RendererSection() override; - - void Render(RenderState &renderState) override; - - void PrepareResources() override; - - void PrepareRender() override; + ~RendererSection(); - void SetEnabled(bool isEnabled); + void Render(RenderState &renderState); - Section *GetSection(); + Vector GetPosition(); - bool IsNeedResourcesPrepare() override; + size_t GetHash(); size_t numOfFaces = 0; }; \ No newline at end of file diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index c2ba3ae..08f890e 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -39,36 +39,33 @@ void RendererWorld::LoadedSectionController() { auto vec = std::get(eventData).chunkPosition; Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); - //if (playerChunk != Vector()) if ((Vector(vec.x, 0, vec.z) - playerChunk).GetLength() > MaxRenderingDistance) return; sectionsMutex.lock(); auto& result = sections.find(vec); if (result != sections.end()) { - sectionsMutex.unlock(); - if (result->second.IsNeedResourcesPrepare()) - result->second.PrepareResources(); - sectionsMutex.lock(); + if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) { + sections.erase(result); + sectionsMutex.unlock(); + RendererSectionData data(&gs->world, vec); + renderDataMutex.lock(); + renderData.push(data); + renderDataMutex.unlock(); + EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{}); + sectionsMutex.lock(); + } } else { - EventAgregator::PushEvent(EventType::CreateSectionRender, CreateSectionRenderData{ vec }); - } - sectionsMutex.unlock(); - }); - - contentListener.RegisterHandler(EventType::CreatedSectionRender, [this](EventData eventData) { - auto vec = std::get(eventData).pos; - sectionsMutex.lock(); - auto it = sections.find(vec); - if (it == sections.end()) { - LOG(ERROR) << "Created wrnog sectionRenderer"; sectionsMutex.unlock(); - return; - } - it->second.PrepareResources(); + RendererSectionData data(&gs->world, vec); + renderDataMutex.lock(); + renderData.push(data); + renderDataMutex.unlock(); + EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{}); + sectionsMutex.lock(); + } sectionsMutex.unlock(); - EventAgregator::PushEvent(EventType::InitalizeSectionRender, InitalizeSectionRenderData{ vec }); }); contentListener.RegisterHandler(EventType::PlayerPosChanged, [this,&updateAllSections](EventData eventData) { @@ -130,30 +127,7 @@ RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { MaxRenderingDistance = 2; PrepareRender(); - - listener.RegisterHandler(EventType::InitalizeSectionRender, [this](EventData eventData) { - auto data = std::get(eventData); - sectionsMutex.lock(); - auto it = sections.find(data.pos); - if (it == sections.end()) { - LOG(ERROR) << "Initializing wrong sectionRenderer"; - sectionsMutex.unlock(); - return; - } - it->second.PrepareRender(); - it->second.SetEnabled(true); - sectionsMutex.unlock(); - }); - - listener.RegisterHandler(EventType::CreateSectionRender, [this](EventData eventData) { - auto vec = std::get(eventData).pos; - auto pair = std::make_pair(vec, RendererSection(&gs->world, vec)); - sectionsMutex.lock(); - sections.insert(pair); - sectionsMutex.unlock(); - EventAgregator::PushEvent(EventType::CreatedSectionRender, CreatedSectionRenderData{ vec }); - }); - + listener.RegisterHandler(EventType::DeleteSectionRender, [this](EventData eventData) { auto vec = std::get(eventData).pos; sectionsMutex.lock(); @@ -166,6 +140,22 @@ RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { sections.erase(it); sectionsMutex.unlock(); }); + + listener.RegisterHandler(EventType::NewRenderDataAvailable,[this](EventData eventData) { + renderDataMutex.lock(); + while (!renderData.empty()) { + auto &data = renderData.front(); + auto pair = std::make_pair(data.sectionPos, RendererSection(data)); + sectionsMutex.lock(); + if (!sections.insert(pair).second) { + sections.erase(sections.find(data.sectionPos)); + sections.insert(pair); + } + sectionsMutex.unlock(); + renderData.pop(); + } + renderDataMutex.unlock(); + }); listener.RegisterHandler(EventType::EntityChanged, [this](EventData eventData) { auto data = std::get(eventData); diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index fb10c88..d339706 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -15,8 +15,9 @@ class RendererWorld: public Renderer { void LoadedSectionController(); bool isRunning = true; //Blocks + std::mutex sectionsMutex; - std::map sections; + std::map sections; Shader *blockShader; void RenderBlocks(RenderState& renderState); //Entities @@ -35,4 +36,7 @@ public: double MaxRenderingDistance; void Update(); + + std::mutex renderDataMutex; + std::queue renderData; }; \ No newline at end of file diff --git a/src/World.cpp b/src/World.cpp index 3eff5dd..dda7058 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -174,6 +174,10 @@ void World::UpdatePhysics(float delta) it.pos = it.pos + it.vel * delta; } } +//Faces: 14 650 653 +//Models: 937.641.792 Bytes x64 +//Textures: 234.410.448 Bytes x16 +//Colors: 175.807.836 Bytes x12 Entity & World::GetEntity(unsigned int EntityId) { -- cgit v1.2.3