diff options
author | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2017-08-27 17:24:28 +0200 |
---|---|---|
committer | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2018-01-13 03:39:28 +0100 |
commit | 04ab1a3420b46af046a898ee5510e0d9b25ed24c (patch) | |
tree | 4e9d300bb38d434305d00337535c7c4077bc57c4 /src | |
parent | 2017-08-23 (diff) | |
download | AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.tar AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.tar.gz AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.tar.bz2 AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.tar.lz AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.tar.xz AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.tar.zst AltCraft-04ab1a3420b46af046a898ee5510e0d9b25ed24c.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/Block.hpp | 5 | ||||
-rw-r--r-- | src/Render.cpp | 178 | ||||
-rw-r--r-- | src/Render.hpp | 6 | ||||
-rw-r--r-- | src/Renderer.hpp | 11 | ||||
-rw-r--r-- | src/RendererSection.cpp | 120 | ||||
-rw-r--r-- | src/RendererSection.hpp | 23 | ||||
-rw-r--r-- | src/RendererWidget.cpp | 76 | ||||
-rw-r--r-- | src/RendererWidget.hpp | 15 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 8 | ||||
-rw-r--r-- | src/RendererWorld.hpp | 2 | ||||
-rw-r--r-- | src/Section.cpp | 267 | ||||
-rw-r--r-- | src/Section.hpp | 44 | ||||
-rw-r--r-- | src/Socket.cpp | 43 | ||||
-rw-r--r-- | src/Socket.hpp | 8 | ||||
-rw-r--r-- | src/Stream.cpp | 5 | ||||
-rw-r--r-- | src/Widget.cpp | 124 | ||||
-rw-r--r-- | src/Widget.hpp | 74 | ||||
-rw-r--r-- | src/World.cpp | 65 | ||||
-rw-r--r-- | src/World.hpp | 8 | ||||
-rw-r--r-- | src/main.cpp | 17 |
20 files changed, 642 insertions, 457 deletions
diff --git a/src/Block.hpp b/src/Block.hpp index 367e559..6bd4e93 100644 --- a/src/Block.hpp +++ b/src/Block.hpp @@ -11,4 +11,9 @@ struct Block { unsigned char state : 4; unsigned char light : 4; unsigned char sky : 4; +}; + +struct BlockId { + unsigned short id : 13; + unsigned char state : 4; };
\ No newline at end of file diff --git a/src/Render.cpp b/src/Render.cpp index 7e88068..c739b77 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -6,12 +6,12 @@ #include "Event.hpp" Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) : timer(std::chrono::milliseconds(0)) { - InitSfml(windowWidth, windowHeight, windowTitle); - glCheckError(); - InitGlew(); - glCheckError(); - PrepareToRendering(); - glCheckError(); + InitSfml(windowWidth, windowHeight, windowTitle); + glCheckError(); + InitGlew(); + glCheckError(); + PrepareToRendering(); + glCheckError(); } Render::~Render() { @@ -29,7 +29,8 @@ void Render::InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string glCheckError(); window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2 - window->getSize().x / 2, sf::VideoMode::getDesktopMode().height / 2 - window->getSize().y / 2)); - SetMouseCapture(false); + window->setKeyRepeatEnabled(false); + SetMouseCapture(false); renderState.WindowWidth = WinWidth; renderState.WindowHeight = WinHeight; } @@ -59,6 +60,23 @@ void Render::PrepareToRendering() { AssetManager::Instance().GetTextureAtlasIndexes(); } +void Render::UpdateKeyboard() { + sf::Keyboard::Key toUpdate[] = { sf::Keyboard::A,sf::Keyboard::W,sf::Keyboard::S,sf::Keyboard::D,sf::Keyboard::Space }; + for (auto key : toUpdate) { + bool isPressed = sf::Keyboard::isKeyPressed(key); + if (!isKeyPressed[key] && isPressed) { + EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ key }); + } + if (isKeyPressed[key] && isPressed) { + //KeyHeld + } + if (isKeyPressed[key] && !isPressed) { + EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ key }); + } + isKeyPressed[key] = isPressed; + } +} + void Render::RenderFrame() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -75,92 +93,62 @@ void Render::RenderFrame() { void Render::HandleEvents() { sf::Event event; - while (window->pollEvent(event)) { - switch (event.type) { - case sf::Event::Closed: - LOG(INFO) << "Received close event by window closing"; - isRunning = false; - break; - case sf::Event::Resized: - glViewport(0, 0, window->getSize().x, window->getSize().y); - renderState.WindowWidth = window->getSize().x; - renderState.WindowHeight = window->getSize().y; - break; - case sf::Event::KeyPressed: - if (!window->hasFocus()) break; - switch (event.key.code) { - case sf::Keyboard::Escape: - LOG(INFO) << "Received close event by esc"; - isRunning = false; - break; - case sf::Keyboard::T: - SetMouseCapture(!isMouseCaptured); - break; - case sf::Keyboard::U: - EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ "10.1.1.2", 25565 }); - break; - case sf::Keyboard::I: - EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ "Manual disconnect" }); - break; - case sf::Keyboard::K: - if (renderWorld) { - world->MaxRenderingDistance--; - if (world->MaxRenderingDistance <= 0) - world->MaxRenderingDistance = 1; - LOG(INFO) << "Decreased rendering distance: " << world->MaxRenderingDistance; - EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{}); - } - break; - case sf::Keyboard::L: - if (renderWorld) { - world->MaxRenderingDistance++; - LOG(INFO) << "Increased rendering distance: " << world->MaxRenderingDistance; - EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{}); - } - break; - case sf::Keyboard::W: - EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::W }); - break; - case sf::Keyboard::A: - EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::A }); - break; - case sf::Keyboard::S: - EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::S }); - break; - case sf::Keyboard::D: - EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::D }); - break; - case sf::Keyboard::Space: - EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::Space }); - break; - default: - break; - } - case sf::Event::KeyReleased: - if (!window->hasFocus()) break; - switch (event.key.code) { - case sf::Keyboard::W: - EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::W }); - break; - case sf::Keyboard::A: - EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::A }); - break; - case sf::Keyboard::S: - EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::S }); - break; - case sf::Keyboard::D: - EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::D }); - break; - case sf::Keyboard::Space: - EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::Space }); - break; - default: - break; + while (window->pollEvent(event)) { + switch (event.type) { + case sf::Event::Closed: + LOG(INFO) << "Received close event by window closing"; + isRunning = false; + break; + case sf::Event::Resized: + glViewport(0, 0, window->getSize().x, window->getSize().y); + renderState.WindowWidth = window->getSize().x; + renderState.WindowHeight = window->getSize().y; + break; + case sf::Event::KeyPressed: + if (!window->hasFocus()) break; + switch (event.key.code) { + case sf::Keyboard::Escape: + LOG(INFO) << "Received close event by esc"; + isRunning = false; + break; + case sf::Keyboard::T: + SetMouseCapture(!isMouseCaptured); + break; + case sf::Keyboard::U: + EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ "10.1.1.2", 25565 }); + break; + case sf::Keyboard::I: + EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ "Manual disconnect" }); + break; + case sf::Keyboard::K: + if (renderWorld) { + world->MaxRenderingDistance--; + if (world->MaxRenderingDistance <= 0) + world->MaxRenderingDistance = 1; + LOG(INFO) << "Decreased rendering distance: " << world->MaxRenderingDistance; + EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{}); } - default: - break; - } - } + break; + case sf::Keyboard::L: + if (renderWorld) { + world->MaxRenderingDistance++; + LOG(INFO) << "Increased rendering distance: " << world->MaxRenderingDistance; + EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{}); + } + break; + default: + break; + } + case sf::Event::KeyReleased: + if (!window->hasFocus()) break; + switch (event.key.code) { + default: + break; + } + default: + break; + } + } } void Render::HandleMouseCapture() { @@ -216,6 +204,7 @@ void Render::ExecuteRenderLoop() { while (isRunning) { HandleEvents(); + if (window->hasFocus()) UpdateKeyboard(); if (isMouseCaptured) HandleMouseCapture(); glCheckError(); @@ -223,10 +212,7 @@ void Render::ExecuteRenderLoop() { while (listener.IsEventsQueueIsNotEmpty()) listener.HandleEvent(); 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())); + window->setTitle("FPS: " + std::to_string(1.0 / timer.GetRealDeltaS())); } timer.Update(); } diff --git a/src/Render.hpp b/src/Render.hpp index 6b4b5a4..b7d12d0 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -4,16 +4,18 @@ #include "Shader.hpp" #include "RendererWorld.hpp" +#include "RendererWidget.hpp" class Render { sf::Window *window; - bool isRunning=true; + bool isRunning = true; bool isMouseCaptured = false; float mouseXDelta, mouseYDelta; std::unique_ptr<RendererWorld> world; bool renderWorld = false; RenderState renderState; LoopExecutionTimeController timer; + std::map<sf::Keyboard::Key, bool> isKeyPressed; void SetMouseCapture(bool IsCaptured); @@ -28,6 +30,8 @@ class Render { void RenderFrame(); void PrepareToRendering(); + + void UpdateKeyboard(); public: Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle); ~Render(); diff --git a/src/Renderer.hpp b/src/Renderer.hpp index 53f6cc8..306a310 100644 --- a/src/Renderer.hpp +++ b/src/Renderer.hpp @@ -1,6 +1,7 @@ #pragma once #include <GL/glew.h> +#include "Utility.hpp" class RenderState { GLuint ActiveVao = -1; @@ -10,12 +11,4 @@ public: void SetActiveShader(GLuint Shader); unsigned int WindowWidth, WindowHeight; long long TimeOfDay; -}; - -/*struct Renderer { - virtual ~Renderer() = default; - virtual void Render(RenderState& renderState) = 0; - virtual void PrepareResources() = 0; - virtual void PrepareRender() = 0; - virtual bool IsNeedResourcesPrepare() = 0; -};*/
\ No newline at end of file +};
\ No newline at end of file diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index 0965453..bb1a888 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -25,30 +25,18 @@ const GLfloat uv_coords[] = { const GLuint magicUniqueConstant = 88375; GLuint RendererSection::VboVertices = magicUniqueConstant; GLuint RendererSection::VboUvs = magicUniqueConstant; -std::map<GLuint, int> RendererSection::refCounterVbo; -std::map<GLuint, int> RendererSection::refCounterVao; RendererSection::~RendererSection() { - refCounterVbo[VboTextures]--; - refCounterVbo[VboModels]--; - refCounterVbo[VboColors]--; - refCounterVbo[VboLights]--; - refCounterVao[Vao]--; - - if (refCounterVbo[VboTextures] <= 0) - glDeleteBuffers(1, &VboTextures); - - if (refCounterVbo[VboModels] <= 0) - glDeleteBuffers(1, &VboTextures); - - if (refCounterVbo[VboColors] <= 0) - glDeleteBuffers(1, &VboColors); - - if (refCounterVbo[VboLights] <= 0) - glDeleteBuffers(1, &VboLights); + if (Vao != 0) + glDeleteVertexArrays(1, &Vao); + + for (int i = 0; i < VBOCOUNT; i++) + if (Vbo[i] != 0) { + glBindBuffer(GL_ARRAY_BUFFER, Vbo[i]); + glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW); + } - if (refCounterVao[Vao] <= 0) - glDeleteVertexArrays(1, &Vao); + glDeleteBuffers(VBOCOUNT, Vbo); } void RendererSection::Render(RenderState &renderState) { @@ -84,30 +72,9 @@ RendererSection::RendererSection(RendererSectionData data) { << ") 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]++; - - glGenBuffers(1, &VboLights); - if (refCounterVbo.find(VboLights) == refCounterVbo.end()) - refCounterVbo[VboLights] = 0; - refCounterVbo[VboLights]++; - glGenVertexArrays(1, &Vao); - if (refCounterVao.find(Vao) == refCounterVao.end()) - refCounterVao[Vao] = 0; - refCounterVao[Vao]++; + + glGenBuffers(VBOCOUNT, Vbo); glBindVertexArray(Vao); { @@ -125,7 +92,7 @@ RendererSection::RendererSection(RendererSectionData data) { //Textures GLuint textureAttribPos = 7; - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[TEXTURES]); glVertexAttribPointer(textureAttribPos, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(textureAttribPos); glVertexAttribDivisor(textureAttribPos, 1); @@ -134,7 +101,7 @@ RendererSection::RendererSection(RendererSectionData data) { //Blocks models GLuint matAttribPos = 8; size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); - glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[MODELS]); 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))); @@ -150,14 +117,14 @@ RendererSection::RendererSection(RendererSectionData data) { //Color GLuint colorAttribPos = 12; - glBindBuffer(GL_ARRAY_BUFFER, VboColors); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[COLORS]); glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(colorAttribPos); glVertexAttribDivisor(colorAttribPos, 1); //Light GLuint lightAttribPos = 13; - glBindBuffer(GL_ARRAY_BUFFER, VboLights); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[LIGHTS]); glVertexAttribPointer(lightAttribPos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(lightAttribPos); glVertexAttribDivisor(lightAttribPos, 1); @@ -169,16 +136,16 @@ RendererSection::RendererSection(RendererSectionData data) { //Upload data to VRAM - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[TEXTURES]); glBufferData(GL_ARRAY_BUFFER, data.textures.size() * sizeof(glm::vec4), data.textures.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[MODELS]); glBufferData(GL_ARRAY_BUFFER, data.models.size() * sizeof(glm::mat4), data.models.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VboColors); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[COLORS]); glBufferData(GL_ARRAY_BUFFER, data.colors.size() * sizeof(glm::vec3), data.colors.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VboLights); + glBindBuffer(GL_ARRAY_BUFFER, Vbo[LIGHTS]); glBufferData(GL_ARRAY_BUFFER, data.lights.size() * sizeof(glm::vec2), data.lights.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -188,21 +155,9 @@ RendererSection::RendererSection(RendererSectionData data) { hash = data.hash; } -RendererSection::RendererSection(const RendererSection &other) { - this->VboModels = other.VboModels; - this->VboTextures = other.VboTextures; - this->VboColors = other.VboColors; - this->VboLights = other.VboLights; - this->sectionPos = other.sectionPos; - this->Vao = other.Vao; - this->numOfFaces = other.numOfFaces; - this->hash = other.hash; - - refCounterVbo[VboTextures]++; - refCounterVbo[VboModels]++; - refCounterVbo[VboColors]++; - refCounterVbo[VboLights]++; - refCounterVao[Vao]++; +RendererSection::RendererSection(RendererSection && other) { + using std::swap; + swap(*this, other); } RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) { @@ -214,7 +169,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) 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)); + BlockId block = section.GetBlockId(Vector(x, y, z)); if (block.id == 0) continue; @@ -243,9 +198,9 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) if (std::find(sectionsList.begin(), sectionsList.end(), sectionPosition + offset) == sectionsList.end()) return true; const Section& blockSection = world->GetSection(sectionPosition + offset); - return blockSection.GetBlock(block).id == 0 || blockSection.GetBlock(block).id == 31 || blockSection.GetBlock(block).id == 18; + return blockSection.GetBlockId(block).id == 0 || blockSection.GetBlockId(block).id == 31 || blockSection.GetBlockId(block).id == 18; } - return section.GetBlock(block).id == 0 || section.GetBlock(block).id == 31 || section.GetBlock(block).id == 18; + return section.GetBlockId(block).id == 0 || section.GetBlockId(block).id == 31 || section.GetBlockId(block).id == 18; }; unsigned char isVisible = 0; @@ -272,7 +227,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) for (int i = 0; i < 4; i++) { textures.push_back(texture->second); colors.push_back(color); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } 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)); @@ -298,7 +253,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, 0.0078125, 0.00442477876106194690)); //Fallback TNT texture colors.push_back(color); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } if (isVisible >> 1 & 0x1) { //west side X- glm::mat4 faceTransform = glm::translate(transform, glm::vec3(1, 0, 0)); @@ -313,7 +268,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, 0.0078125, 0.00442477876106194690)); //Fallback TNT texture colors.push_back(color); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } if (isVisible >> 2 & 0x1) { //Top side Y+ glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 1, 0)); @@ -328,7 +283,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) colors.push_back(color); else colors.push_back(biomeColor); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } if (isVisible >> 3 & 0x1) { //Bottom side Y- glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 0)); @@ -342,7 +297,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, 0.0078125, 0.00442477876106194690)); //Fallback TNT texture colors.push_back(color); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } if (isVisible >> 4 & 0x1) { //south side Z+ glm::mat4 faceTransform = glm::translate(transform, glm::vec3(1, 0, 0)); @@ -356,7 +311,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, 0.0078125, 0.00442477876106194690)); //Fallback TNT texture colors.push_back(color); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } if (isVisible >> 5 & 0x1) { //north side Z- glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 1)); @@ -373,7 +328,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, 0.0078125, 0.00442477876106194690)); //Fallback TNT texture colors.push_back(color); - lights.push_back(glm::vec2(block.light, block.sky)); + lights.push_back(glm::vec2(0, 0)); } } } @@ -383,9 +338,12 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) textures.shrink_to_fit(); models.shrink_to_fit(); colors.shrink_to_fit(); +} - /*for (auto& it : lights) { - it.x = 8; - it.y = 16; - }*/ +void swap(RendererSection & lhs, RendererSection & rhs) { + std::swap(lhs.Vbo, rhs.Vbo); + std::swap(lhs.Vao, rhs.Vao); + std::swap(lhs.hash, rhs.hash); + std::swap(lhs.numOfFaces, rhs.numOfFaces); + std::swap(lhs.sectionPos, rhs.sectionPos); } diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp index 9e5fd99..12a169e 100644 --- a/src/RendererSection.hpp +++ b/src/RendererSection.hpp @@ -23,19 +23,28 @@ struct RendererSectionData { RendererSectionData(World *world, Vector sectionPosition); }; - class RendererSection { - GLuint Vao, VboTextures, VboModels, VboColors, VboLights; + enum Vbos { + MODELS = 0, + TEXTURES, + COLORS, + LIGHTS, + VBOCOUNT, + }; + GLuint Vao = { 0 }; + GLuint Vbo[VBOCOUNT] = { 0 }; static GLuint VboVertices, VboUvs; - static std::map<GLuint, int> refCounterVbo; - static std::map<GLuint, int> refCounterVao; size_t hash; Vector sectionPos; + + RendererSection(const RendererSection &other) = delete; public: RendererSection(RendererSectionData data); - RendererSection(const RendererSection &other); + + RendererSection(RendererSection &&other); + ~RendererSection(); void Render(RenderState &renderState); @@ -44,5 +53,7 @@ public: size_t GetHash(); - size_t numOfFaces = 0; + size_t numOfFaces; + + friend void swap(RendererSection &lhs, RendererSection &rhs); };
\ No newline at end of file diff --git a/src/RendererWidget.cpp b/src/RendererWidget.cpp new file mode 100644 index 0000000..6b732e3 --- /dev/null +++ b/src/RendererWidget.cpp @@ -0,0 +1,76 @@ +#include "RendererWidget.hpp" + +const GLfloat vertices[] = { + 0.0f,0.0f,0.0f, + 1.0f,1.0f,0.0f, + 0.0f,1.0f,0.0f, + + 0.0f,0.0f,0.0f, + 1.0f,0.0f,0.0f, + 1.0f,1.0f,0.0f, +}; + +const GLfloat uvs[] = { + 0.0f,0.0f, + 1.0f,1.0f, + 0.0f,1.0f, + + 0.0f,0.0f, + 1.0f,0.0f, + 1.0f,1.0f, +}; + +static GLuint VboVertices, VboUvs, Vao; +static Shader* guiShader = nullptr; + +RendererWidget::RendererWidget(RootWidget *widget) { + this->tree = widget; + + if (guiShader == nullptr) { + guiShader = new Shader("./shaders/gui.vs", "./shaders/gui.fs"); + guiShader->Use(); + glUniform1i(glGetUniformLocation(guiShader->Program, "textureAtlas"), 0); + + glGenBuffers(1, &VboVertices); + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glGenBuffers(1, &VboUvs); + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW); + + glGenVertexArrays(1, &Vao); + glBindVertexArray(Vao); + { + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); + glEnableVertexAttribArray(1); + } + glBindVertexArray(0); + } +} + +RendererWidget::~RendererWidget() { + +} + +void RendererWidget::Render(RenderState &state) { + state.SetActiveVao(Vao); + state.SetActiveShader(guiShader->Program); + + auto toRender = tree->GetRenderList(); + for (auto& it : toRender) { + auto[x, y, w, h] = it->GetTexture(); + glUniform4f(glGetUniformLocation(guiShader->Program, "widgetTexture"), x, y, w, h); + + glUniform4f(glGetUniformLocation(guiShader->Program, "transform"), it->x, it->y, it->w, it->h); + + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + glCheckError(); +}
\ No newline at end of file diff --git a/src/RendererWidget.hpp b/src/RendererWidget.hpp new file mode 100644 index 0000000..a979c88 --- /dev/null +++ b/src/RendererWidget.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "Renderer.hpp" +#include "Widget.hpp" +#include "Shader.hpp" + +class RendererWidget { + RootWidget *tree; + +public: + RendererWidget(RootWidget *widget); + ~RendererWidget(); + + void Render(RenderState &state); +};
\ No newline at end of file diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index dd5fdb4..7262583 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -94,7 +94,6 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr):gs(ptr) { sectionsMutex.lock(); auto it = sections.find(vec); if (it == sections.end()) { - //LOG(ERROR) << "Deleting wrong sectionRenderer"; sectionsMutex.unlock(); return; } @@ -124,7 +123,7 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr):gs(ptr) { sections.erase(sections.find(data.sectionPos)); } RendererSection renderer(data); - sections.insert(std::make_pair(data.sectionPos, renderer)); + sections.insert(std::make_pair(data.sectionPos, std::move(renderer))); sectionsMutex.unlock(); renderData.pop(); } @@ -155,7 +154,6 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr):gs(ptr) { if (isParsing.find(vec) == isParsing.end()) isParsing[vec] = false; if (isParsing[vec] == true) { - //LOG(WARNING) << "Changed parsing block"; isParsingMutex.unlock(); return; } @@ -188,6 +186,8 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr):gs(ptr) { for (int i = 0; i < numOfWorkers; i++) workers.push_back(std::thread(&RendererWorld::WorkerFunction, this, i)); + EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{}); + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } @@ -349,7 +349,7 @@ void RendererWorld::PrepareRender() { } void RendererWorld::Update(double timeToUpdate) { - auto timeSincePreviousUpdate = std::chrono::steady_clock::now(); + static auto timeSincePreviousUpdate = std::chrono::steady_clock::now(); int i = 0; while (listener.IsEventsQueueIsNotEmpty() && i++ < 50) listener.HandleEvent(); diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 5bc575c..4e098e5 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -37,9 +37,7 @@ public: ~RendererWorld(); void Render(RenderState& renderState); - void PrepareResources(); void PrepareRender(); - bool IsNeedResourcesPrepare(); double MaxRenderingDistance; diff --git a/src/Section.cpp b/src/Section.cpp index c9af5c6..9b4292b 100644 --- a/src/Section.cpp +++ b/src/Section.cpp @@ -2,164 +2,134 @@ #include <bitset> +void Section::CalculateHash() { + std::vector<unsigned char> rawData; + rawData.reserve(block.size() * sizeof(long long) + light.size() + sky.size()); + std::copy(block.begin(), block.end(), std::back_inserter(rawData)); + std::copy(light.begin(), light.end(), std::back_inserter(rawData)); + if (!sky.empty()) + std::copy(sky.begin(), sky.end(), std::back_inserter(rawData)); + + const unsigned char *from = reinterpret_cast<const unsigned char *>(rawData.data()); + size_t length = rawData.size(); + + std::string str(from, from + length); + hash = std::hash<std::string>{}(str); +} + +Section::Section(Vector pos, unsigned char bitsPerBlock, std::vector<unsigned short> palette, std::vector<long long> blockData, std::vector<unsigned char> lightData, std::vector<unsigned char> skyData) { + if (bitsPerBlock < 4) + bitsPerBlock = 4; + if (bitsPerBlock > 8) + bitsPerBlock = 13; + this->bitsPerBlock = bitsPerBlock; + + this->worldPosition = pos; + this->block = std::move(blockData); + this->palette = std::move(palette); + this->light = std::move(lightData); + this->sky = std::move(skyData); + + CalculateHash(); +} + +Section::Section() { + + CalculateHash(); +} + Section::~Section() { + } Section::Section(Section && other) noexcept { using std::swap; swap(*this, other); + CalculateHash(); } -Block &Section::GetBlock(Vector pos) { - return blocks[pos.y * 256 + pos.z * 16 + pos.x]; +Section &Section::operator=(Section other) noexcept { + using std::swap; + swap(*this, other); + CalculateHash(); + return *this; } -Block Section::GetBlock(Vector pos) const -{ - if (blocks.empty()) { - static Block fallback; - return fallback; +BlockId Section::GetBlockId(Vector pos) const { + if (block.empty()) + return BlockId{ 0,0 }; + int value; + + unsigned char individualValueMask = ((1 << bitsPerBlock) - 1); + + int blockNumber = (((pos.y * 16) + pos.z) * 16) + pos.x; + int startLong = (blockNumber * bitsPerBlock) / 64; + int startOffset = (blockNumber * bitsPerBlock) % 64; + int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64; + + unsigned short t; + + if (startLong == endLong) { + t = (block[startLong] >> startOffset); + } + else { + int endOffset = 64 - startOffset; + t = (block[startLong] >> startOffset |block[endLong] << endOffset); } - return blocks[pos.y * 256 + pos.z * 16 + pos.x]; + + t &= individualValueMask; + + + if (t >= palette.size()) { + //LOG(ERROR) << "Out of palette: " << t; + value = 0; + } + else + value = palette[t]; + + BlockId blockId; + blockId.id = value >> 4; + blockId.state = value & 0xF; + return blockId; } -double totalParsingTime = 0; +unsigned char Section::GetBlockLight(Vector pos) +{ + int blockNumber = pos.y * 256 + pos.z * 16 + pos.x; + unsigned char lightValue = this->light[blockNumber]; + return (blockNumber % 2 == 0) ? (lightValue & 0xF) : (lightValue >> 4); +} -Section::Section(PackedSection data) +unsigned char Section::GetBlockSkyLight(Vector pos) { - if (data.blocks.empty()) - return; - worldPosition = data.position; - - bool useFirst = false; - - if (useFirst) { - unsigned char *blocksData = reinterpret_cast<unsigned char*>(data.blocks.data()); - std::vector<unsigned short> blocks; - blocks.reserve(4096); - { - auto begin = std::chrono::steady_clock::now(); - int bitPos = 0; - unsigned short t = 0; - for (size_t i = 0; i < data.blocks.size() * 8; i++) { - for (int j = 0; j < 8; j++) { - t |= (blocksData[i] & 0x01) ? 0x80 : 0x00; - t >>= 1; - blocksData[i] >>= 1; - bitPos++; - if (bitPos >= data.bitsPerBlock) { - bitPos = 0; - t >>= data.bitsPerBlock - 1; - blocks.push_back(t); - t = 0; - } - } - } - auto end = std::chrono::steady_clock::now(); - std::chrono::duration<double, std::milli> time = end - begin; - totalParsingTime += time.count(); - } - std::vector<byte> light; - light.reserve(4096); - for (int i = 0; i < 2048; i++) { - byte t = data.light[i]; - byte first = t & 0x0F; - byte second = t >> 4; - light.push_back(0); - light.push_back(0); - } - - std::vector<byte> sky; - if (!data.sky.empty()) { - sky.reserve(4096); - for (int i = 0; i < 2048; i++) { - byte t = data.sky[i]; - byte first = t & 0x0F; - byte second = t >> 4; - sky.push_back(first); - sky.push_back(second); - } - } - - for (int i = 0; i < 4096; i++) { - unsigned short blockId = !data.palette.empty() ? data.palette[blocks[i]] : blocks[i]; - Block block(blockId >> 4, blockId & 0xF, light[i], sky.empty() ? 0 : sky[i]); - this->blocks.push_back(block); - } - } else { - - std::vector<unsigned short> blocks; - blocks.reserve(4096); - - unsigned char individualValueMask = ((1 << data.bitsPerBlock) - 1); - - for (int blockNumber = 0; blockNumber < 4096; blockNumber++) { - int startLong = (blockNumber * data.bitsPerBlock) / 64; - int startOffset = (blockNumber * data.bitsPerBlock) % 64; - int endLong = ((blockNumber + 1) * data.bitsPerBlock - 1) / 64; - - unsigned short t; - - if (startLong == endLong) { - t = (data.blocks[startLong] >> startOffset); - } - else { - int endOffset = 64 - startOffset; - t = (data.blocks[startLong] >> startOffset | data.blocks[endLong] << endOffset); - } - - t &= individualValueMask; - - - if (t >= data.palette.size()) { - //LOG(ERROR) << "Out of palette: "<<t; - blocks.push_back(0); - } - else - blocks.push_back(data.palette.empty() ? t : data.palette[t]); - } - - - std::vector<unsigned char> light; - light.reserve(4096); - for (int i = 0; i < 2048; i++) { - unsigned char t = data.light[i]; - light.push_back(t & 0xF); - light.push_back(t >> 4 & 0xF); - } - - std::vector<unsigned char> sky; - if (!data.sky.empty()) { - sky.reserve(4096); - for (int i = 0; i < 2048; i++) { - unsigned char t = data.sky[i]; - sky.push_back(t & 0xF); - sky.push_back(t >> 4 & 0xF); - } - } - - for (int i = 0; i < 4096; i++) { - unsigned short blockId = blocks[i]; - Block block(blockId >> 4, blockId & 0xF, light[i], sky.empty() ? 0 : sky[i]); - this->blocks.push_back(block); - } - } + int blockNumber = pos.y * 256 + pos.z * 16 + pos.x; + unsigned char skyValue = this->sky[blockNumber]; + return (blockNumber % 2 == 0) ? (skyValue & 0xF) : (skyValue >> 4); } -Section &Section::operator=(Section other) noexcept { - using std::swap; - swap(*this, other); - return *this; +void Section::SetBlockId(Vector pos, BlockId value) { + LOG(WARNING) << "Block changing not implemented!"; } void swap(Section& lhs, Section& rhs) noexcept { - std::swap(lhs.blocks, rhs.blocks); + std::swap(lhs.block, rhs.block); + std::swap(lhs.light, rhs.light); + std::swap(lhs.sky, rhs.sky); + std::swap(lhs.bitsPerBlock, rhs.bitsPerBlock); + std::swap(lhs.palette, rhs.palette); + std::swap(lhs.hash, rhs.hash); std::swap(lhs.worldPosition, rhs.worldPosition); } Section::Section(const Section &other) { worldPosition = other.worldPosition; - this->blocks = other.blocks; + this->block = other.block; + this->light = other.light; + this->sky = other.sky; + this->bitsPerBlock = other.bitsPerBlock; + this->palette = other.palette; + this->hash = other.hash; + this->worldPosition = other.worldPosition; } Vector Section::GetPosition() const { @@ -167,32 +137,5 @@ Vector Section::GetPosition() const { } size_t Section::GetHash() const { - if (blocks.empty()) return 0; - - const unsigned char *from = reinterpret_cast<const unsigned char *>(blocks.data()); - size_t length = blocks.size() * sizeof(Block); - - std::string str(from, from + length); - return std::hash<std::string>{}(str); -} - -PackedSection::PackedSection(Vector position, byte * dataBlocks, size_t dataBlocksLength, byte * dataLight, byte * dataSky, byte bitsPerBlock, std::vector<unsigned short> palette) -{ - this->position = position; - - this->palette = palette; - - this->bitsPerBlock = bitsPerBlock; - - for (long long *t = reinterpret_cast<long long *>(dataBlocks); (byte*)t < dataBlocks + dataBlocksLength; t++) { - long long l = *t; - endswap(l); - this->blocks.push_back(l); - } - - light.assign(dataLight, dataLight + 2048); - - if (dataSky != nullptr) { - sky.assign(dataSky, dataSky + 2048); - } -} + return hash; +}
\ No newline at end of file diff --git a/src/Section.hpp b/src/Section.hpp index dfa738a..bda3584 100644 --- a/src/Section.hpp +++ b/src/Section.hpp @@ -11,47 +11,45 @@ #include "Vector.hpp" #include "Utility.hpp" -struct PackedSection { - Vector position; - - int bitsPerBlock; - - std::vector<unsigned short> palette; - - std::vector<long long> blocks; +class Section { + std::vector<long long> block; std::vector<unsigned char> light; std::vector<unsigned char> sky; - - PackedSection(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, - std::vector<unsigned short> palette); - - PackedSection() = default; -}; - -class Section { - std::vector<Block> blocks; + unsigned char bitsPerBlock; + std::vector<unsigned short> palette; Vector worldPosition; + size_t hash; + void CalculateHash(); public: + Section(Vector pos, unsigned char bitsPerBlock, std::vector<unsigned short> palette, std::vector<long long> blockData, std::vector<unsigned char> lightData, std::vector<unsigned char> skyData); - Section(PackedSection data); + Section(); ~Section(); + Section(const Section &other); + Section(Section &&other) noexcept; - Block &GetBlock(Vector pos); + Section &operator=(Section other) noexcept; - Block GetBlock(Vector pos) const; + BlockId GetBlockId(Vector pos) const; - Section &operator=(Section other) noexcept; + unsigned char GetBlockLight(Vector pos); - friend void swap(Section& lhs, Section& rhs) noexcept; + unsigned char GetBlockSkyLight(Vector pos); - Section(const Section &other); + void SetBlockId(Vector pos, BlockId value); + + void SetBlockLight(Vector pos, unsigned char value); + + void SetBlockSkyLight(Vector pos, unsigned char value); Vector GetPosition() const; size_t GetHash() const; + + friend void swap(Section& lhs, Section& rhs) noexcept; };
\ No newline at end of file diff --git a/src/Socket.cpp b/src/Socket.cpp index 519da2f..aea0c73 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -1,30 +1,37 @@ #include <iostream> #include "Socket.hpp" -Socket::Socket(std::string address, unsigned short port) { - sf::Socket::Status connectionStatus = socket.connect(sf::IpAddress(address), port); - if (connectionStatus == sf::Socket::Status::Error) - throw std::runtime_error("Can't connect to remote server"); - else if (connectionStatus != sf::Socket::Status::Done) - throw std::runtime_error("Connection failed with unknown reason"); +#include <thread> + +Socket::Socket(std::string address, unsigned short port) { + if (SDLNet_Init() == -1) + throw std::runtime_error("SDL_Net initalization failed: " + std::string(SDLNet_GetError())); + + if (SDLNet_ResolveHost(&server, address.c_str(), port) == -1) + throw std::runtime_error("Hostname not resolved: " + std::string(SDLNet_GetError())); + + socket = SDLNet_TCP_Open(&server); + if (!socket) + throw std::runtime_error(std::string(SDLNet_GetError())); } Socket::~Socket() { - socket.disconnect(); + SDLNet_TCP_Close(socket); + + SDLNet_Quit(); } -void Socket::Read(unsigned char *buffPtr, size_t buffLen) { - size_t received = 0; - socket.receive(buffPtr, buffLen, received); - size_t totalReceived = received; - while (totalReceived < buffLen) { - if (socket.receive(buffPtr + totalReceived, buffLen - totalReceived, received) != sf::Socket::Done) - throw std::runtime_error("Raw socket data receiving is failed"); - totalReceived += received; - } +void Socket::Read(unsigned char *buffPtr, size_t buffLen) { + size_t totalReceived = 0; + while (buffLen > totalReceived) { + size_t received = SDLNet_TCP_Recv(socket, buffPtr + totalReceived, buffLen - totalReceived); + if ( received <= 0) + throw std::runtime_error("Data receiving failed: " + std::string(SDLNet_GetError())); + totalReceived += received; + } } void Socket::Write(unsigned char *buffPtr, size_t buffLen) { - if (socket.send(buffPtr, buffLen) != sf::Socket::Done) - throw std::runtime_error("Raw socket data sending is failed"); + if (SDLNet_TCP_Send(socket, buffPtr, buffLen) < buffLen) + throw std::runtime_error("Data sending failed: " + std::string(SDLNet_GetError())); } diff --git a/src/Socket.hpp b/src/Socket.hpp index 48bcad9..16825f0 100644 --- a/src/Socket.hpp +++ b/src/Socket.hpp @@ -4,14 +4,16 @@ #include <SFML/Network.hpp> +#include <SDL_net.h> + /** * Platform independent class for working with platform dependent hardware socket * @brief Wrapper around raw sockets * @warning Connection state is based on lifetime of Socket object instance, ie connected at ctor and disconnect at dtor - * @todo Replace SFML's socket with WinSock and POSIX's socket implementation */ class Socket { - sf::TcpSocket socket; + IPaddress server; + TCPsocket socket; public: /** * Constructs Socket class instance from IP's string and Port number and connects to remote server @@ -23,7 +25,7 @@ public: /** * Destruct Socket instance and disconnect from server - * @warning There is no way to force disconnect, except use delete for manually allocated objects and scope of visibility for variables on stack + * @warning There is no way to force disconnect, except use delete for manually allocated objects and scope of visibility for auto variables */ ~Socket(); diff --git a/src/Stream.cpp b/src/Stream.cpp index a44b91c..28680c6 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -281,8 +281,9 @@ void StreamOutput::WriteByteArray(std::vector<unsigned char> 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"); + throw std::runtime_error("Internal error: StreamBuffer reader out of data"); std::memcpy(buffPtr, bufferPtr, buffLen); bufferPtr += buffLen; } @@ -290,7 +291,7 @@ void StreamBuffer::ReadData(unsigned char *buffPtr, size_t buffLen) { void StreamBuffer::WriteData(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"); + throw std::runtime_error("Internal error: StreamBuffer writer out of data"); std::memcpy(bufferPtr, buffPtr, buffLen); bufferPtr += buffLen; } diff --git a/src/Widget.cpp b/src/Widget.cpp new file mode 100644 index 0000000..1a522ca --- /dev/null +++ b/src/Widget.cpp @@ -0,0 +1,124 @@ +#include "Widget.hpp" + +void RootWidget::AttachWidget(std::unique_ptr<Widget> widget, Widget * parent) +{ + parent->childs.push_back(widget.get()); + this->allWidgets.push_back(std::move(widget)); +} + +void RootWidget::AttachWidget(std::unique_ptr<Widget> widget) { + widget->parent = nullptr; + this->childs.push_back(widget.get()); + this->allWidgets.push_back(std::move(widget)); +} + +std::vector<Widget*> RootWidget::GetRenderList() +{ + std::vector<Widget*> renderList; + + std::function<void(Widget*)> treeWalker = [&](Widget* node) { + for (auto it : node->childs) + treeWalker(it); + renderList.push_back(node); + }; + + for (auto& it : this->childs) + treeWalker(it); + + return renderList; +} + +void RootWidget::UpdateEvents(double mouseX, double mouseY, bool mouseButton) { + + LOG(INFO) << mouseX << "x" << mouseY; + + auto testIsHover = [&](double x, double y, Widget* widget) { + bool isOnX = widget->x > x && widget->x + widget->w < x; + bool isOnY = widget->y > y && widget->y + widget->h < y; + if (mouseButton) + LOG(INFO) << "X: " << isOnX << " Y: " << isOnY; + return isOnX && isOnY; + }; + + std::function<void(Widget*)> treeWalker = [&](Widget* node) { + for (auto it : node->childs) + treeWalker(it); + + if (testIsHover(mouseX,mouseY,node)) { + if (node->onHover) + node->onHover(node); + if (mouseButton && !prevBut) + if (node->onPress) + node->onPress(node); + else if (!mouseButton && prevBut) + if (node->onRelease) + node->onRelease(node); + } + else { + if (testIsHover(prevX, prevY, node)) + if (node->onUnhover) + node->onUnhover(node); + } + + if (node->onUpdate) + node->onUpdate(node); + }; + + for (auto it : childs) + treeWalker(it); + + prevX = mouseX; + prevY = mouseY; + prevBut = mouseButton; +} + +WidgetButton::WidgetButton() +{ + this->state = WidgetState::Idle; + + onHover = [](Widget* widget) { + WidgetButton* w = dynamic_cast<WidgetButton*>(widget); + if (w->state != WidgetState::Pressed) + w->state = WidgetState::Hovering; + LOG(INFO) << "Hover"; + }; + + onPress = [](Widget* widget) { + WidgetButton* w = dynamic_cast<WidgetButton*>(widget); + w->state = WidgetState::Pressed; + LOG(INFO) << "Press"; + }; + + onRelease = [](Widget* widget) { + WidgetButton* w = dynamic_cast<WidgetButton*>(widget); + w->state = WidgetState::Idle; + w->onClick(w); + LOG(INFO) << "Release"; + }; + + onUnhover = [](Widget *widget) { + WidgetButton* w = dynamic_cast<WidgetButton*>(widget); + if (w->state!=WidgetState::Pressed) + w->state = WidgetState::Idle; + LOG(INFO) << "Unhover"; + }; + +} + +std::tuple<double, double, double, double> WidgetButton::GetTexture() +{ + double yOffset; + switch (this->state) { + case WidgetState::Idle: + yOffset = 0.2578; + break; + case WidgetState::Hovering: + yOffset = 0.3359; + break; + case WidgetState::Pressed: + yOffset = 0.1796; + } + + TextureCoordinates texture = AssetManager::Instance().GetTextureByAssetName("minecraft/textures/gui/widgets"); + return { texture.x,texture.y + texture.h * yOffset,texture.w * 0.7812,texture.h * 0.07812 }; +} diff --git a/src/Widget.hpp b/src/Widget.hpp new file mode 100644 index 0000000..6d78ebe --- /dev/null +++ b/src/Widget.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include <vector> +#include <memory> +#include <functional> + +#include "AssetManager.hpp" + +class Widget; +class RootWidget { + std::vector<std::unique_ptr<Widget>> allWidgets; + + std::vector<Widget*> childs; + + double prevX, prevY; + bool prevBut; +public: + RootWidget() = default; + + ~RootWidget() = default; + + void AttachWidget(std::unique_ptr<Widget> widget, Widget* parent); + + void AttachWidget(std::unique_ptr<Widget> widget); + + std::vector<Widget*> GetRenderList(); + + void UpdateEvents(double mouseX, double mouseY, bool mouseButton); +}; + +struct Widget { + Widget() = default; + + virtual ~Widget() = default; + + Widget *parent; + + std::vector<Widget*> childs; + + double x, y, w, h; //In OGL screen-coordinates + + virtual std::tuple<double, double, double, double> GetTexture() = 0; + + + using Handler = std::function<void(Widget*)>; + + Handler onPress; + + Handler onRelease; + + Handler onHover; + + Handler onUnhover; + + Handler onUpdate; +}; + +struct WidgetButton : Widget { + WidgetButton(); + + ~WidgetButton() override = default; + + std::string Text; + + Handler onClick; + + std::tuple<double, double, double, double> GetTexture() override; + + enum class WidgetState { + Idle, + Hovering, + Pressed, + } state; +};
\ No newline at end of file diff --git a/src/World.cpp b/src/World.cpp index f9edbe1..1a0e0fa 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -7,29 +7,23 @@ void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { for (int i = 0; i < 16; i++) { if (bitmask[i]) { Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); - PackedSection packedSection = ParseSection(&chunkData, chunkPosition); - Section section(packedSection); + Section section = ParseSection(&chunkData, chunkPosition); if (packet->GroundUpContinuous) { - if (!cachedSections.insert(std::make_pair(chunkPosition, section)).second) { + if (!sections.insert(std::make_pair(chunkPosition, section)).second) { LOG(ERROR) << "New chunk not created " << chunkPosition << " potential memory leak"; } } else { using std::swap; - swap(cachedSections.at(chunkPosition), section); + swap(sections.at(chunkPosition), section); } EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ chunkPosition }); } } } -PackedSection World::ParseSection(StreamInput *data, Vector position) { - unsigned char bitsPerBlock = data->ReadUByte(); - if (bitsPerBlock < 4) - bitsPerBlock = 4; - - if (bitsPerBlock > 8) - bitsPerBlock = 13; +Section World::ParseSection(StreamInput *data, Vector position) { + unsigned char bitsPerBlock = data->ReadUByte(); int paletteLength = data->ReadVarInt(); std::vector<unsigned short> palette; @@ -42,24 +36,17 @@ PackedSection World::ParseSection(StreamInput *data, Vector position) { std::vector<unsigned char> skyLight; if (dimension == 0) skyLight = data->ReadByteArray(2048); - return PackedSection(position, dataArray.data(), dataArray.size(), blockLight.data(), - (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette); -} -World::~World() { + long long *blockData = reinterpret_cast<long long*>(dataArray.data()); + for (int i = 0; i < dataArray.size() / sizeof(long long); i++) + endswap(blockData[i]); + std::vector<long long> blockArray (blockData, blockData + dataArray.size() / sizeof (long long)); + + + return Section(position, bitsPerBlock, std::move(palette), std::move(blockArray), std::move(blockLight), std::move(skyLight)); } -Block & World::GetBlock(Vector worldPosition) -{ - Vector sectionPos(std::floor(worldPosition.x / 16.0), std::floor(worldPosition.y / 16.0), std::floor(worldPosition.z / 16.0)); - auto it = cachedSections.find(sectionPos); - if (it == cachedSections.end()) { - static Block fallbackBlock; - return fallbackBlock; - } - Section& section = it->second; - Block& block = section.GetBlock(worldPosition - sectionPos * 16); - return block; +World::~World() { } World::World() { @@ -67,7 +54,7 @@ World::World() { bool World::isPlayerCollides(double X, double Y, double Z) { Vector PlayerChunk(floor(X / 16.0), floor(Y / 16.0), floor(Z / 16.0)); - if (cachedSections.find(PlayerChunk) == cachedSections.end() || cachedSections.find(PlayerChunk - Vector(0,1,0)) == cachedSections.end()) + if (sections.find(PlayerChunk) == sections.end() || sections.find(PlayerChunk - Vector(0,1,0)) == sections.end()) return true; std::vector<Vector> closestSectionsCoordinates = { Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z), @@ -80,7 +67,7 @@ bool World::isPlayerCollides(double X, double Y, double Z) { }; std::vector<Vector> closestSections; for (auto &coord:closestSectionsCoordinates) { - if (cachedSections.find(coord) != cachedSections.end()) + if (sections.find(coord) != sections.end()) closestSections.push_back(coord); } @@ -102,7 +89,7 @@ bool World::isPlayerCollides(double X, double Y, double Z) { for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { - Block block = section.GetBlock(Vector(x, y, z)); + BlockId block = section.GetBlockId(Vector(x, y, z)); if (block.id == 0 || block.id == 31) continue; AABB blockColl{(x + it.x * 16.0), @@ -119,18 +106,18 @@ bool World::isPlayerCollides(double X, double Y, double Z) { std::vector<Vector> World::GetSectionsList() { std::vector<Vector> sectionsList; - for (auto& it : cachedSections) { + for (auto& it : sections) { if (std::find(sectionsList.begin(), sectionsList.end(), it.first) == sectionsList.end()) sectionsList.push_back(it.first); } return sectionsList; } -static Section fallbackSection = Section(PackedSection()); +static Section fallbackSection; const Section &World::GetSection(Vector sectionPos) { - auto result = cachedSections.find(sectionPos); - if (result == cachedSections.end()) { + auto result = sections.find(sectionPos); + if (result == sections.end()) { LOG(ERROR) << "Accessed not loaded section " << sectionPos; return fallbackSection; } else { @@ -205,14 +192,14 @@ void World::DeleteEntity(unsigned int EntityId) } void World::ParseChunkData(std::shared_ptr<PacketBlockChange> packet) { - Block& block = this->GetBlock(packet->Position); + /*Block& block = this->GetBlock(packet->Position); block = Block(packet->BlockId >> 4, packet->BlockId & 15, block.light, block.sky); Vector sectionPos(std::floor(packet->Position.x / 16.0), std::floor(packet->Position.y / 16.0), std::floor(packet->Position.z / 16.0)); - EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos }); + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos });*/ } void World::ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet) { - std::vector<Vector> changedSections; + /*std::vector<Vector> changedSections; for (auto& it : packet->Records) { int x = (it.HorizontalPosition >> 4 & 15) + (packet->ChunkX * 16); int y = it.YCoordinate; @@ -226,17 +213,17 @@ void World::ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet) { changedSections.push_back(sectionPos); } for (auto& sectionPos: changedSections) - EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos }); + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos });*/ } void World::ParseChunkData(std::shared_ptr<PacketUnloadChunk> packet) { std::vector<std::map<Vector,Section>::iterator> toRemove; - for (auto it = cachedSections.begin(); it != cachedSections.end(); ++it) { + for (auto it = sections.begin(); it != sections.end(); ++it) { if (it->first.x == packet->ChunkX && it->first.z == packet->ChunkZ) toRemove.push_back(it); } for (auto& it : toRemove) { EventAgregator::PushEvent(EventType::ChunkDeleted, ChunkDeletedData{ it->first }); - cachedSections.erase(it); + sections.erase(it); } }
\ No newline at end of file diff --git a/src/World.hpp b/src/World.hpp index 6ff0619..a5cf60c 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -16,17 +16,15 @@ class World { int dimension = 0; - //std::map<Vector, PackedSection> sections; - std::map<Vector, Section> cachedSections; - PackedSection ParseSection(StreamInput *data, Vector position); + std::map<Vector, Section> sections; + + Section ParseSection(StreamInput *data, Vector position); std::vector<Entity> entities; std::mutex entitiesMutex; - Block& GetBlock(Vector worldPosition); - public: World(); diff --git a/src/main.cpp b/src/main.cpp index 0a6ad17..9c38814 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,12 +16,9 @@ const char *getTimeSinceProgramStart(void) { INITIALIZE_EASYLOGGINGPP -#ifdef WIN32 -int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, - _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { -#else -int main() { -#endif +#undef main + +int main(int argc, char** argv) { el::Configurations loggerConfiguration; el::Helpers::installCustomFormatSpecifier( el::CustomFormatSpecifier("%startTime", std::bind(getTimeSinceProgramStart))); @@ -37,6 +34,14 @@ int main() { LOG(WARNING) << "Sizeof EventData is " << sizeof(EventData); + try { + if (SDL_Init(0) == -1) + throw std::runtime_error("SDL initialization failed: " + std::string(SDL_GetError())); + } catch (std::exception& e) { + LOG(ERROR) << e.what(); + return -1; + } + ThreadGame game; std::thread threadGame(&ThreadGame::Execute, game); |