summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Block.hpp5
-rw-r--r--src/Render.cpp178
-rw-r--r--src/Render.hpp6
-rw-r--r--src/Renderer.hpp11
-rw-r--r--src/RendererSection.cpp120
-rw-r--r--src/RendererSection.hpp23
-rw-r--r--src/RendererWidget.cpp76
-rw-r--r--src/RendererWidget.hpp15
-rw-r--r--src/RendererWorld.cpp8
-rw-r--r--src/RendererWorld.hpp2
-rw-r--r--src/Section.cpp267
-rw-r--r--src/Section.hpp44
-rw-r--r--src/Socket.cpp43
-rw-r--r--src/Socket.hpp8
-rw-r--r--src/Stream.cpp5
-rw-r--r--src/Widget.cpp124
-rw-r--r--src/Widget.hpp74
-rw-r--r--src/World.cpp65
-rw-r--r--src/World.hpp8
-rw-r--r--src/main.cpp17
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);