diff options
author | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2017-08-18 17:13:01 +0200 |
---|---|---|
committer | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2017-08-18 17:13:01 +0200 |
commit | a2fe2786682e626dae25db2d375280c83b615796 (patch) | |
tree | 34bc8295ad75b967519959e6300aada5531e2345 /src/RendererWorld.cpp | |
parent | 2017-08-17 (diff) | |
download | AltCraft-a2fe2786682e626dae25db2d375280c83b615796.tar AltCraft-a2fe2786682e626dae25db2d375280c83b615796.tar.gz AltCraft-a2fe2786682e626dae25db2d375280c83b615796.tar.bz2 AltCraft-a2fe2786682e626dae25db2d375280c83b615796.tar.lz AltCraft-a2fe2786682e626dae25db2d375280c83b615796.tar.xz AltCraft-a2fe2786682e626dae25db2d375280c83b615796.tar.zst AltCraft-a2fe2786682e626dae25db2d375280c83b615796.zip |
Diffstat (limited to 'src/RendererWorld.cpp')
-rw-r--r-- | src/RendererWorld.cpp | 182 |
1 files changed, 165 insertions, 17 deletions
diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 08f890e..61c2afa 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -6,7 +6,8 @@ void RendererWorld::LoadedSectionController() { Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); std::vector<Vector> suitableChunks; - for (auto& it : gs->world.GetSectionsList()) { + auto chunks = gs->world.GetSectionsList(); + for (auto& it : chunks) { double distance = (Vector(it.x, 0, it.z) - playerChunk).GetLength(); if (distance > MaxRenderingDistance) continue; @@ -46,7 +47,6 @@ void RendererWorld::LoadedSectionController() { auto& result = sections.find(vec); if (result != sections.end()) { if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) { - sections.erase(result); sectionsMutex.unlock(); RendererSectionData data(&gs->world, vec); renderDataMutex.lock(); @@ -70,7 +70,7 @@ void RendererWorld::LoadedSectionController() { contentListener.RegisterHandler(EventType::PlayerPosChanged, [this,&updateAllSections](EventData eventData) { auto pos = std::get<PlayerPosChangedData>(eventData).newPos; - updateAllSections(pos); + updateAllSections(Vector(pos.x,pos.y,pos.z)); }); contentListener.RegisterHandler(EventType::UpdateSectionsRender, [this,&updateAllSections](EventData eventData) { @@ -91,6 +91,50 @@ void RendererWorld::LoadedSectionController() { } } +/*void RendererWorld::WorkerFunction(size_t workerId) { + EventListener tasksListener; + + tasksListener.RegisterHandler(EventType::RendererWorkerTask, [&](EventData eventData) { + auto data = std::get<RendererWorkerTaskData>(eventData); + if (data.WorkerId != workerId) + return; + Vector vec = data.Task; + + sectionsMutex.lock(); + auto& result = sections.find(vec); + if (result != sections.end()) { + if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) { + sectionsMutex.unlock(); + RendererSectionData data(&gs->world, vec); + renderDataMutex.lock(); + renderData.push(data); + renderDataMutex.unlock(); + EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{}); + sectionsMutex.lock(); + } + } + else { + sectionsMutex.unlock(); + RendererSectionData data(&gs->world, vec); + renderDataMutex.lock(); + renderData.push(data); + renderDataMutex.unlock(); + EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{}); + sectionsMutex.lock(); + } + sectionsMutex.unlock(); + LOG(INFO) << "Task " << vec << " done in " << workerId; + + }); + + LoopExecutionTimeController timer(std::chrono::milliseconds(50)); + while (isRunning) { + while (tasksListener.IsEventsQueueIsNotEmpty()) + tasksListener.HandleEvent(); + timer.Update(); + } +}*/ + void RendererWorld::RenderBlocks(RenderState& renderState) { renderState.SetActiveShader(blockShader->Program); @@ -124,7 +168,7 @@ void RendererWorld::RenderEntities(RenderState& renderState) } RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { - MaxRenderingDistance = 2; + MaxRenderingDistance = 15; PrepareRender(); @@ -144,30 +188,70 @@ RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { 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)); + auto &data = renderData.front(); sectionsMutex.lock(); - if (!sections.insert(pair).second) { + 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.insert(pair); } + RendererSection renderer(data); + sections.insert(std::make_pair(data.sectionPos, renderer)); sectionsMutex.unlock(); renderData.pop(); } renderDataMutex.unlock(); + + /*sectionsMutex.lock(); + renderList.clear(); + for (auto& it : sections) { + renderList.push_back(it.first); + } + sectionsMutex.unlock(); + std::sort(renderList.begin(), renderList.end(), [&](Vector lhs, Vector rhs) { + VectorF playerPos(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ); + VectorF left = VectorF(lhs.x, lhs.y, lhs.z) * 16 - playerPos; + VectorF right = VectorF(rhs.x, rhs.y, rhs.z) * 16 - playerPos; + return left.GetLength() > right.GetLength(); + });*/ }); listener.RegisterHandler(EventType::EntityChanged, [this](EventData eventData) { auto data = std::get<EntityChangedData>(eventData); - for (auto&it : gs->world.entities) { - if (it.entityId == data.EntityId) { - entities.push_back(RendererEntity(&gs->world,it.entityId)); - return; + for (unsigned int entityId : gs->world.GetEntitiesList()) { + if (entityId == data.EntityId) { + entities.push_back(RendererEntity(&gs->world, entityId)); } } }); + /*listener.RegisterHandler(EventType::ChunkChanged, [this](EventData eventData) { + auto vec = std::get<ChunkChangedData>(eventData).chunkPosition; + Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); + + double distanceToChunk = (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); + if (distanceToChunk > MaxRenderingDistance) { + //LOG(WARNING) << (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); + //LOG(WARNING) << distanceToChunk; + return; + } + + EventAgregator::PushEvent(EventType::RendererWorkerTask, RendererWorkerTaskData{ currentWorker++,vec }); + if (currentWorker > numOfWorkers) + currentWorker = 0; + LOG(INFO) << "New task " << vec << " for " << currentWorker; + }); + + for (int i = 0; i < numOfWorkers; i++) + workers[i] = std::thread(&RendererWorld::WorkerFunction, this, i);*/ + resourceLoader = std::thread(&RendererWorld::LoadedSectionController, this); + + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } RendererWorld::~RendererWorld() { @@ -179,6 +263,8 @@ RendererWorld::~RendererWorld() { sectionsMutex.unlock(); LOG(INFO) << "Total faces to render: "<<faces; isRunning = false; + /*for (int i = 0; i < numOfWorkers; i++) + workers[i].join();*/ resourceLoader.join(); delete blockShader; delete entityShader; @@ -198,13 +284,73 @@ void RendererWorld::Render(RenderState & renderState) { glUniform2f(windowSizeLoc, renderState.WindowWidth, renderState.WindowHeight); glCheckError(); - sectionsMutex.lock(); - for (auto& it : sections) { + /*for (auto& pos : renderList) { + std::vector<Vector> sectionCorners = { + Vector(0, 0, 0), + Vector(0, 0, 16), + Vector(0, 16, 0), + Vector(0, 16, 16), + Vector(16, 0, 0), + Vector(16, 0, 16), + Vector(16, 16, 0), + Vector(16, 16, 16), + }; + bool isBreak = true; + glm::mat4 vp = projection * view; + for (auto &it : sectionCorners) { + glm::vec3 point(pos.x * 16 + it.x, pos.y * 16 + it.y, pos.z * 16 + it.z); + glm::vec4 p = vp * glm::vec4(point, 1); + glm::vec3 res = glm::vec3(p) / p.w; + if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { + isBreak = false; + break; + } + } + double lengthToSection = (VectorF(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ) - VectorF(pos.x * 16, pos.y * 16, pos.z * 16)).GetLength(); - it.second.Render(renderState); + if (isBreak && lengthToSection > 30.0f) { + continue; + } + + sections.find(pos)->second.Render(renderState); + }*/ + sectionsMutex.lock(); + for (auto& section : sections) { + sectionsMutex.unlock(); + std::vector<Vector> sectionCorners = { + Vector(0, 0, 0), + Vector(0, 0, 16), + Vector(0, 16, 0), + Vector(0, 16, 16), + Vector(16, 0, 0), + Vector(16, 0, 16), + Vector(16, 16, 0), + Vector(16, 16, 16), + }; + bool isBreak = true; + glm::mat4 vp = projection * view; + for (auto &it : sectionCorners) { + glm::vec3 point(section.second.GetPosition().x * 16 + it.x, + section.second.GetPosition().y * 16 + it.y, + section.second.GetPosition().z * 16 + it.z); + glm::vec4 p = vp * glm::vec4(point, 1); + glm::vec3 res = glm::vec3(p) / p.w; + if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { + isBreak = false; + break; + } + } + double lengthToSection = (VectorF(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ) - VectorF(section.first.x*16,section.first.y*16,section.first.z*16)).GetLength(); + + if (isBreak && lengthToSection > 30.0f) { + sectionsMutex.lock(); + continue; + } + section.second.Render(renderState); + sectionsMutex.lock(); } sectionsMutex.unlock(); - + glCheckError(); renderState.SetActiveShader(entityShader->Program); glCheckError(); @@ -231,6 +377,7 @@ void RendererWorld::PrepareRender() { blockShader = new Shader("./shaders/face.vs", "./shaders/face.fs"); blockShader->Use(); glUniform1i(glGetUniformLocation(blockShader->Program, "textureAtlas"), 0); + entityShader = new Shader("./shaders/entity.vs", "./shaders/entity.fs"); } @@ -240,5 +387,6 @@ bool RendererWorld::IsNeedResourcesPrepare() { } void RendererWorld::Update() { - listener.HandleEvent(); + while (listener.IsEventsQueueIsNotEmpty()) + listener.HandleEvent(); } |