summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaG1924 <12997935+LaG1924@users.noreply.github.com>2017-10-09 18:39:48 +0200
committerLaG1924 <12997935+LaG1924@users.noreply.github.com>2018-01-13 03:39:32 +0100
commita81bcb1942ddad5989115061338e72211443e633 (patch)
treecb1cc6feadb7dfb49f96cbc9b2a4f2bfb9ad8488
parent2017-10-07 (diff)
downloadAltCraft-a81bcb1942ddad5989115061338e72211443e633.tar
AltCraft-a81bcb1942ddad5989115061338e72211443e633.tar.gz
AltCraft-a81bcb1942ddad5989115061338e72211443e633.tar.bz2
AltCraft-a81bcb1942ddad5989115061338e72211443e633.tar.lz
AltCraft-a81bcb1942ddad5989115061338e72211443e633.tar.xz
AltCraft-a81bcb1942ddad5989115061338e72211443e633.tar.zst
AltCraft-a81bcb1942ddad5989115061338e72211443e633.zip
-rw-r--r--src/AssetManager.hpp7
-rw-r--r--src/Event.hpp8
-rw-r--r--src/Frustum.cpp63
-rw-r--r--src/Frustum.hpp35
-rw-r--r--src/GameState.cpp30
-rw-r--r--src/GameState.hpp35
-rw-r--r--src/GlobalState.cpp215
-rw-r--r--src/GlobalState.hpp14
-rw-r--r--src/NetworkClient.cpp77
-rw-r--r--src/NetworkClient.hpp8
-rw-r--r--src/Render.cpp47
-rw-r--r--src/Render.hpp2
-rw-r--r--src/RendererSection.cpp43
-rw-r--r--src/RendererWorld.cpp106
-rw-r--r--src/RendererWorld.hpp4
-rw-r--r--src/ThreadGame.cpp109
-rw-r--r--src/ThreadGame.hpp15
-rw-r--r--src/ThreadNetwork.cpp57
-rw-r--r--src/ThreadNetwork.hpp14
-rw-r--r--src/ThreadRender.cpp13
-rw-r--r--src/ThreadRender.hpp12
-rw-r--r--src/imgui_impl_sdl_gl3.cpp12
-rw-r--r--src/main.cpp47
23 files changed, 490 insertions, 483 deletions
diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp
index 50d9bbf..7cb7f8f 100644
--- a/src/AssetManager.hpp
+++ b/src/AssetManager.hpp
@@ -106,8 +106,9 @@ struct BlockModel {
};
struct FaceData {
struct Uv {
- int x1, y1, x2, y2;
+ int x1, y1, x2, y2;
} uv = { 0,0,0,0 };
+
std::string texture;
FaceDirection cullface = FaceDirection::none;
int rotation = 0;
@@ -120,6 +121,10 @@ struct BlockModel {
std::vector<ElementData> Elements;
};
+inline bool operator==(const BlockModel::ElementData::FaceData::Uv &lhs, const BlockModel::ElementData::FaceData::Uv &rhs) {
+ return lhs.x1 == rhs.x1 && lhs.y1 == rhs.y1 && lhs.x2 == rhs.x2 && lhs.y2 == rhs.y2;
+}
+
class AssetManager {
Texture *textureAtlas;
std::map<std::string, BlockId> assetIds;
diff --git a/src/Event.hpp b/src/Event.hpp
index 569be00..9ee445a 100644
--- a/src/Event.hpp
+++ b/src/Event.hpp
@@ -54,14 +54,12 @@ struct ChunkChangedData {
};
struct ConnectToServerData {
+ std::string username;
std::string address;
unsigned short port;
};
-class NetworkClient;
-
struct ConnectionSuccessfullData {
- std::shared_ptr<NetworkClient> ptr;
};
struct DisconnectData {
@@ -81,13 +79,9 @@ struct RequestNetworkClientData {
};
struct RegisterNetworkClientData {
- NetworkClient *ptr;
};
-class GameState;
-
struct PlayerConnectedData {
- std::shared_ptr<GameState> ptr;
};
struct RemoveLoadingScreenData {
diff --git a/src/Frustum.cpp b/src/Frustum.cpp
new file mode 100644
index 0000000..dbad920
--- /dev/null
+++ b/src/Frustum.cpp
@@ -0,0 +1,63 @@
+#include "Frustum.hpp"
+
+#include <glm/gtc/type_ptr.hpp>
+
+void Frustum::NormalizePlane(FrustumSide side) {
+ float magnitude = (float)sqrt(frustum[side][A] * frustum[side][A] + frustum[side][B] * frustum[side][B] + frustum[side][C] * frustum[side][C]);
+
+ frustum[side][A] /= magnitude;
+ frustum[side][B] /= magnitude;
+ frustum[side][C] /= magnitude;
+ frustum[side][D] /= magnitude;
+}
+
+void Frustum::UpdateFrustum(const glm::mat4& vpmat) {
+ vp = vpmat;
+ float *clip = glm::value_ptr(vp);
+
+ frustum[RIGHT][A] = clip[3] - clip[0];
+ frustum[RIGHT][B] = clip[7] - clip[4];
+ frustum[RIGHT][C] = clip[11] - clip[8];
+ frustum[RIGHT][D] = clip[15] - clip[12];
+ NormalizePlane(RIGHT);
+
+
+ frustum[LEFT][A] = clip[3] + clip[0];
+ frustum[LEFT][B] = clip[7] + clip[4];
+ frustum[LEFT][C] = clip[11] + clip[8];
+ frustum[LEFT][D] = clip[15] + clip[12];
+ NormalizePlane(LEFT);
+
+ frustum[BOTTOM][A] = clip[3] + clip[1];
+ frustum[BOTTOM][B] = clip[7] + clip[5];
+ frustum[BOTTOM][C] = clip[11] + clip[9];
+ frustum[BOTTOM][D] = clip[15] + clip[13];
+ NormalizePlane(BOTTOM);
+
+ frustum[TOP][A] = clip[3] - clip[1];
+ frustum[TOP][B] = clip[7] - clip[5];
+ frustum[TOP][C] = clip[11] - clip[9];
+ frustum[TOP][D] = clip[15] - clip[13];
+ NormalizePlane(TOP);
+
+ frustum[BACK][A] = clip[3] - clip[2];
+ frustum[BACK][B] = clip[7] - clip[6];
+ frustum[BACK][C] = clip[11] - clip[10];
+ frustum[BACK][D] = clip[15] - clip[14];
+ NormalizePlane(BACK);
+
+ frustum[FRONT][A] = clip[3] + clip[2];
+ frustum[FRONT][B] = clip[7] + clip[6];
+ frustum[FRONT][C] = clip[11] + clip[10];
+ frustum[FRONT][D] = clip[15] + clip[14];
+ NormalizePlane(FRONT);
+}
+
+bool Frustum::TestPoint(VectorF point) {
+ for (int i = 0; i < 6; i++) {
+ if (frustum[i][A] * point.x + frustum[i][B] * point.y + frustum[i][C] * point.z + frustum[i][D] <= 0) {
+ return false;
+ }
+ }
+ return true;
+} \ No newline at end of file
diff --git a/src/Frustum.hpp b/src/Frustum.hpp
new file mode 100644
index 0000000..4817cd4
--- /dev/null
+++ b/src/Frustum.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <glm/glm.hpp>
+#include "Vector.hpp"
+
+class Frustum {
+ enum FrustumSide {
+ RIGHT = 0,
+ LEFT,
+ BOTTOM,
+ TOP,
+ BACK,
+ FRONT,
+ };
+ enum PlaneData {
+ A = 0,
+ B,
+ C,
+ D,
+ };
+
+ glm::mat4 vp;
+ float frustum[6][4];
+ void NormalizePlane(FrustumSide side);
+
+public:
+ Frustum() = default;
+
+ ~Frustum() = default;
+
+ void UpdateFrustum(const glm::mat4& vpmat);
+
+ //Return true, if tested point is visible
+ bool TestPoint(VectorF point);
+}; \ No newline at end of file
diff --git a/src/GameState.cpp b/src/GameState.cpp
index 08b29b4..3020bde 100644
--- a/src/GameState.cpp
+++ b/src/GameState.cpp
@@ -1,12 +1,7 @@
#include "GameState.hpp"
#include "Event.hpp"
#include <iomanip>
-
-GameState::GameState(std::shared_ptr<NetworkClient> networkClient) : nc(networkClient) {
- //Front = glm::vec3(0.0f, 0.0f, -1.0f);
- //this->SetPosition(glm::vec3(0.0f, 0.0f, 3.0f));
- //this->WorldUp = glm::vec3(0.0f, 1.0f, 0.0f);
-}
+#include "GlobalState.hpp"
void GameState::Update(float deltaTime) {
if (g_IsGameStarted) {
@@ -15,26 +10,38 @@ void GameState::Update(float deltaTime) {
auto delta = clock.now() - timeOfPreviousSendedPacket;
using namespace std::chrono_literals;
if (delta >= 50ms) {
+ packetsMutex.lock();
auto packetToSend = std::make_shared<PacketPlayerPositionAndLookSB>(player->pos.x, player->pos.y, player->pos.z, player->yaw, player->pitch, player->onGround);
- nc->SendPacket(packetToSend);
+ packets.push(packetToSend);
timeOfPreviousSendedPacket = clock.now();
+ packetsMutex.unlock();
}
bool prevOnGround = player->onGround;
world.UpdatePhysics(deltaTime);
if (player->onGround != prevOnGround) {
+ packetsMutex.lock();
auto updatePacket = std::make_shared<PacketPlayerPosition>(player->pos.x, player->pos.y, player->pos.z, player->onGround);
- nc->SendPacket(updatePacket);
+ packets.push(updatePacket);
+ packetsMutex.unlock();
}
}
}
-void GameState::UpdatePacket()
+void GameState::UpdatePacket(NetworkClient *nc)
{
+
+ packetsMutex.lock();
+ while (!packets.empty()) {
+ nc->SendPacket(packets.front());
+ packets.pop();
+ }
+ packetsMutex.unlock();
+
//Packet handling
auto ptr = nc->ReceivePacket();
- while (ptr) {
+ if (ptr) {
switch ((PacketNamePlayCB)ptr->GetPacketId()) {
case SpawnObject: {
auto packet = std::static_pointer_cast<PacketSpawnObject>(ptr);
@@ -202,7 +209,7 @@ void GameState::UpdatePacket()
g_ReducedDebugInfo = packet->ReducedDebugInfo;
LOG(INFO) << "Gamemode is " << g_Gamemode << ", Difficulty is " << (int)g_Difficulty
<< ", Level Type is " << g_LevelType;
- EventAgregator::PushEvent(EventType::PlayerConnected, PlayerConnectedData{ gs });
+ EventAgregator::PushEvent(EventType::PlayerConnected, PlayerConnectedData{});
break;
}
case Map:
@@ -393,7 +400,6 @@ void GameState::UpdatePacket()
case EntityEffect:
break;
}
- ptr = nc->ReceivePacket();
}
while (!playerInventory.pendingTransactions.empty()) {
nc->SendPacket(std::make_shared<PacketClickWindow>(playerInventory.pendingTransactions.front()));
diff --git a/src/GameState.hpp b/src/GameState.hpp
index 31ec928..0551f1c 100644
--- a/src/GameState.hpp
+++ b/src/GameState.hpp
@@ -11,13 +11,17 @@
#include "Window.hpp"
class GameState {
- std::shared_ptr<NetworkClient> nc;
+ std::mutex packetsMutex;
+ std::queue<std::shared_ptr<Packet>> packets;
public:
- GameState(std::shared_ptr<NetworkClient> networkClient);
+
+ GameState() = default;
+
+ ~GameState() = default;
void Update(float deltaTime);
- void UpdatePacket();
+ void UpdatePacket(NetworkClient *nc);
enum Direction {
FORWARD, BACKWARD, LEFT, RIGHT, JUMP
@@ -26,19 +30,6 @@ public:
void HandleRotation(double yaw, double pitch);
glm::mat4 GetViewMatrix();
Entity* player;
- /*void updateCameraVectors();
-
- float Yaw();
- float Pitch();
- void SetYaw(float yaw);
- void SetPitch(float pitch);
-
- glm::vec3 Position();
- void SetPosition(glm::vec3 Position);
- glm::vec3 Front;
- glm::vec3 Up;
- glm::vec3 Right;
- glm::vec3 WorldUp;*/
World world;
@@ -59,23 +50,11 @@ public:
bool g_PlayerCreativeMode = false;
float g_PlayerFlyingSpeed = 0;
float g_PlayerFovModifier = 0;
- /*float g_PlayerPitch = 0;
- float g_PlayerYaw = 0;
- double g_PlayerX = 0;
- double g_PlayerY = 0;
- double g_PlayerZ = 0;*/
float g_PlayerHealth = 0;
- /*bool g_OnGround = true;
- double g_PlayerVelocityX = 0;
- double g_PlayerVelocityY = 0;
- double g_PlayerVelocityZ = 0;*/
-
long long WorldAge = 0;
long long TimeOfDay = 0;
- std::shared_ptr<GameState> gs;
-
Window playerInventory;
std::vector<Window> openedWindows;
};
diff --git a/src/GlobalState.cpp b/src/GlobalState.cpp
new file mode 100644
index 0000000..49dbf2b
--- /dev/null
+++ b/src/GlobalState.cpp
@@ -0,0 +1,215 @@
+#include "GlobalState.hpp"
+
+#include "NetworkClient.hpp"
+#include "GameState.hpp"
+#include "Render.hpp"
+#include "DebugInfo.hpp"
+
+
+//Global game variables
+std::unique_ptr<NetworkClient> nc;
+std::unique_ptr<GameState> gs;
+std::unique_ptr<Render> render;
+std::thread threadGs;
+bool isRunning;
+bool isPhysRunning;
+EventListener listener;
+bool isMoving[5] = { 0,0,0,0,0 };
+std::thread threadPhys;
+
+void PhysExec();
+
+void InitEvents() {
+ /*
+ * Network Events
+ */
+
+ listener.RegisterHandler(EventType::Exit, [](EventData eventData) {
+ isRunning = false;
+ });
+
+ listener.RegisterHandler(EventType::ConnectToServer, [](EventData eventData) {
+ auto data = std::get<ConnectToServerData>(eventData);
+ if (data.address == "" || data.port == 0)
+ LOG(FATAL) << "NOT VALID CONNECT-TO-SERVER EVENT";
+ if (nc != nullptr) {
+ LOG(ERROR) << "Already connected";
+ return;
+ }
+ LOG(INFO) << "Connecting to server";
+ EventAgregator::PushEvent(EventType::Connecting, ConnectingData{});
+ try {
+ nc = std::make_unique<NetworkClient>(data.address, data.port, data.username);
+ }
+ catch (std::exception &e) {
+ LOG(WARNING) << "Connection failed";
+ EventAgregator::PushEvent(EventType::ConnectionFailed, ConnectionFailedData{ e.what() });
+ return;
+ }
+ LOG(INFO) << "Connected to server";
+ EventAgregator::PushEvent(EventType::ConnectionSuccessfull, ConnectionSuccessfullData{});
+ });
+
+ listener.RegisterHandler(EventType::Disconnect, [](EventData eventData) {
+ auto data = std::get<DisconnectData>(eventData);
+ EventAgregator::PushEvent(EventType::Disconnected, DisconnectedData{ data.reason });
+ LOG(INFO) << "Disconnected: " << data.reason;
+ nc.reset();
+ });
+
+ listener.RegisterHandler(EventType::NetworkClientException, [](EventData eventData) {
+ auto data = std::get<NetworkClientExceptionData>(eventData);
+ EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ data.what });
+ });
+
+ /*
+ * GameState Events
+ */
+
+ listener.RegisterHandler(EventType::Exit, [](EventData eventData) {
+ isRunning = false;
+ });
+
+ listener.RegisterHandler(EventType::ConnectionSuccessfull, [](EventData eventData) {
+ auto data = std::get<ConnectionSuccessfullData>(eventData);
+ gs = std::make_unique<GameState>();
+ isPhysRunning = true;
+ threadPhys = std::thread(&PhysExec);
+ });
+
+ listener.RegisterHandler(EventType::Disconnected, [](EventData eventData) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ if (!gs)
+ return;
+ isPhysRunning = false;
+ threadPhys.join();
+ gs.reset();
+ });
+}
+
+void PhysExec() {
+ EventListener listener;
+
+ listener.RegisterHandler(EventType::KeyPressed, [](EventData eventData) {
+ if (!gs)
+ return;
+ switch (std::get<KeyPressedData>(eventData).key) {
+ case SDL_SCANCODE_W:
+ isMoving[GameState::FORWARD] = true;
+ break;
+ case SDL_SCANCODE_A:
+ isMoving[GameState::LEFT] = true;
+ break;
+ case SDL_SCANCODE_S:
+ isMoving[GameState::BACKWARD] = true;
+ break;
+ case SDL_SCANCODE_D:
+ isMoving[GameState::RIGHT] = true;
+ break;
+ case SDL_SCANCODE_SPACE:
+ isMoving[GameState::JUMP] = true;
+ break;
+ }
+ });
+
+ listener.RegisterHandler(EventType::KeyReleased, [](EventData eventData) {
+ if (!gs)
+ return;
+ switch (std::get<KeyReleasedData>(eventData).key) {
+ case SDL_SCANCODE_W:
+ isMoving[GameState::FORWARD] = false;
+ break;
+ case SDL_SCANCODE_A:
+ isMoving[GameState::LEFT] = false;
+ break;
+ case SDL_SCANCODE_S:
+ isMoving[GameState::BACKWARD] = false;
+ break;
+ case SDL_SCANCODE_D:
+ isMoving[GameState::RIGHT] = false;
+ break;
+ case SDL_SCANCODE_SPACE:
+ isMoving[GameState::JUMP] = false;
+ break;
+ }
+ });
+
+ listener.RegisterHandler(EventType::MouseMoved, [](EventData eventData) {
+ if (!gs)
+ return;
+ auto data = std::get<MouseMovedData>(eventData);
+ gs->HandleRotation(data.x, data.y);
+ });
+
+ LoopExecutionTimeController timer(std::chrono::milliseconds(8));
+
+ while (isPhysRunning) {
+ DebugInfo::gameThreadTime = timer.GetRealDeltaS() * 1000'00.0f;
+
+ if (isMoving[GameState::FORWARD])
+ gs->HandleMovement(GameState::FORWARD, timer.GetRealDeltaS());
+ if (isMoving[GameState::BACKWARD])
+ gs->HandleMovement(GameState::BACKWARD, timer.GetRealDeltaS());
+ if (isMoving[GameState::LEFT])
+ gs->HandleMovement(GameState::LEFT, timer.GetRealDeltaS());
+ if (isMoving[GameState::RIGHT])
+ gs->HandleMovement(GameState::RIGHT, timer.GetRealDeltaS());
+ if (isMoving[GameState::JUMP])
+ gs->HandleMovement(GameState::JUMP, timer.GetRealDeltaS());
+
+ gs->Update(timer.GetRealDeltaS());
+
+ while (listener.IsEventsQueueIsNotEmpty())
+ listener.HandleEvent();
+
+ timer.Update();
+ }
+}
+
+void GsExec() {
+ LoopExecutionTimeController timer(std::chrono::milliseconds(16));
+
+ while (isRunning) {
+ try {
+ while (nc && gs) {
+ nc->UpdatePacket();
+
+ gs->UpdatePacket(nc.get());
+ while (listener.IsEventsQueueIsNotEmpty())
+ listener.HandleEvent();
+ }
+ } catch (std::exception &e) {
+ EventAgregator::PushEvent(EventType::NetworkClientException, NetworkClientExceptionData{ e.what() });
+ }
+
+ while (listener.IsEventsQueueIsNotEmpty())
+ listener.HandleEvent();
+
+ timer.Update();
+ }
+ if (isPhysRunning) {
+ isPhysRunning = false;
+ threadPhys.join();
+ }
+ nc.reset();
+ gs.reset();
+}
+
+void GlobalState::Exec() {
+ render = std::make_unique<Render>(900, 480, "AltCraft");
+ isRunning = true;
+ InitEvents();
+ threadGs = std::thread(&GsExec);
+ render->ExecuteRenderLoop();
+ isRunning = false;
+ threadGs.join();
+ render.reset();
+}
+
+GameState *GlobalState::GetGameState() {
+ return gs.get();
+}
+
+Render *GlobalState::GetRender() {
+ return render.get();
+} \ No newline at end of file
diff --git a/src/GlobalState.hpp b/src/GlobalState.hpp
new file mode 100644
index 0000000..29ab7a0
--- /dev/null
+++ b/src/GlobalState.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <memory>
+#include <thread>
+
+class NetworkClient;
+class GameState;
+class Render;
+
+struct GlobalState {
+ static GameState *GetGameState();
+ static Render *GetRender();
+ static void Exec();
+}; \ No newline at end of file
diff --git a/src/NetworkClient.cpp b/src/NetworkClient.cpp
index 74d7804..dd467e8 100644
--- a/src/NetworkClient.cpp
+++ b/src/NetworkClient.cpp
@@ -37,72 +37,49 @@ NetworkClient::NetworkClient(std::string address, unsigned short port, std::stri
throw std::logic_error("Received username is not sended username: "+response->Username+" != "+username);
}
- state = Play;
+ timeOfLastKeepAlivePacket = std::chrono::steady_clock::now();
- isActive = true;
- networkThread = std::thread(&NetworkClient::NetworkLoop, this);
+ state = Play;
}
NetworkClient::~NetworkClient() {
- isActive = false;
- networkThread.join();
}
std::shared_ptr<Packet> NetworkClient::ReceivePacket() {
if (toReceive.empty())
return std::shared_ptr < Packet > (nullptr);
- toReceiveMutex.lock();
auto ret = toReceive.front();
toReceive.pop();
- toReceiveMutex.unlock();
return ret;
}
void NetworkClient::SendPacket(std::shared_ptr<Packet> packet) {
- toSendMutex.lock();
toSend.push(packet);
- toSendMutex.unlock();
}
-void NetworkClient::NetworkLoop() {
- auto timeOfLastKeepAlivePacket = std::chrono::steady_clock::now();
- el::Helpers::setThreadName("Network");
- bool validEnded = true;
-
- try {
- while (isActive) {
- toSendMutex.lock();
- while (!toSend.empty()) {
- if (toSend.front() != nullptr)
- network.SendPacket(*toSend.front(), compressionThreshold);
- toSend.pop();
- }
- toSendMutex.unlock();
- auto packet = network.ReceivePacket(state, compressionThreshold >= 0);
- if (packet.get() != nullptr) {
- if (packet->GetPacketId() != PacketNamePlayCB::KeepAliveCB) {
- toReceiveMutex.lock();
- toReceive.push(packet);
- toReceiveMutex.unlock();
- } else {
- timeOfLastKeepAlivePacket = std::chrono::steady_clock::now();
- auto packetKeepAlive = std::static_pointer_cast<PacketKeepAliveCB>(packet);
- auto packetKeepAliveSB = std::make_shared<PacketKeepAliveSB>(packetKeepAlive->KeepAliveId);
- network.SendPacket(*packetKeepAliveSB, compressionThreshold);
- }
- }
- using namespace std::chrono_literals;
- if (std::chrono::steady_clock::now() - timeOfLastKeepAlivePacket > 20s) {
- auto disconnectPacket = std::make_shared<PacketDisconnectPlay>();
- disconnectPacket->Reason = "Timeout: server not respond";
- toReceiveMutex.lock();
- toReceive.push(disconnectPacket);
- toReceiveMutex.unlock();
- break;
- }
- }
- } catch (std::exception &e) {
- EventAgregator::PushEvent(EventType::NetworkClientException, NetworkClientExceptionData{ e.what() });
- validEnded = false;
- }
+void NetworkClient::UpdatePacket() {
+ while (!toSend.empty()) {
+ if (toSend.front() != nullptr)
+ network.SendPacket(*toSend.front(), compressionThreshold);
+ toSend.pop();
+ }
+
+ auto packet = network.ReceivePacket(state, compressionThreshold >= 0);
+ if (packet.get() != nullptr) {
+ if (packet->GetPacketId() != PacketNamePlayCB::KeepAliveCB) {
+ toReceive.push(packet);
+ }
+ else {
+ timeOfLastKeepAlivePacket = std::chrono::steady_clock::now();
+ auto packetKeepAlive = std::static_pointer_cast<PacketKeepAliveCB>(packet);
+ auto packetKeepAliveSB = std::make_shared<PacketKeepAliveSB>(packetKeepAlive->KeepAliveId);
+ network.SendPacket(*packetKeepAliveSB, compressionThreshold);
+ }
+ }
+ using namespace std::chrono_literals;
+ if (std::chrono::steady_clock::now() - timeOfLastKeepAlivePacket > 20s) {
+ auto disconnectPacket = std::make_shared<PacketDisconnectPlay>();
+ disconnectPacket->Reason = "Timeout: server not respond";
+ toReceive.push(disconnectPacket);
+ }
} \ No newline at end of file
diff --git a/src/NetworkClient.hpp b/src/NetworkClient.hpp
index acb3ecb..a26c262 100644
--- a/src/NetworkClient.hpp
+++ b/src/NetworkClient.hpp
@@ -9,19 +9,17 @@
class NetworkClient {
Network network;
- std::thread networkThread;
- std::mutex toSendMutex;
- std::mutex toReceiveMutex;
std::queue <std::shared_ptr<Packet>> toSend;
std::queue <std::shared_ptr<Packet>> toReceive;
- bool isActive=true;
ConnectionState state;
- void NetworkLoop();
int compressionThreshold = -1;
+ std::chrono::steady_clock::time_point timeOfLastKeepAlivePacket;
public:
NetworkClient(std::string address, unsigned short port, std::string username);
~NetworkClient();
std::shared_ptr <Packet> ReceivePacket();
void SendPacket(std::shared_ptr<Packet> packet);
+
+ void UpdatePacket();
}; \ No newline at end of file
diff --git a/src/Render.cpp b/src/Render.cpp
index 0011e1c..6bf3eb3 100644
--- a/src/Render.cpp
+++ b/src/Render.cpp
@@ -5,6 +5,7 @@
#include "AssetManager.hpp"
#include "Event.hpp"
#include "DebugInfo.hpp"
+#include "GlobalState.hpp"
#include <imgui.h>
#include "imgui_impl_sdl_gl3.h"
@@ -153,8 +154,8 @@ void Render::HandleEvents() {
case SDL_WINDOWEVENT_FOCUS_LOST:
HasFocus = false;
SetMouseCapture(false);
- if (state == GlobalState::Playing)
- state = GlobalState::Paused;
+ if (state == GameState::Playing)
+ state = GameState::Paused;
isDisplayInventory = false;
break;
}
@@ -163,22 +164,22 @@ void Render::HandleEvents() {
case SDL_KEYDOWN:
switch (event.key.keysym.scancode) {
case SDL_SCANCODE_ESCAPE:
- if (state == GlobalState::Playing) {
- state = GlobalState::Paused;
+ if (state == GameState::Playing) {
+ state = GameState::Paused;
SetMouseCapture(false);
isDisplayInventory = false;
}
- else if (state == GlobalState::Paused) {
- state = GlobalState::Playing;
+ else if (state == GameState::Paused) {
+ state = GameState::Playing;
SetMouseCapture(true);
}
- else if (state == GlobalState::MainMenu) {
+ else if (state == GameState::MainMenu) {
LOG(INFO) << "Received close event by esc";
isRunning = false;
}
break;
case SDL_SCANCODE_E:
- if (state != GlobalState::Playing)
+ if (state != GameState::Playing)
return;
isDisplayInventory = !isDisplayInventory;
SetMouseCapture(!isDisplayInventory);
@@ -230,13 +231,13 @@ void Render::ExecuteRenderLoop() {
listener.RegisterHandler(EventType::PlayerConnected, [this](EventData eventData) {
auto data = std::get<PlayerConnectedData>(eventData);
stateString = "Loading terrain...";
- world = std::make_unique<RendererWorld>(data.ptr);
+ world = std::make_unique<RendererWorld>(GlobalState::GetGameState());
});
listener.RegisterHandler(EventType::RemoveLoadingScreen, [this](EventData eventData) {
stateString = "Playing";
renderWorld = true;
- state = GlobalState::Playing;
+ state = GameState::Playing;
SetMouseCapture(true);
glClearColor(0, 0, 0, 1.0f);
});
@@ -245,7 +246,7 @@ void Render::ExecuteRenderLoop() {
stateString = "Connection failed: " + std::get<ConnectionFailedData>(eventData).reason;
renderWorld = false;
world.reset();
- state = GlobalState::MainMenu;
+ state = GameState::MainMenu;
glClearColor(0.8, 0.8, 0.8, 1.0f);
});
@@ -253,21 +254,21 @@ void Render::ExecuteRenderLoop() {
stateString = "Disconnected: " + std::get<DisconnectedData>(eventData).reason;
renderWorld = false;
world.reset();
- state = GlobalState::MainMenu;
+ state = GameState::MainMenu;
SetMouseCapture(false);
glClearColor(0.8, 0.8, 0.8, 1.0f);
});
listener.RegisterHandler(EventType::Connecting, [this](EventData eventData) {
stateString = "Connecting to the server...";
- state = GlobalState::Loading;
+ state = GameState::Loading;
});
- state = GlobalState::MainMenu;
+ state = GameState::MainMenu;
while (isRunning) {
HandleEvents();
- if (HasFocus && state == GlobalState::Playing) UpdateKeyboard();
+ if (HasFocus && state == GameState::Playing) UpdateKeyboard();
if (isMouseCaptured) HandleMouseCapture();
glCheckError();
@@ -311,14 +312,16 @@ void Render::RenderGui() {
switch (state) {
- case GlobalState::MainMenu: {
+ case GameState::MainMenu: {
ImGui::SetNextWindowPosCenter();
ImGui::Begin("Menu",0, windowFlags);
static char buff[512] = "127.0.0.1";
static int port = 25565;
+ static char buffName[512] = "HelloOne";
if (ImGui::Button("Connect")) {
- EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ buff, (unsigned short)port });
+ EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ std::string(buffName), buff, (unsigned short)port });
}
+ ImGui::InputText("Username", buffName, 512);
ImGui::InputText("Address", buff, 512);
ImGui::InputInt("Port", &port);
ImGui::Separator();
@@ -327,9 +330,9 @@ void Render::RenderGui() {
ImGui::End();
break;
}
- case GlobalState::Loading:
+ case GameState::Loading:
break;
- case GlobalState::Playing:
+ case GameState::Playing:
if (isDisplayInventory) {
auto renderSlot = [](const SlotData &slot, int i) -> bool {
return ImGui::Button(((slot.BlockId == -1 ? " ##" :
@@ -419,11 +422,11 @@ void Render::RenderGui() {
ImGui::End();
}
break;
- case GlobalState::Paused: {
+ case GameState::Paused: {
ImGui::SetNextWindowPosCenter();
ImGui::Begin("Pause Menu", 0, windowFlags);
if (ImGui::Button("Continue")) {
- state = GlobalState::Playing;
+ state = GameState::Playing;
SetMouseCapture(true);
}
ImGui::Separator();
@@ -460,7 +463,7 @@ void Render::RenderGui() {
ImGui::End();
break;
}
- case GlobalState::InitialLoading:
+ case GameState::InitialLoading:
break;
}
diff --git a/src/Render.hpp b/src/Render.hpp
index 2a48356..f9d3497 100644
--- a/src/Render.hpp
+++ b/src/Render.hpp
@@ -24,7 +24,7 @@ class Render {
bool isWireframe = false;
bool isDisplayInventory = false;
- enum GlobalState {
+ enum GameState {
InitialLoading,
MainMenu,
Loading,
diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp
index c813071..55761f7 100644
--- a/src/RendererSection.cpp
+++ b/src/RendererSection.cpp
@@ -227,7 +227,30 @@ void RendererSectionData::AddFacesByBlockModel(const std::vector<Vector> &sectio
Vector t = element.to - element.from;
VectorF elementSize(VectorF(t.x,t.y,t.z) / 16.0f);
VectorF elementOrigin(VectorF(element.from.x,element.from.y,element.from.z) / 16.0f);
- elementTransform = glm::translate(transform, elementOrigin.glm());
+ elementTransform = transform;
+
+ /*if (element.rotationAngle != 0) {
+ const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
+ const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
+ const glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
+ const glm::vec3 *targetAxis = nullptr;
+ switch (element.rotationAxis) {
+ case BlockModel::ElementData::Axis::x:
+ targetAxis = &xAxis;
+ break;
+ case BlockModel::ElementData::Axis::y:
+ targetAxis = &yAxis;
+ break;
+ case BlockModel::ElementData::Axis::z:
+ targetAxis = &zAxis;
+ break;
+ }
+ VectorF rotateOrigin(VectorF(element.rotationOrigin.x, element.rotationOrigin.y, element.rotationOrigin.z) / 16.0f);
+ elementTransform = glm::translate(elementTransform, -rotateOrigin.glm());
+ elementTransform = glm::rotate(elementTransform, glm::radians(float(45)), yAxis);
+ elementTransform = glm::translate(elementTransform, rotateOrigin.glm());
+ }*/
+ elementTransform = glm::translate(elementTransform, elementOrigin.glm());
elementTransform = glm::scale(elementTransform, elementSize.glm());
for (const auto& face : element.faces) {
@@ -301,6 +324,24 @@ void RendererSectionData::AddFacesByBlockModel(const std::vector<Vector> &sectio
textureName = model.Textures.find(std::string(textureName.begin()+1,textureName.end()))->second;
}
glm::vec4 texture = AssetManager::Instance().GetTextureByAssetName("minecraft/textures/" + textureName);
+
+ if (!(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,16,0,16 }) && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,0,0 })
+ && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,16,16 })) {
+ double x = face.second.uv.x1;
+ double y = face.second.uv.x1;
+ double w = face.second.uv.x2 - face.second.uv.x1;
+ double h = face.second.uv.y2 - face.second.uv.y1;
+ x /= 16.0;
+ y /= 16.0;
+ w /= 16.0;
+ h /= 16.0;
+ double X = texture.x;
+ double Y = texture.y;
+ double W = texture.z;
+ double H = texture.w;
+
+ texture = glm::vec4{ X + x * W, Y + y * H, w * W , h * H };
+ }
textures.push_back(texture);
if (face.second.tintIndex)
colors.push_back(glm::vec3(0.275, 0.63, 0.1));
diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp
index c50ff44..0438613 100644
--- a/src/RendererWorld.cpp
+++ b/src/RendererWorld.cpp
@@ -1,106 +1,6 @@
#include "RendererWorld.hpp"
#include "DebugInfo.hpp"
-
-class Frustum {
- enum FrustumSide
- {
- RIGHT = 0,
- LEFT,
- BOTTOM,
- TOP,
- BACK,
- FRONT,
- };
-
- enum PlaneData
- {
- A = 0,
- B,
- C,
- D,
- };
-
- glm::mat4 vp;
-
- float frustum[6][4];
-
- void NormalizePlane(FrustumSide side)
- {
- float magnitude = (float)sqrt(frustum[side][A] * frustum[side][A] +
- frustum[side][B] * frustum[side][B] +
- frustum[side][C] * frustum[side][C]);
-
- frustum[side][A] /= magnitude;
- frustum[side][B] /= magnitude;
- frustum[side][C] /= magnitude;
- frustum[side][D] /= magnitude;
- }
-
-public:
- Frustum() {}
-
- ~Frustum() {}
-
- void UpdateFrustum(const glm::mat4& vpmat) {
- vp = vpmat;
- return;
-
- float *clip = glm::value_ptr(vp);
-
-
- frustum[RIGHT][A] = clip[3] - clip[0];
- frustum[RIGHT][B] = clip[7] - clip[4];
- frustum[RIGHT][C] = clip[11] - clip[8];
- frustum[RIGHT][D] = clip[15] - clip[12];
- NormalizePlane(RIGHT);
-
-
- frustum[LEFT][A] = clip[3] + clip[0];
- frustum[LEFT][B] = clip[7] + clip[4];
- frustum[LEFT][C] = clip[11] + clip[8];
- frustum[LEFT][D] = clip[15] + clip[12];
- NormalizePlane(LEFT);
-
- frustum[BOTTOM][A] = clip[3] + clip[1];
- frustum[BOTTOM][B] = clip[7] + clip[5];
- frustum[BOTTOM][C] = clip[11] + clip[9];
- frustum[BOTTOM][D] = clip[15] + clip[13];
- NormalizePlane(BOTTOM);
-
- frustum[TOP][A] = clip[3] - clip[1];
- frustum[TOP][B] = clip[7] - clip[5];
- frustum[TOP][C] = clip[11] - clip[9];
- frustum[TOP][D] = clip[15] - clip[13];
- NormalizePlane(TOP);
-
- frustum[BACK][A] = clip[3] - clip[2];
- frustum[BACK][B] = clip[7] - clip[6];
- frustum[BACK][C] = clip[11] - clip[10];
- frustum[BACK][D] = clip[15] - clip[14];
- NormalizePlane(BACK);
-
- frustum[FRONT][A] = clip[3] + clip[2];
- frustum[FRONT][B] = clip[7] + clip[6];
- frustum[FRONT][C] = clip[11] + clip[10];
- frustum[FRONT][D] = clip[15] + clip[14];
- NormalizePlane(FRONT);
- }
-
- //Return true, if tested point is visible
- bool TestPoint(VectorF point) {
- glm::vec4 p = vp * glm::vec4(point.glm(), 1);
- glm::vec3 res = glm::vec3(p) / p.w;
- return (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0);
- for (int i = 0; i < 6; i++)
- {
- if (frustum[i][A] * point.x + frustum[i][B] * point.y + frustum[i][C] * point.z + frustum[i][D] <= 0)
- {
- return false;
- }
- }
- return true;
- }
-};
+#include "Frustum.hpp"
void RendererWorld::WorkerFunction(size_t workerId) {
EventListener tasksListener;
@@ -187,7 +87,7 @@ void RendererWorld::UpdateAllSections(VectorF playerPos)
}
}
-RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr):gs(ptr) {
+RendererWorld::RendererWorld(GameState* ptr):gs(ptr) {
frustum = std::make_unique<Frustum>();
MaxRenderingDistance = 2;
numOfWorkers = 2;
@@ -476,5 +376,5 @@ void RendererWorld::Update(double timeToUpdate) {
}
GameState* RendererWorld::GameStatePtr() {
- return gs.get();
+ return gs;
} \ No newline at end of file
diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp
index b020006..e7bd512 100644
--- a/src/RendererWorld.hpp
+++ b/src/RendererWorld.hpp
@@ -12,7 +12,7 @@ class Frustum;
class RendererWorld {
//General
- std::shared_ptr<GameState> gs;
+ GameState *gs;
EventListener listener;
size_t numOfWorkers;
size_t currentWorker = 0;
@@ -38,7 +38,7 @@ class RendererWorld {
Shader *skyShader;
RendererSky rendererSky;
public:
- RendererWorld(std::shared_ptr<GameState> ptr);
+ RendererWorld(GameState* ptr);
~RendererWorld();
void Render(RenderState& renderState);
diff --git a/src/ThreadGame.cpp b/src/ThreadGame.cpp
deleted file mode 100644
index 3ca9b13..0000000
--- a/src/ThreadGame.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "ThreadGame.hpp"
-
-#include "DebugInfo.hpp"
-
-ThreadGame::ThreadGame() {
-
-}
-
-ThreadGame::~ThreadGame() {
-
-}
-
-void ThreadGame::Execute() {
-
- EventListener listener;
-
- listener.RegisterHandler(EventType::Exit, [this] (EventData eventData) {
- isRunning = false;
- });
-
- listener.RegisterHandler(EventType::ConnectionSuccessfull, [this](EventData eventData) {
- auto data = std::get<ConnectionSuccessfullData>(eventData);
- gs = std::make_shared<GameState>(data.ptr);
- gs->gs = gs;
- });
-
- listener.RegisterHandler(EventType::Disconnected, [this](EventData eventData) {
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- if (!gs)
- return;
- gs->gs.reset();
- gs.reset();
- });
-
- listener.RegisterHandler(EventType::KeyPressed, [this](EventData eventData) {
- if (!gs)
- return;
- switch (std::get<KeyPressedData>(eventData).key) {
- case SDL_SCANCODE_W:
- isMoving[GameState::FORWARD] = true;
- break;
- case SDL_SCANCODE_A:
- isMoving[GameState::LEFT] = true;
- break;
- case SDL_SCANCODE_S:
- isMoving[GameState::BACKWARD] = true;
- break;
- case SDL_SCANCODE_D:
- isMoving[GameState::RIGHT] = true;
- break;
- case SDL_SCANCODE_SPACE:
- isMoving[GameState::JUMP] = true;
- break;
- }
- });
-
- listener.RegisterHandler(EventType::KeyReleased, [this](EventData eventData) {
- if (!gs)
- return;
- switch (std::get<KeyReleasedData>(eventData).key) {
- case SDL_SCANCODE_W:
- isMoving[GameState::FORWARD] = false;
- break;
- case SDL_SCANCODE_A:
- isMoving[GameState::LEFT] = false;
- break;
- case SDL_SCANCODE_S:
- isMoving[GameState::BACKWARD] = false;
- break;
- case SDL_SCANCODE_D:
- isMoving[GameState::RIGHT] = false;
- break;
- case SDL_SCANCODE_SPACE:
- isMoving[GameState::JUMP] = false;
- break;
- }
- });
-
- listener.RegisterHandler(EventType::MouseMoved, [this](EventData eventData) {
- if (!gs)
- return;
- auto data = std::get<MouseMovedData>(eventData);
- gs->HandleRotation(data.x, data.y);
- });
-
- LoopExecutionTimeController timer(std::chrono::milliseconds(int(1.0f / 120.0f * 1000.0f)));
-
- while (isRunning) {
- DebugInfo::gameThreadTime = timer.GetRealDeltaS() * 1000'00.0f;
- if (gs != nullptr)
- gs->Update(timer.GetRealDeltaS());
- listener.HandleEvent();
- if (gs != nullptr) {
- gs->UpdatePacket();
- if (isMoving[GameState::FORWARD])
- gs->HandleMovement(GameState::FORWARD, timer.GetRealDeltaS());
- if (isMoving[GameState::BACKWARD])
- gs->HandleMovement(GameState::BACKWARD, timer.GetRealDeltaS());
- if (isMoving[GameState::LEFT])
- gs->HandleMovement(GameState::LEFT, timer.GetRealDeltaS());
- if (isMoving[GameState::RIGHT])
- gs->HandleMovement(GameState::RIGHT, timer.GetRealDeltaS());
- if (isMoving[GameState::JUMP])
- gs->HandleMovement(GameState::JUMP, timer.GetRealDeltaS());
- }
- timer.Update();
- }
- gs.reset();
-}
diff --git a/src/ThreadGame.hpp b/src/ThreadGame.hpp
deleted file mode 100644
index 41676d6..0000000
--- a/src/ThreadGame.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "Thread.hpp"
-#include "GameState.hpp"
-#include "Event.hpp"
-
-class ThreadGame: Thread {
- std::shared_ptr<GameState> gs;
- bool isRunning = true;
- bool isMoving[5] = { 0,0,0,0,0 };
-public:
- ThreadGame();
- ~ThreadGame();
- void Execute() override;
-}; \ No newline at end of file
diff --git a/src/ThreadNetwork.cpp b/src/ThreadNetwork.cpp
deleted file mode 100644
index 5a8a61a..0000000
--- a/src/ThreadNetwork.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "ThreadNetwork.hpp"
-
-ThreadNetwork::ThreadNetwork() {
-
-}
-
-ThreadNetwork::~ThreadNetwork() {
-}
-
-void ThreadNetwork::Execute() {
- EventListener listener;
-
- listener.RegisterHandler(EventType::Exit, [this] (EventData eventData) {
- isRunning = false;
- });
-
- listener.RegisterHandler(EventType::ConnectToServer, [this](EventData eventData) {
- auto data = std::get<ConnectToServerData>(eventData);
- if (data.address == "" || data.port == 0)
- LOG(FATAL) << "NOT VALID CONNECT-TO-SERVER EVENT";
- if (nc != nullptr) {
- LOG(ERROR) << "Already connected";
- return;
- }
- LOG(INFO) << "Connecting to server";
- EventAgregator::PushEvent(EventType::Connecting, ConnectingData{});
- try {
- nc = std::make_shared<NetworkClient>(data.address, data.port, "HelloOne");
- } catch (std::exception &e) {
- LOG(WARNING) << "Connection failed";
- EventAgregator::PushEvent(EventType::ConnectionFailed, ConnectionFailedData{e.what()});
- return;
- }
- LOG(INFO) << "Connected to server";
- EventAgregator::PushEvent(EventType::ConnectionSuccessfull, ConnectionSuccessfullData{nc});
- });
-
- listener.RegisterHandler(EventType::Disconnect, [this](EventData eventData) {
- auto data = std::get<DisconnectData>(eventData);
- EventAgregator::PushEvent(EventType::Disconnected, DisconnectedData{ data.reason });
- LOG(INFO) << "Disconnected: " << data.reason;
- nc.reset();
- });
-
- listener.RegisterHandler(EventType::NetworkClientException, [this](EventData eventData) {
- auto data = std::get<NetworkClientExceptionData>(eventData);
- EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ data.what });
- });
-
- LoopExecutionTimeController timer(std::chrono::milliseconds(16));
- while (isRunning) {
- listener.HandleEvent();
-
- timer.Update();
- }
- nc.reset();
-} \ No newline at end of file
diff --git a/src/ThreadNetwork.hpp b/src/ThreadNetwork.hpp
deleted file mode 100644
index 73f9ab8..0000000
--- a/src/ThreadNetwork.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include "Thread.hpp"
-#include "NetworkClient.hpp"
-#include "Event.hpp"
-
-class ThreadNetwork : Thread {
- std::shared_ptr<NetworkClient> nc;
- bool isRunning = true;
-public:
- ThreadNetwork();
- ~ThreadNetwork();
- void Execute() override;
-}; \ No newline at end of file
diff --git a/src/ThreadRender.cpp b/src/ThreadRender.cpp
deleted file mode 100644
index 540be52..0000000
--- a/src/ThreadRender.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "ThreadRender.hpp"
-
-ThreadRender::ThreadRender() {
- render = new Render(900, 480, "AltCraft");
-}
-
-ThreadRender::~ThreadRender() {
- delete render;
-}
-
-void ThreadRender::Execute() {
- render->ExecuteRenderLoop();
-}
diff --git a/src/ThreadRender.hpp b/src/ThreadRender.hpp
deleted file mode 100644
index 4d9223f..0000000
--- a/src/ThreadRender.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include "Thread.hpp"
-#include "Render.hpp"
-
-class ThreadRender : Thread {
- Render *render;
-public:
- ThreadRender();
- ~ThreadRender();
- void Execute() override;
-}; \ No newline at end of file
diff --git a/src/imgui_impl_sdl_gl3.cpp b/src/imgui_impl_sdl_gl3.cpp
index 63d7033..9833b12 100644
--- a/src/imgui_impl_sdl_gl3.cpp
+++ b/src/imgui_impl_sdl_gl3.cpp
@@ -25,8 +25,8 @@ static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_Attr
static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0;
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
-// If text or lines are blurry when integrating ImGui in your engine:
-// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
+// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
+// If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
@@ -42,9 +42,11 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
glActiveTexture(GL_TEXTURE0);
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
+ GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
@@ -58,13 +60,14 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
- // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Setup viewport, orthographic projection matrix
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
@@ -79,6 +82,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
glUniform1i(g_AttribLocationTex, 0);
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
glBindVertexArray(g_VaoHandle);
+ glBindSampler(0, 0); // Rely on combined texture/sampler state.
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
@@ -111,6 +115,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
// Restore modified GL state
glUseProgram(last_program);
glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindSampler(0, last_sampler);
glActiveTexture(last_active_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
@@ -121,6 +126,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
+ glPolygonMode(GL_FRONT_AND_BACK, last_polygon_mode[0]);
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
}
diff --git a/src/main.cpp b/src/main.cpp
index aa7383d..8c70bc8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,8 +1,6 @@
#include "Event.hpp"
#include "Utility.hpp"
-#include "ThreadGame.hpp"
-#include "ThreadRender.hpp"
-#include "ThreadNetwork.hpp"
+#include "GlobalState.hpp"
#include <set>
@@ -17,24 +15,26 @@ const char *getTimeSinceProgramStart(void) {
INITIALIZE_EASYLOGGINGPP
+void initLogger() {
+ el::Configurations loggerConfiguration;
+ el::Helpers::installCustomFormatSpecifier(el::CustomFormatSpecifier("%startTime", std::bind(getTimeSinceProgramStart)));
+ std::string format = "[%startTime][%level][%thread][%fbase]: %msg";
+ loggerConfiguration.set(el::Level::Info, el::ConfigurationType::Format, format);
+ loggerConfiguration.set(el::Level::Error, el::ConfigurationType::Format, format);
+ loggerConfiguration.set(el::Level::Fatal, el::ConfigurationType::Format, format);
+ loggerConfiguration.set(el::Level::Warning, el::ConfigurationType::Format, format);
+ el::Helpers::setThreadName("Render");
+ el::Loggers::reconfigureAllLoggers(loggerConfiguration);
+ el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput);
+ LOG(INFO) << "Logger is configured";
+}
+
#undef main
int main(int argc, char** argv) {
srand(time(0));
- el::Configurations loggerConfiguration;
- el::Helpers::installCustomFormatSpecifier(
- el::CustomFormatSpecifier("%startTime", std::bind(getTimeSinceProgramStart)));
- std::string format = "[%startTime][%level][%thread][%fbase]: %msg";
- loggerConfiguration.set(el::Level::Info, el::ConfigurationType::Format, format);
- loggerConfiguration.set(el::Level::Error, el::ConfigurationType::Format, format);
- loggerConfiguration.set(el::Level::Fatal, el::ConfigurationType::Format, format);
- loggerConfiguration.set(el::Level::Warning, el::ConfigurationType::Format, format);
- el::Helpers::setThreadName("Render");
- el::Loggers::reconfigureAllLoggers(loggerConfiguration);
- el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput);
- LOG(INFO) << "Logger is configured";
-
- LOG(WARNING) << "Sizeof EventData is " << sizeof(EventData);
+ initLogger();
+ LOG(WARNING) << "Sizeof EventData is " << sizeof(EventData);
try {
if (SDL_Init(0) == -1)
@@ -44,16 +44,7 @@ int main(int argc, char** argv) {
return -1;
}
- ThreadGame game;
- std::thread threadGame(&ThreadGame::Execute, game);
-
- ThreadNetwork network;
- std::thread threadNetwork(&ThreadNetwork::Execute, network);
-
- ThreadRender render;
- render.Execute();
-
- threadGame.join();
- threadNetwork.join();
+ GlobalState::Exec();
+
return 0;
} \ No newline at end of file