From dee50239be8fff566b3ca687bc70900b391a8164 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Wed, 16 Aug 2017 20:11:07 +0500 Subject: 2017-08-16 --- CMakeLists.txt | 2 +- RenderSection.cpp | 281 ++++++++++++++++++++++++++++++++++++++++++++++++ cwd/shaders/entity.fs | 9 ++ cwd/shaders/entity.vs | 13 +++ src/Entity.cpp | 78 ++++++++++++++ src/Entity.hpp | 138 ++++++++++++++++++++++-- src/Event.hpp | 8 +- src/FSM.cpp | 1 - src/FSM.hpp | 36 ------- src/GameState.cpp | 94 +++++++++++++--- src/Network.cpp | 14 +-- src/Packet.hpp | 200 +++++++++++++++++++++++++++++++++- src/Render.cpp | 9 +- src/RendererEntity.cpp | 161 +++++++++++++++++++++++++++ src/RendererEntity.hpp | 25 +++++ src/RendererSection.cpp | 11 +- src/RendererSection.hpp | 6 +- src/RendererWorld.cpp | 134 +++++++++++++++++++---- src/RendererWorld.hpp | 16 ++- src/Stream.cpp | 4 +- src/ThreadGame.cpp | 4 +- src/Utility.cpp | 2 +- src/World.cpp | 33 ++++++ src/World.hpp | 6 ++ 24 files changed, 1178 insertions(+), 107 deletions(-) create mode 100644 RenderSection.cpp create mode 100644 cwd/shaders/entity.fs create mode 100644 cwd/shaders/entity.vs delete mode 100644 src/FSM.cpp delete mode 100644 src/FSM.hpp create mode 100644 src/RendererEntity.cpp create mode 100644 src/RendererEntity.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index aa172f4..5655cd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(externalProject) file(GLOB_RECURSE SOURCES "./src/*.cpp") file(GLOB_RECURSE HEADERS "./src/*.hpp") -add_executable(AltCraft ${HEADERS} ${SOURCES} src/Utility.cpp src/Render.cpp src/Render.hpp src/RendererWorld.cpp src/RendererWorld.hpp src/Renderer.cpp src/Renderer.hpp src/Thread.cpp src/Thread.hpp src/ThreadGame.cpp src/ThreadGame.hpp src/ThreadRender.cpp src/ThreadRender.hpp src/ThreadNetwork.cpp src/ThreadNetwork.hpp src/FSM.cpp src/FSM.hpp) +add_executable(AltCraft ${HEADERS} ${SOURCES}) ################ # CONFIGURATION diff --git a/RenderSection.cpp b/RenderSection.cpp new file mode 100644 index 0000000..fec67b5 --- /dev/null +++ b/RenderSection.cpp @@ -0,0 +1,281 @@ +#include + +const GLfloat vertices[] = { + //Z+ edge + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + + //Z- edge + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + + //X+ edge + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + //X- edge + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + + //Y+ edge + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + + //Y- edge + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, +}; + +const GLfloat uv_coords[] = { + //Z+ + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Z- + 1.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + + //X+ + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //X- + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Y+ + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Y- + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, +}; + +void RenderState::SetActiveVao(GLuint Vao) { + if (Vao != ActiveVao) { + glBindVertexArray(Vao); + ActiveVao = Vao; + } +} + +void RenderState::SetActiveShader(GLuint Shader) { + if (Shader != ActiveShader) { + glUseProgram(Shader); + ActiveShader = Shader; + } +} + +const GLuint magicUniqueConstant = 88375; +GLuint RenderSection::VboVertices = magicUniqueConstant; +GLuint RenderSection::VboUvs = magicUniqueConstant; +std::map RenderSection::refCounterVbo; +std::map RenderSection::refCounterVao; + + +RenderSection::RenderSection(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, &VboBlocks); + if (refCounterVbo.find(VboBlocks) == refCounterVbo.end()) + refCounterVbo[VboBlocks] = 0; + refCounterVbo[VboBlocks]++; + + glGenBuffers(1, &VboModels); + if (refCounterVbo.find(VboModels) == refCounterVbo.end()) + refCounterVbo[VboModels] = 0; + refCounterVbo[VboModels]++; + + glGenVertexArrays(1, &Vao); + if (refCounterVao.find(Vao) == refCounterVao.end()) + refCounterVao[Vao] = 0; + refCounterVao[Vao]++; + + glBindVertexArray(Vao); + { + //Cube vertices + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(0); + + //Cube UVs + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(2); + + //Blocks ids + glBindBuffer(GL_ARRAY_BUFFER, VboBlocks); + glVertexAttribPointer(7, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(7); + glVertexAttribDivisor(7, 1); + glCheckError(); + + //Blocks models + size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); + glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glVertexAttribPointer(8 + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); + glVertexAttribPointer(8 + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (1 * 4 * sizeof(GLfloat))); + glVertexAttribPointer(8 + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (2 * 4 * sizeof(GLfloat))); + glVertexAttribPointer(8 + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (3 * 4 * sizeof(GLfloat))); + glEnableVertexAttribArray(8 + 0); + glEnableVertexAttribArray(8 + 1); + glEnableVertexAttribArray(8 + 2); + glEnableVertexAttribArray(8 + 3); + glVertexAttribDivisor(8 + 0, 1); + glVertexAttribDivisor(8 + 1, 1); + glVertexAttribDivisor(8 + 2, 1); + glVertexAttribDivisor(8 + 3, 1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + glBindVertexArray(0); + UpdateState(); + glCheckError(); +} + +RenderSection::~RenderSection() { + refCounterVbo[VboBlocks]--; + refCounterVbo[VboModels]--; + refCounterVao[Vao]--; + if (refCounterVbo[VboBlocks] <= 0) + glDeleteBuffers(1, &VboBlocks); + if (refCounterVbo[VboModels] <= 0) + glDeleteBuffers(1, &VboBlocks); + if (refCounterVao[Vao] <= 0) + glDeleteVertexArrays(1, &Vao); +} + +void RenderSection::UpdateState() { + Section *section = &world->sections.find(sectionPosition)->second; + std::vector models; + std::vector blocks; + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + Block block = section->GetBlock(Vector(x, y, z)); + if (block.id == 0) + continue; + + unsigned char isVisible = 0; + if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { + isVisible = 0; + } else { + isVisible |= (section->GetBlock(Vector(x + 1, y, z)).id != 0) << 0; + isVisible |= (section->GetBlock(Vector(x - 1, y, z)).id != 0) << 1; + isVisible |= (section->GetBlock(Vector(x, y + 1, z)).id != 0) << 2; + isVisible |= (section->GetBlock(Vector(x, y - 1, z)).id != 0) << 3; + isVisible |= (section->GetBlock(Vector(x, y, z + 1)).id != 0) << 4; + isVisible |= (section->GetBlock(Vector(x, y, z - 1)).id != 0) << 5; + } + if (isVisible == 0x3F) + continue; + + glm::vec2 data(block.id, block.state); + blocks.push_back(data); + glm::mat4 model; + model = glm::translate(model, glm::vec3(section->GetPosition().GetX() * 16, + section->GetPosition().GetY() * 16, + section->GetPosition().GetZ() * 16)); + model = glm::translate(model, glm::vec3(x, y, z)); + double size = 0.999; + model = glm::scale(model, glm::vec3(size, size, size)); + models.push_back(model); + } + } + } + glBindBuffer(GL_ARRAY_BUFFER, VboBlocks); + glBufferData(GL_ARRAY_BUFFER, blocks.size() * sizeof(glm::vec2), blocks.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glBufferData(GL_ARRAY_BUFFER, models.size() * sizeof(glm::mat4), models.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + numOfBlocks = blocks.size(); +} + +void RenderSection::Render(RenderState &state) { + state.SetActiveVao(Vao); + glDrawArraysInstanced(GL_TRIANGLES, 0, 36, numOfBlocks); + glCheckError(); +} + +Section *RenderSection::GetSection() { + return &world->sections.find(sectionPosition)->second; +} + +RenderSection::RenderSection(const RenderSection &other) { + this->world = other.world; + this->VboModels = other.VboModels; + this->VboBlocks = other.VboBlocks; + this->sectionPosition = other.sectionPosition; + this->Vao = other.Vao; + this->numOfBlocks = other.numOfBlocks; + + refCounterVbo[VboBlocks]++; + refCounterVbo[VboModels]++; + refCounterVao[Vao]++; +} diff --git a/cwd/shaders/entity.fs b/cwd/shaders/entity.fs new file mode 100644 index 0000000..6935d1b --- /dev/null +++ b/cwd/shaders/entity.fs @@ -0,0 +1,9 @@ +#version 330 core + +uniform vec3 color; +in vec2 uvPos; + +void main(){ + if (uvPos.x < 0.9 && uvPos.x > 0.1 && uvPos.y < 0.9 && uvPos.y > 0.1) discard; + gl_FragColor = vec4(color,1); +} \ No newline at end of file diff --git a/cwd/shaders/entity.vs b/cwd/shaders/entity.vs new file mode 100644 index 0000000..baa25e5 --- /dev/null +++ b/cwd/shaders/entity.vs @@ -0,0 +1,13 @@ +#version 330 core + +uniform mat4 view; +uniform mat4 projection; +uniform mat4 model; +layout (location = 0) in vec3 position; +layout (location = 1) in vec2 uvPosition; +out vec2 uvPos; + +void main(){ + uvPos = uvPosition; + gl_Position = projection*view*model*vec4(position,1); +} \ No newline at end of file diff --git a/src/Entity.cpp b/src/Entity.cpp index 8f76818..cdfd85d 100644 --- a/src/Entity.cpp +++ b/src/Entity.cpp @@ -6,3 +6,81 @@ VectorF Entity::DecodeVelocity(short x, short y, short z) const double velMod = 1 / 8000.0; return VectorF(x * velMod * ticksPerSecond, y*velMod*ticksPerSecond, z*velMod*ticksPerSecond); } + +VectorF Entity::DecodeDeltaPos(short deltaX, short deltaY, short deltaZ) +{ + const double posMod = 4096.0; + return VectorF(deltaX / posMod, deltaY / posMod, deltaZ / posMod); +} + +Entity CreateObject(ObjectType type) +{ + Entity entity; + entity.isMob = false; + switch (type) { + case ObjectType::Boat: + break; + case ObjectType::ItemStack: + entity.width = 0.25; + entity.height = 0.25; + break; + case ObjectType::AreaEffectCloud: + break; + case ObjectType::Minecart: + break; + case ObjectType::ActivatedTNT: + break; + case ObjectType::EnderCrystal: + break; + case ObjectType::TippedArrow: + break; + case ObjectType::Snowball: + break; + case ObjectType::Egg: + break; + case ObjectType::FireBall: + break; + case ObjectType::FireCharge: + break; + case ObjectType::ThrownEnderpearl: + break; + case ObjectType::WitherSkull: + break; + case ObjectType::ShulkerBullet: + break; + case ObjectType::LlamaSpit: + break; + case ObjectType::FallingObjects: + break; + case ObjectType::Itemframes: + break; + case ObjectType::EyeOfEnder: + break; + case ObjectType::ThrownPotion: + break; + case ObjectType::ThrownExpBottle: + break; + case ObjectType::FireworkRocket: + break; + case ObjectType::LeashKnot: + break; + case ObjectType::ArmorStand: + break; + case ObjectType::EvocationFangs: + break; + case ObjectType::FishingHook: + break; + case ObjectType::SpectralArrow: + break; + case ObjectType::DragonFireball: + break; + default: + break; + } + return entity; +} + +Entity CreateMob(MobType type) +{ + return Entity(); +} diff --git a/src/Entity.hpp b/src/Entity.hpp index 6df7983..c818abe 100644 --- a/src/Entity.hpp +++ b/src/Entity.hpp @@ -3,12 +3,138 @@ #include "Utility.hpp" #include "Vector.hpp" +enum class ObjectType{ + Boat=1, + ItemStack, + AreaEffectCloud, + Minecart=10, + ActivatedTNT=50, + EnderCrystal, + TippedArrow=60, + Snowball, + Egg, + FireBall, + FireCharge, + ThrownEnderpearl, + WitherSkull, + ShulkerBullet, + LlamaSpit, + FallingObjects=70, + Itemframes, + EyeOfEnder, + ThrownPotion, + ThrownExpBottle=75, + FireworkRocket, + LeashKnot, + ArmorStand, + EvocationFangs, + FishingHook=90, + SpectralArrow, + DragonFireball=93, +}; + +enum MobType { + Item = 1, + XPOrb, + AreaEffectCloud, + ElderGuardian, + WitherSkeleton, + Stray, + ThrownEgg, + LeashKnot, + Painting, + Arrow, + Snowball, + Fireball, + SmallFireball, + ThrownEnderpearl, + EyeOfEnderSignal, + ThrownPotion, + ThrownExpBottle, + ItemFrame, + WitherSkull, + PrimedTnt, + FallingSand, + FireworksRocketEntity, + Husk, + SpectralArrow, + ShulkerBullet, + DragonFireball, + ZombieVillager, + SkeletonHorse, + ZombieHorse, + ArmorStand, + Donkey, + Mule, + EvocationFangs, + EvocationIllager, + Vex, + VindicationIllager, + IllusionIllager, + MinecartCommandBlock=40, + Boat, + MinecartRideable, + MinecartChest, + MinecartFurnace, + MinecartTNT, + MinecartHopper, + MinecartSpawner, + Creeper=50, + Skeleton, + Spider, + Giant, + Zombie, + Slime, + Ghast, + PigZombie, + Enderman, + CaveSpider, + Silverfish, + Blaze, + LavaSlime, + EnderDragon, + WitherBoss, + Bat, + Witch, + Endermite, + Guardian, + Shulker, + Pig=90, + Sheep, + Cow, + Chicken, + Squid, + Wolf, + MushroomCow, + SnowMan, + Ozelot, + VillagerGolem, + Horse, + Rabbit, + PolarBear, + Llama, + LlamaSpit, + Parrot, + Villager=120, + EnderCrystal=200, +}; + struct Entity { Uuid uuid; - VectorF pos; - VectorF vel; - unsigned int entityId; - double yaw; - double pitch; + VectorF pos = 0; + VectorF vel = 0; + unsigned int entityId = 0; + double yaw = 0; + double pitch = 0; + double width = 1.0; + double height = 1.0; + glm::vec3 renderColor; + int entityType=0; + bool isMob=false; static VectorF DecodeVelocity(short x, short y, short z); -}; \ No newline at end of file + static VectorF DecodeDeltaPos(short deltaX, short deltaY, short deltaZ); +}; + +Entity CreateObject(ObjectType type); + +Entity CreateMob(MobType type); \ No newline at end of file diff --git a/src/Event.hpp b/src/Event.hpp index 232e6f2..f07ed57 100644 --- a/src/Event.hpp +++ b/src/Event.hpp @@ -13,7 +13,6 @@ #include "Vector.hpp" #include "Packet.hpp" -#include "FSM.hpp" enum class EventType { Echo, @@ -39,6 +38,7 @@ enum class EventType { CreatedSectionRender, PlayerPosChanged, DeleteSectionRender, + EntityChanged, }; struct EchoData { @@ -146,12 +146,16 @@ struct DeleteSectionRenderData { Vector pos; }; +struct EntityChangedData { + unsigned int EntityId; +}; + using EventData = std::variant; + UpdateSectionsRenderData, DeleteSectionRenderData, EntityChangedData>; struct Event { EventType type; diff --git a/src/FSM.cpp b/src/FSM.cpp deleted file mode 100644 index 6614c58..0000000 --- a/src/FSM.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "FSM.hpp" diff --git a/src/FSM.hpp b/src/FSM.hpp deleted file mode 100644 index 346d0f0..0000000 --- a/src/FSM.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include - -template -class FSM { -public: - using Transaction = std::pair; - using Handler = std::function; - - FSM(T initialState) : state(initialState), previousState(initialState) {} - - ~FSM() = default; - - void Update() { - auto &handler = handlers[Transaction{previousState, state}]; - if (handler) - handler(state); - previousState = state; - } - - void RegisterHandler(T state, Handler handler) { - handlers[Transaction{state, state}] = handler; - } - - void RegisterTransactionHandler(Transaction transaction, Handler handler) { - handlers[transaction] = handler; - } - -private: - T previousState; - T state; - std::map handlers; -}; \ No newline at end of file diff --git a/src/GameState.cpp b/src/GameState.cpp index 18ea722..afe1e26 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -61,31 +61,57 @@ void GameState::UpdatePacket() { //Packet handling auto ptr = nc->ReceivePacket(); - if (ptr) { + while (ptr) { switch ((PacketNamePlayCB)ptr->GetPacketId()) { case SpawnObject: { auto packet = std::static_pointer_cast(ptr); - Entity entity; + Entity entity = CreateObject(static_cast(packet->Type)); entity.entityId = packet->EntityId; - entity.pitch = packet->Pitch; entity.pos = VectorF(packet->X, packet->Y, packet->Z); entity.uuid = packet->ObjectUuid; entity.vel = Entity::DecodeVelocity(packet->VelocityX, packet->VelocityY, packet->VelocityZ); - entity.yaw = packet->Yaw; - if (entity.vel != VectorF()) - world.entities.push_back(entity); + entity.yaw = packet->Yaw / 256.0; + entity.pitch = packet->Pitch / 256.0; + entity.renderColor = glm::vec3(0,1,0); + world.entities.push_back(entity); + EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; - } + } case SpawnExperienceOrb: break; case SpawnGlobalEntity: break; - case SpawnMob: + case SpawnMob: { + auto packet = std::static_pointer_cast(ptr); + Entity entity; + entity.entityId = packet->EntityId; + entity.pos = VectorF(packet->X, packet->Y, packet->Z); + entity.uuid = packet->ObjectUuid; + entity.vel = Entity::DecodeVelocity(packet->VelocityX, packet->VelocityY, packet->VelocityZ); + entity.yaw = packet->Yaw / 256.0; + entity.pitch = packet->Pitch / 256.0; + entity.renderColor = glm::vec3(0,0,1); + world.entities.push_back(entity); + EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; + } case SpawnPainting: break; - case SpawnPlayer: + case SpawnPlayer: { + auto packet = std::static_pointer_cast(ptr); + Entity entity; + entity.entityId = packet->EntityId; + entity.pos = VectorF(packet->X, packet->Y, packet->Z); + entity.uuid = packet->PlayerUuid; + entity.yaw = packet->Yaw / 256.0; + entity.pitch = packet->Pitch / 256.0; + entity.renderColor = glm::vec3(1, 0, 0); + entity.height = 1.8; + entity.width = 0.5; + world.entities.push_back(entity); + EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; + } case AnimationCB: break; case Statistics: @@ -168,12 +194,30 @@ void GameState::UpdatePacket() } case Map: break; - case EntityRelativeMove: + case EntityRelativeMove: { + auto packet = std::static_pointer_cast(ptr); + Entity& entity = world.GetEntity(packet->EntityId); + entity.pos = entity.pos + Entity::DecodeDeltaPos(packet->DeltaX, packet->DeltaY, packet->DeltaZ); + if (entity.entityId != 0) + LOG(INFO) << "M: " << packet->EntityId; break; - case EntityLookAndRelativeMove: + } + case EntityLookAndRelativeMove: { + auto packet = std::static_pointer_cast(ptr); + Entity& entity = world.GetEntity(packet->EntityId); + entity.pos = entity.pos + Entity::DecodeDeltaPos(packet->DeltaX, packet->DeltaY, packet->DeltaZ); + entity.pitch = packet->Pitch / 256.0; + entity.yaw = packet->Yaw / 256.0; break; - case EntityLook: + } + case EntityLook: { + auto packet = std::static_pointer_cast(ptr); + Entity& entity = world.GetEntity(packet->EntityId); + entity.pitch = packet->Pitch / 256.0; + entity.yaw = packet->Yaw / 256.0; + //LOG(INFO) << "L: " << packet->EntityId; break; + } case EntityCB: break; case VehicleMove: @@ -245,8 +289,17 @@ void GameState::UpdatePacket() break; case UnlockRecipes: break; - case DestroyEntities: + case DestroyEntities: { + auto packet = std::static_pointer_cast(ptr); + for (auto& entityId : packet->EntityIds) { + auto it = world.entities.begin(); + while (it != world.entities.end() && it->entityId != entityId) + ++it; + if (it != world.entities.end()) + world.entities.erase(it); + } break; + } case RemoveEntityEffect: break; case ResourcePackSend: @@ -269,8 +322,12 @@ void GameState::UpdatePacket() break; case AttachEntity: break; - case EntityVelocity: + case EntityVelocity: { + auto packet = std::static_pointer_cast(ptr); + Entity& entity = world.GetEntity(packet->EntityId); + entity.vel = Entity::DecodeVelocity(packet->VelocityX, packet->VelocityY, packet->VelocityZ); break; + } case EntityEquipment: break; case SetExperience: @@ -309,8 +366,14 @@ void GameState::UpdatePacket() break; case CollectItem: break; - case EntityTeleport: + case EntityTeleport: { + auto packet = std::static_pointer_cast(ptr); + Entity& entity = world.GetEntity(packet->EntityId); + entity.pos = VectorF(packet->X, packet->Y, packet->Z); + entity.pitch = packet->Pitch / 256.0; + entity.yaw = packet->Yaw / 256.0; break; + } case Advancements: break; case EntityProperties: @@ -318,6 +381,7 @@ void GameState::UpdatePacket() case EntityEffect: break; } + ptr = nc->ReceivePacket(); } } diff --git a/src/Network.cpp b/src/Network.cpp index e70cce9..789e650 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -75,11 +75,11 @@ std::shared_ptr Network::ParsePacketPlay(PacketNamePlayCB id) { case SpawnGlobalEntity: break; case SpawnMob: - break; + return std::make_shared(); case SpawnPainting: break; case SpawnPlayer: - break; + return std::make_shared(); case AnimationCB: break; case Statistics: @@ -143,11 +143,11 @@ std::shared_ptr Network::ParsePacketPlay(PacketNamePlayCB id) { case Map: break; case EntityRelativeMove: - break; + return std::make_shared(); case EntityLookAndRelativeMove: - break; + return std::make_shared(); case EntityLook: - break; + return std::make_shared(); case EntityCB: break; case VehicleMove: @@ -165,7 +165,7 @@ std::shared_ptr Network::ParsePacketPlay(PacketNamePlayCB id) { case UseBed: break; case DestroyEntities: - break; + return std::make_shared(); case RemoveEntityEffect: break; case ResourcePackSend: @@ -187,6 +187,7 @@ std::shared_ptr Network::ParsePacketPlay(PacketNamePlayCB id) { case AttachEntity: break; case EntityVelocity: + return std::make_shared(); break; case EntityEquipment: break; @@ -215,6 +216,7 @@ std::shared_ptr Network::ParsePacketPlay(PacketNamePlayCB id) { case CollectItem: break; case EntityTeleport: + return std::make_shared(); break; case EntityProperties: break; diff --git a/src/Packet.hpp b/src/Packet.hpp index f48088d..c499720 100644 --- a/src/Packet.hpp +++ b/src/Packet.hpp @@ -9,7 +9,7 @@ enum PacketNameLoginSB { EncryptionResponse = 0x01, }; enum PacketNamePlaySB { - TeleportConfirm, + TeleportConfirm = 0x00, PrepareCraftingGrid, TabCompleteSB, ChatMessageSB, @@ -553,4 +553,202 @@ struct PacketSpawnObject : Packet { short VelocityX; short VelocityY; short VelocityZ; +}; + +struct PacketEntityRelativeMove : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + DeltaX = stream->ReadShort(); + DeltaY = stream->ReadShort(); + DeltaZ = stream->ReadShort(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlayCB::EntityRelativeMove; + } + + int EntityId; + short DeltaX, DeltaY, DeltaZ; + bool OnGround; +}; + +struct PacketEntityLookAndRelativeMove : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + DeltaX = stream->ReadShort(); + DeltaY = stream->ReadShort(); + DeltaZ = stream->ReadShort(); + return; + //TODO: WTF? + Yaw = stream->ReadAngle(); + Pitch = stream->ReadAngle(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlayCB::EntityLookAndRelativeMove; + } + + int EntityId; + short DeltaX, DeltaY, DeltaZ; + unsigned char Yaw, Pitch; + bool OnGround; +}; + +struct PacketEntityLook : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + Yaw = stream->ReadAngle(); + Pitch = stream->ReadAngle(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlayCB::EntityLook; + } + + int EntityId; + unsigned char Yaw, Pitch; + bool OnGround; +}; + +struct PacketEntityVelocity : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + VelocityX = stream->ReadShort(); + VelocityY = stream->ReadShort(); + VelocityZ = stream->ReadShort(); + } + + int GetPacketId() override { + return PacketNamePlayCB::EntityVelocity; + } + + int EntityId; + short VelocityX; + short VelocityY; + short VelocityZ; +}; + +struct PacketEntityTeleport : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + X = stream->ReadDouble(); + Y = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadAngle(); + Pitch = stream->ReadAngle(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlayCB::EntityTeleport; + } + + int EntityId; + double X, Y, Z; + unsigned char Yaw, Pitch; + bool OnGround; +}; + +struct PacketSpawnPlayer : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + PlayerUuid = stream->ReadUuid(); + X = stream->ReadDouble(); + Y = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadAngle(); + Pitch = stream->ReadAngle(); + } + + int GetPacketId() override { + return PacketNamePlayCB::SpawnPlayer; + } + + int EntityId; + Uuid PlayerUuid; + double X, Y, Z; + unsigned char Yaw, Pitch; + + +}; + +struct PacketDestroyEntities : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + int count = stream->ReadVarInt(); + EntityIds.reserve(count); + for (int i = 0; i < count; i++) { + int entityId = stream->ReadVarInt(); + EntityIds.push_back(entityId); + } + } + + int GetPacketId() override { + return PacketNamePlayCB::DestroyEntities; + } + + std::vector EntityIds; +}; + +struct PacketSpawnMob : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadVarInt(); + EntityUuid = stream->ReadUuid(); + type = stream->ReadVarInt(); + X = stream->ReadDouble(); + Y = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadAngle(); + Pitch = stream->ReadAngle(); + HeadPitch = stream->ReadAngle(); + VelocityX = stream->ReadShort(); + VelocityY = stream->ReadShort(); + VelocityZ = stream->ReadShort(); + } + + int GetPacketId() override { + return PacketNamePlayCB::SpawnMob; + } + + unsigned int EntityId; + Uuid EntityUuid; + int type; + double X, Y, Z; + unsigned char Yaw, Pitch, HeadPitch; + short VelocityX, VelocityY, VelocityZ; + //Metadata }; \ No newline at end of file diff --git a/src/Render.cpp b/src/Render.cpp index aec60aa..c44c346 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -60,10 +60,13 @@ void Render::PrepareToRendering() { void Render::RenderFrame() { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (world) { + world->Update(); + } if (renderWorld) - world->Render(renderState); + world->Render(renderState); window->display(); } @@ -209,7 +212,7 @@ void Render::ExecuteRenderLoop() { window->setTitle("Connecting"); }); - LoopExecutionTimeController timer(std::chrono::milliseconds(32)); + LoopExecutionTimeController timer(std::chrono::milliseconds(16)); while (isRunning) { HandleEvents(); if (isMouseCaptured) HandleMouseCapture(); diff --git a/src/RendererEntity.cpp b/src/RendererEntity.cpp new file mode 100644 index 0000000..3adcf60 --- /dev/null +++ b/src/RendererEntity.cpp @@ -0,0 +1,161 @@ +#include "RendererEntity.hpp" + +const GLfloat vertices[] = { + //Z+ edge + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + + //Z- edge + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + + //X+ edge + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + //X- edge + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + + //Y+ edge + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + + //Y- edge + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, +}; + +const GLfloat uv_coords[] = { + //Z+ + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Z- + 1.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + + //X+ + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //X- + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Y+ + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Y- + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, +}; + +const GLuint magic = 993214; +GLuint Vbo = magic,Vao = magic,Vbo2 = magic; + +RendererEntity::RendererEntity(World *ptr, unsigned int id) +{ + world = ptr; + entityId = id; + + + if (Vbo == magic || Vao == magic) { + glGenVertexArrays(1, &Vao); + glGenBuffers(1, &Vbo); + glGenBuffers(1, &Vbo2); + + glBindVertexArray(Vao); + { + glBindBuffer(GL_ARRAY_BUFFER, Vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, Vbo2); + glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); + glEnableVertexAttribArray(1); + } + glBindVertexArray(0); + } +} + +RendererEntity::~RendererEntity() { +} + +void RendererEntity::Render(RenderState & renderState) { + renderState.SetActiveVao(Vao); + glm::mat4 model; + Entity& entity = world->GetEntity(entityId); + model = glm::translate(model, entity.pos.glm()); + model = glm::translate(model, glm::vec3(0, entity.height / 2.0, 0)); + model = glm::scale(model, glm::vec3(entity.width, entity.height, entity.width)); + + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); + glUniform3f(colorLoc, entity.renderColor.x, entity.renderColor.y, entity.renderColor.z); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glCheckError(); +} + +void RendererEntity::PrepareResources() +{ +} + +void RendererEntity::PrepareRender() +{ +} + +bool RendererEntity::IsNeedResourcesPrepare() +{ + return false; +} diff --git a/src/RendererEntity.hpp b/src/RendererEntity.hpp new file mode 100644 index 0000000..23fd029 --- /dev/null +++ b/src/RendererEntity.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +#include "Renderer.hpp" +#include "Entity.hpp" +#include "World.hpp" + +class RendererEntity :Renderer { + unsigned int entityId; + World *world; +public: + RendererEntity(World *ptr, unsigned int id); + ~RendererEntity(); + + void Render(RenderState& renderState) override; + void PrepareResources() override; + void PrepareRender() override; + bool IsNeedResourcesPrepare() override; + + GLint modelLoc = 0; + GLint colorLoc = 0; +}; \ No newline at end of file diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index 439fab1..a2d6825 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -123,7 +123,7 @@ RendererSection::~RendererSection() { refCounterVbo[VboModels]--; refCounterVbo[VboColors]--; refCounterVao[Vao]--; - if (refCounterVbo[VboTextures] <= 0) + /*if (refCounterVbo[VboTextures] <= 0) glDeleteBuffers(1, &VboTextures); if (refCounterVbo[VboModels] <= 0) @@ -132,12 +132,13 @@ 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); @@ -332,15 +333,15 @@ void RendererSection::PrepareResources() { void RendererSection::PrepareRender() { glBindBuffer(GL_ARRAY_BUFFER, VboTextures); glBufferData(GL_ARRAY_BUFFER, textures.size() * sizeof(glm::vec4), textures.data(), GL_DYNAMIC_DRAW); - textures.clear(); + std::vector().swap(textures); glBindBuffer(GL_ARRAY_BUFFER, VboModels); glBufferData(GL_ARRAY_BUFFER, models.size() * sizeof(glm::mat4), models.data(), GL_DYNAMIC_DRAW); - models.clear(); + std::vector().swap(models); glBindBuffer(GL_ARRAY_BUFFER, VboColors); glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_DYNAMIC_DRAW); - colors.clear(); + std::vector().swap(colors); glBindBuffer(GL_ARRAY_BUFFER, 0); } diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp index c165da4..57d04d5 100644 --- a/src/RendererSection.hpp +++ b/src/RendererSection.hpp @@ -25,9 +25,9 @@ class RendererSection : Renderer { static std::map refCounterVbo; static std::map refCounterVao; - size_t numOfFaces = 0; + - bool isEnabled = true; + bool isEnabled = false; size_t hash = 0; public: @@ -46,4 +46,6 @@ public: Section *GetSection(); bool IsNeedResourcesPrepare() override; + + size_t numOfFaces = 0; }; \ No newline at end of file diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 7d965f6..c2ba3ae 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -1,7 +1,7 @@ #include "RendererWorld.hpp" void RendererWorld::LoadedSectionController() { - + el::Helpers::setThreadName("RenderParser"); std::function updateAllSections = [this](Vector playerPos) { Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); @@ -25,20 +25,24 @@ void RendererWorld::LoadedSectionController() { for (auto& it : toRemove) { EventAgregator::PushEvent(EventType::DeleteSectionRender, DeleteSectionRenderData{ it }); } - + std::sort(suitableChunks.begin(), suitableChunks.end(), [playerChunk](Vector lhs, Vector rhs) { + return (playerChunk - lhs).GetLength() < (playerChunk - rhs).GetLength(); + }); for (auto& it : suitableChunks) { EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ it }); } }; - EventListener contentListener; + EventListener contentListener; contentListener.RegisterHandler(EventType::ChunkChanged, [this](EventData eventData) { auto vec = std::get(eventData).chunkPosition; - Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); + Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); - if ((Vector(vec.x,0,vec.z) - playerChunk).GetLength() > MaxRenderingDistance) + //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()) { @@ -56,7 +60,13 @@ void RendererWorld::LoadedSectionController() { contentListener.RegisterHandler(EventType::CreatedSectionRender, [this](EventData eventData) { auto vec = std::get(eventData).pos; sectionsMutex.lock(); - sections.find(vec)->second.PrepareResources(); + auto it = sections.find(vec); + if (it == sections.end()) { + LOG(ERROR) << "Created wrnog sectionRenderer"; + sectionsMutex.unlock(); + return; + } + it->second.PrepareResources(); sectionsMutex.unlock(); EventAgregator::PushEvent(EventType::InitalizeSectionRender, InitalizeSectionRenderData{ vec }); }); @@ -69,6 +79,7 @@ void RendererWorld::LoadedSectionController() { contentListener.RegisterHandler(EventType::UpdateSectionsRender, [this,&updateAllSections](EventData eventData) { updateAllSections(Vector(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ)); }); + LoopExecutionTimeController timer(std::chrono::milliseconds(32)); auto timeSincePreviousUpdate = std::chrono::steady_clock::now(); @@ -83,6 +94,38 @@ void RendererWorld::LoadedSectionController() { } } +void RendererWorld::RenderBlocks(RenderState& renderState) +{ + renderState.SetActiveShader(blockShader->Program); + glCheckError(); + + GLint projectionLoc = glGetUniformLocation(blockShader->Program, "projection"); + GLint viewLoc = glGetUniformLocation(blockShader->Program, "view"); + GLint windowSizeLoc = glGetUniformLocation(blockShader->Program, "windowSize"); + glm::mat4 projection = glm::perspective(45.0f, (float)renderState.WindowWidth / (float)renderState.WindowHeight, 0.1f, 10000000.0f); + glm::mat4 view = gs->GetViewMatrix(); + glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); + glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); + glUniform2f(windowSizeLoc, renderState.WindowWidth, renderState.WindowHeight); + + glCheckError(); + + sectionsMutex.lock(); + for (auto& it : sections) { + + it.second.Render(renderState); + } + + sectionsMutex.unlock(); +} + +void RendererWorld::RenderEntities(RenderState& renderState) +{ + renderState.SetActiveShader(entityShader->Program); + glCheckError(); + +} + RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { MaxRenderingDistance = 2; @@ -91,15 +134,22 @@ RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { listener.RegisterHandler(EventType::InitalizeSectionRender, [this](EventData eventData) { auto data = std::get(eventData); sectionsMutex.lock(); - sections.find(data.pos)->second.PrepareRender(); - sections.find(data.pos)->second.SetEnabled(true); + 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(std::make_pair(vec, RendererSection(&gs->world, vec))); + sections.insert(pair); sectionsMutex.unlock(); EventAgregator::PushEvent(EventType::CreatedSectionRender, CreatedSectionRenderData{ vec }); }); @@ -107,32 +157,55 @@ RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { listener.RegisterHandler(EventType::DeleteSectionRender, [this](EventData eventData) { auto vec = std::get(eventData).pos; sectionsMutex.lock(); - sections.erase(sections.find(vec)); + auto it = sections.find(vec); + if (it == sections.end()) { + LOG(ERROR) << "Deleting wrong sectionRenderer"; + sectionsMutex.unlock(); + return; + } + sections.erase(it); sectionsMutex.unlock(); }); + + listener.RegisterHandler(EventType::EntityChanged, [this](EventData eventData) { + auto data = std::get(eventData); + for (auto&it : gs->world.entities) { + if (it.entityId == data.EntityId) { + entities.push_back(RendererEntity(&gs->world,it.entityId)); + return; + } + } + }); resourceLoader = std::thread(&RendererWorld::LoadedSectionController, this); } RendererWorld::~RendererWorld() { + size_t faces = 0; + sectionsMutex.lock(); + for (auto& it : sections) { + faces += it.second.numOfFaces; + } + sectionsMutex.unlock(); + LOG(INFO) << "Total faces to render: "<Program); + renderState.SetActiveShader(blockShader->Program); glCheckError(); - GLint projectionLoc = glGetUniformLocation(shader->Program, "projection"); - GLint viewLoc = glGetUniformLocation(shader->Program, "view"); - GLint windowSizeLoc = glGetUniformLocation(shader->Program, "windowSize"); + GLint projectionLoc = glGetUniformLocation(blockShader->Program, "projection"); + GLint viewLoc = glGetUniformLocation(blockShader->Program, "view"); + GLint windowSizeLoc = glGetUniformLocation(blockShader->Program, "windowSize"); glm::mat4 projection = glm::perspective(45.0f, (float)renderState.WindowWidth / (float)renderState.WindowHeight, 0.1f, 10000000.0f); glm::mat4 view = gs->GetViewMatrix(); glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniform2f(windowSizeLoc, renderState.WindowWidth, renderState.WindowHeight); - glCheckError(); sectionsMutex.lock(); @@ -140,10 +213,24 @@ void RendererWorld::Render(RenderState & renderState) { it.second.Render(renderState); } - sectionsMutex.unlock(); - listener.HandleEvent(); + + renderState.SetActiveShader(entityShader->Program); + glCheckError(); + projectionLoc = glGetUniformLocation(entityShader->Program, "projection"); + viewLoc = glGetUniformLocation(entityShader->Program, "view"); + glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); + glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); + glCheckError(); + GLint modelLoc = glGetUniformLocation(entityShader->Program, "model"); + GLint colorLoc = glGetUniformLocation(entityShader->Program, "color"); + for (auto& it : entities) { + it.modelLoc = modelLoc; + it.colorLoc = colorLoc; + it.Render(renderState); + } + } void RendererWorld::PrepareResources() { @@ -151,12 +238,17 @@ void RendererWorld::PrepareResources() { } void RendererWorld::PrepareRender() { - shader = new Shader("./shaders/face.vs", "./shaders/face.fs"); - shader->Use(); - glUniform1i(glGetUniformLocation(shader->Program, "textureAtlas"), 0); + 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"); } bool RendererWorld::IsNeedResourcesPrepare() { LOG(ERROR) << "Incorrect call"; return false; } + +void RendererWorld::Update() { + listener.HandleEvent(); +} diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 2ae4e37..fb10c88 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -1,20 +1,28 @@ #pragma once #include "RendererSection.hpp" +#include "RendererEntity.hpp" #include "GameState.hpp" #include "Shader.hpp" #include class RendererWorld: public Renderer { + //General GameState *gs; - std::mutex sectionsMutex; - std::map sections; EventListener listener; - Shader *shader; std::thread resourceLoader; void LoadedSectionController(); bool isRunning = true; + //Blocks + std::mutex sectionsMutex; + std::map sections; + Shader *blockShader; + void RenderBlocks(RenderState& renderState); + //Entities + Shader *entityShader; + std::vector entities; + void RenderEntities(RenderState& renderState); public: RendererWorld(GameState* ptr); ~RendererWorld(); @@ -25,4 +33,6 @@ public: bool IsNeedResourcesPrepare() override; double MaxRenderingDistance; + + void Update(); }; \ No newline at end of file diff --git a/src/Stream.cpp b/src/Stream.cpp index d7b1072..a44b91c 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -281,8 +281,8 @@ void StreamOutput::WriteByteArray(std::vector value) { void StreamBuffer::ReadData(unsigned char *buffPtr, size_t buffLen) { size_t bufferLengthLeft = buffer + bufferLength - bufferPtr; - if (bufferLengthLeft < buffLen) - throw std::runtime_error("Required data is more, than in buffer available"); + if (bufferLengthLeft < buffLen) + throw std::runtime_error("Required data is more, than in buffer available"); std::memcpy(buffPtr, bufferPtr, buffLen); bufferPtr += buffLen; } diff --git a/src/ThreadGame.cpp b/src/ThreadGame.cpp index 74802bb..d3750ea 100644 --- a/src/ThreadGame.cpp +++ b/src/ThreadGame.cpp @@ -84,8 +84,8 @@ void ThreadGame::Execute() { while (isRunning) { if (gs != nullptr) gs->Update(timer.GetRealDeltaS()); - listener.HandleEvent(); - if (gs != nullptr) { + listener.HandleEvent(); + if (gs != nullptr) { gs->UpdatePacket(); if (isMoving[GameState::FORWARD]) gs->HandleMovement(GameState::FORWARD, timer.GetRealDeltaS()); diff --git a/src/Utility.cpp b/src/Utility.cpp index ebb6981..655c26f 100644 --- a/src/Utility.cpp +++ b/src/Utility.cpp @@ -29,7 +29,7 @@ GLenum glCheckError_(const char *file, int line) { break; } static int t = 0; - t++; + //t++; if (t > 10) LOG(FATAL); LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; diff --git a/src/World.cpp b/src/World.cpp index 17f9cd2..3eff5dd 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -169,7 +169,40 @@ glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLengt void World::UpdatePhysics(float delta) { + delta /= 5; for (auto& it : entities) { it.pos = it.pos + it.vel * delta; } } + +Entity & World::GetEntity(unsigned int EntityId) +{ + for (auto& it : entities) { + if (it.entityId == EntityId) { + return it; + } + } + static Entity fallback; + return fallback; +} + +std::vector World::GetEntitiesList() +{ + std::vector ret; + for (auto& it : entities) { + ret.push_back(it.entityId); + } + return ret; +} + +void World::AddEntity(Entity entity) +{ + for (auto& it : entities) { + if (it.entityId == entity.entityId) { + LOG(ERROR) << "Adding already existing entity" << entity.entityId; + return; + } + } + entities.push_back(entity); + +} diff --git a/src/World.hpp b/src/World.hpp index 2415610..06155cf 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -49,4 +49,10 @@ public: std::vector entities; void UpdatePhysics(float delta); + + Entity& GetEntity(unsigned int EntityId); + + std::vector GetEntitiesList(); + + void AddEntity(Entity entity); }; \ No newline at end of file -- cgit v1.2.3