Compare commits

..

74 Commits

Author SHA1 Message Date
Jace 3261e21d96 Coloring players depending on team and created a blue spawn in MovementTest 2016-01-24 15:46:01 +01:00
Jace 373bb33cf0 Player jumping taking air acceleration into account 2016-01-24 15:20:34 +01:00
Jace aaa11d2109 Merge remote-tracking branch 'origin/master' into PlayerMovement 2016-01-24 14:18:23 +01:00
Jace 1ce9128da8 Source-like movement 2016-01-23 19:45:23 +01:00
Viktor Ljung 132de88d28 Merge pull request #50 from teamfisk/Forward+
Forward+
2016-01-23 18:23:16 +01:00
viktorljung df485ccf7b Merge branch 'master' into Forward+ 2016-01-23 18:21:35 +01:00
viktorljung 85a4d98c81 Revert "Revert "Merge pull request #43 from teamfisk/Forward+""
This reverts commit bd62b5873d.
2016-01-23 18:21:10 +01:00
viktorljung ef020a3770 Text fixed 2016-01-23 18:17:20 +01:00
viktorljung 160b7183b2 WIP 2016-01-23 18:07:07 +01:00
Tleety 5edf5a41f1 Transparency bug fix 2016-01-23 16:45:26 +01:00
viktorljung ff6ec82a6c AMD fix 2016-01-23 16:27:01 +01:00
viktorljung bd62b5873d Revert "Merge pull request #43 from teamfisk/Forward+"
This reverts commit d59ab5aba2, reversing
changes made to bef95235d0.
2016-01-23 15:57:26 +01:00
Jace 666ef6589e Crouching! 2016-01-23 15:06:47 +01:00
Jace b83d773627 Infinite respawning for now 2016-01-23 15:06:41 +01:00
Viktor Ljung d59ab5aba2 Merge pull request #43 from teamfisk/Forward+
Bloom render pass and HDR colors
2016-01-23 14:58:10 +01:00
Tleety f623232a2b Removed a temp variable. 2016-01-23 14:52:29 +01:00
Tleety 6a18cb88af Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	src/Engine/Rendering/PickingPass.cpp
#	src/Engine/Rendering/Renderer.cpp
2016-01-23 13:59:21 +01:00
Tleety b499f4b020 Fixed some rendering bugs and some code refactoring 2016-01-23 12:17:38 +01:00
Jace 482689fd48 fixup! Moved FirstPersonInputController implementation out of header 2016-01-23 12:16:40 +01:00
Jace 32f73201c5 Basic jumping! 2016-01-23 12:15:33 +01:00
Jace 3aeeb3cad5 Moved FirstPersonInputController implementation out of header 2016-01-23 12:15:32 +01:00
Jace 4d5cbb6057 fixup! Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky 2016-01-23 12:14:29 +01:00
Jace bef95235d0 Merge pull request #41 from teamfisk/TextRendering
Text rendering
2016-01-23 11:51:11 +01:00
viktorljung 9a23d8887a Merge remote-tracking branch 'origin/master' into TextRendering
# Conflicts:
#	include/Engine/Rendering/RenderSystem.h
#	src/Engine/Rendering/RenderSystem.cpp
2016-01-23 11:48:10 +01:00
Jace db0e67b9bd Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky 2016-01-23 11:44:16 +01:00
viktorljung e4513376bb fixup! Changed name and made a TextPassState 2016-01-23 11:39:10 +01:00
viktorljung 445248af55 Changed name and made a TextPassState 2016-01-23 11:38:31 +01:00
Jace 64a7239b17 Merge pull request #46 from teamfisk/CapturePointCrashFixBranch
Crash fix for: if you delete a team component in editor.
2016-01-23 11:10:57 +01:00
Jace 31e7340daf Ignoring interpolation and rendering for local player entities! 2016-01-23 00:40:37 +01:00
Jace 3ac3311c0c "inline" caused missing symbol when compiling in Release for some reason 2016-01-23 00:38:11 +01:00
Jace 90867b094a Merge remote-tracking branch 'origin/TextRendering' into Networking
# Conflicts:
#	include/Engine/Rendering/RenderSystem.h
#	src/Engine/Rendering/RenderSystem.cpp
2016-01-22 22:08:56 +01:00
Jace 55ee2bb3bf Player input properly separated from editor input and server 2016-01-22 21:35:31 +01:00
stiffly 406b730ef3 Sends entity names. Temporarily 2016-01-22 19:07:20 +01:00
stiffly b37b20b7d8 Didn't bulid lol. Fixed. 2016-01-22 17:57:31 +01:00
stiffly 750442d224 Merge remote-tracking branch 'origin/Networking' into Networking 2016-01-22 17:49:56 +01:00
stiffly 389e057611 EPlayerSpawned special logic added to server and client. 2016-01-22 17:49:21 +01:00
Jace 74d9bae896 Added conditional spawning based on whether the running instance is a server or not 2016-01-22 17:34:57 +01:00
stiffly 74c95089ea Merge remote-tracking branch 'origin/PlayerMovement' into Networking 2016-01-22 16:19:35 +01:00
Jace ca2aab449e Basic movement and camera management between players and editor 2016-01-22 16:12:51 +01:00
Tleety 7498cebf5e Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	src/Engine/Rendering/DrawFinalPassState.cpp
#	src/Engine/Rendering/PickingPass.cpp
#	src/Engine/Rendering/Renderer.cpp
2016-01-22 15:57:38 +01:00
Tleety 2b8debbfff Added MipMap texture generation 2016-01-22 15:55:32 +01:00
stiffly 08c476e9e3 Added kick logic to the server. Also typedefed. 2016-01-22 15:42:36 +01:00
stiffly 10c3b475bf Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
#	src/Engine/Network/Server.cpp
2016-01-22 13:19:51 +01:00
stiffly 08fcdb382b Used config for a lot of things 2016-01-22 13:18:53 +01:00
stiffly b1ea5429ce Used config for a lot of things 2016-01-22 11:53:04 +01:00
stiffly fcc9d64e7a Now publishes an EPlayerDisconnected event 2016-01-22 10:58:10 +01:00
Tleety caf55fb8d1 Small fix to the bloom light, now feels smoother. 2016-01-22 10:52:45 +01:00
stiffly 7a95880e10 Merge remote-tracking branch 'origin/master' into Networking 2016-01-22 10:36:11 +01:00
Jocke 6cd073c3c8 Added network metrics logging and reactored code. 2016-01-22 10:32:54 +01:00
Jace 1e3fc1ae2d Created EPlayerSpawned that gets published when a player spawns 2016-01-22 10:16:35 +01:00
verysecrethero 6f739e22f3 Crash fix for: if you delete a team component in editor. 2016-01-22 10:10:39 +01:00
Tleety afe43c5f44 Shader will now handle Glowmaps. However the load code is not there yet. 2016-01-21 14:53:47 +01:00
Tleety 70bbc5ed0a Normals scaling with model scale bug fixed. 2016-01-21 13:52:43 +01:00
Tleety 983f90504d Bloom effect added, will have to see if it needs improving. Also added HDR colors and gamma correction. 2016-01-21 12:02:28 +01:00
viktorljung ea9c4d19d0 Merge remote-tracking branch 'origin/master' into TextRendering
# Conflicts:
#	include/Game/Game.h
2016-01-21 10:19:32 +01:00
viktorljung f3bfe388af Clean up 2016-01-21 10:16:03 +01:00
Tleety 86824f1b1f Colors above value 1 is now added to the bloomtexture, and will be used to get a glow effect in later stage. 2016-01-20 15:23:49 +01:00
Tleety 78a1037983 WIP
DrawScreenQuad implemented and working.
Started work on HDR coloring.
2016-01-20 13:34:56 +01:00
viktorljung ce27b224df Merge remote-tracking branch 'origin/master' into TextRendering
# Conflicts:
#	include/Engine/Rendering/RenderQueue.h
#	include/Engine/Rendering/RenderSystem.h
#	include/Engine/Rendering/Renderer.h
#	src/Engine/Rendering/RenderSystem.cpp
2016-01-19 17:27:09 +01:00
viktorljung f0763bc2a3 Font loading crash fixed 2016-01-19 17:18:18 +01:00
viktorljung dbe56280a6 Resolution fixed and Centered text 2016-01-19 11:45:34 +01:00
viktorljung c4594524da Better default values and documentation 2016-01-18 17:51:17 +01:00
viktorljung 2a93e2ae7f Merge remote-tracking branch 'origin/master' into TextRendering
# Conflicts:
#	include/Engine/Rendering/RenderQueue.h
#	include/Engine/Rendering/RenderSystem.h
#	include/Game/Game.h
#	resources/Schema/Types/Entity.xsd
#	src/Engine/Rendering/RenderSystem.cpp
2016-01-18 17:44:26 +01:00
viktorljung 92553f1e93 text size can now be entered in the filepath with a comma separator, like this "filepath,16" 2016-01-18 17:17:12 +01:00
viktorljung 7faed50507 Merge remote-tracking branch 'origin/master' into TextRendering 2016-01-15 13:24:24 +01:00
viktorljung 6fbb962b5e Merge branch 'Rendering' into TextRendering
# Conflicts:
#	include/Engine/Rendering/RenderQueue.h
#	include/Engine/Rendering/RenderQueueFactory.h
#	include/Engine/Rendering/Renderer.h
#	include/Engine/Rendering/ShaderProgram.h
#	include/Game/Game.h
#	resources/Schema/Components.xsd
#	resources/Schema/Entities/Test.xml
#	resources/Schema/Types/Entity.xsd
#	src/Engine/Rendering/RenderQueueFactory.cpp
#	src/Engine/Rendering/Renderer.cpp
#	src/Game/Game.cpp
2016-01-15 13:23:42 +01:00
viktorljung 123c198e19 Text component added and Text render queue 2015-12-14 14:48:24 +01:00
viktorljung 9bd3da409d Added Font to ResourceManager 2015-12-11 16:53:51 +01:00
viktorljung a8a38716bd Text renderer up and working, needs more work to be compatible with the ResourceManager and the Entity Component system 2015-12-11 16:12:29 +01:00
viktorljung 8f007f6daf Added Freetype 2.62 config and option files 2015-12-11 11:26:41 +01:00
viktorljung 4c2ce3882e Added fonts folder and font 2015-12-11 11:07:22 +01:00
viktorljung 7b6902eafe Merge remote-tracking branch 'origin/master' into TextRendering 2015-12-11 10:55:10 +01:00
viktorljung 46854a63dd Text rendering includes 2015-12-11 10:54:52 +01:00
viktorljung dc66891d60 Added Freetype 2.62 2015-12-10 11:22:56 +01:00
90 changed files with 2788 additions and 576 deletions
+1 -1
Submodule assets updated: f7e349a316...e8174f630f
+19
View File
@@ -0,0 +1,19 @@
#ifndef EPlayerSpawned_h__
#define EPlayerSpawned_h__
#include "Core/Event.h"
#include "Core/EntityWrapper.h"
namespace Events
{
struct PlayerSpawned : Event
{
int PlayerID;
EntityWrapper Player;
EntityWrapper Spawner;
};
}
#endif
+2
View File
@@ -25,6 +25,8 @@ struct EntityWrapper
bool HasComponent(const std::string& componentName);
EntityWrapper Parent();
EntityWrapper FirstChildByName(const std::string& name);
bool IsChildOf(EntityWrapper potentialParent);
bool Valid();
ComponentWrapper operator[](const char* componentName);
+1 -1
View File
@@ -111,7 +111,7 @@ struct Child
std::vector<ContainedObject>& m_StaticObjectsRef;
std::vector<ContainedObject>& m_DynamicObjectsRef;
inline bool hasChildren() const;
bool hasChildren() const;
int childIndexContainingPoint(const glm::vec3& point) const;
std::vector<int> childIndicesContainingBox(const AABB& box) const;
};
+5
View File
@@ -3,13 +3,18 @@
#include "../GLM.h"
#include "World.h"
#include "EntityWrapper.h"
namespace Transform
{
glm::vec3 AbsolutePosition(EntityWrapper entity);
glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::quat AbsoluteOrientation(EntityWrapper entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(EntityWrapper entity);
glm::vec3 AbsoluteScale(World* world, EntityID entity);
glm::mat4 ModelMatrix(EntityWrapper entity);
glm::mat4 ModelMatrix(EntityID entity, World* world);
}
@@ -0,0 +1,115 @@
#ifndef EditorCameraInputController_h__
#define EditorCameraInputController_h__
#include <imgui/imgui.h>
#include "../Input/FirstPersonInputController.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
#include "../Core/EMouseScroll.h"
#include "../Core/ConfigFile.h"
template <typename EventContext>
class EditorCameraInputController : public FirstPersonInputController<EventContext>
{
public:
EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID)
: FirstPersonInputController(eventBroker, playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorCameraInputController::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorCameraInputController::OnMouseRelease);
EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &EditorCameraInputController::OnMouseScroll);
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
m_SpeedMultiplier = m_Config->Get<float>("Editor.CameraSpeed", 3.f);
}
virtual const glm::vec3 Movement() const override { return m_Movement * m_SpeedMultiplier; }
void Enable() { m_Enabled = true; }
void Disable() { m_Enabled = false; }
virtual bool OnCommand(const Events::InputCommand& e) override
{
if (glm::abs(e.Value) > 0 && !m_MouseLocked) {
return false;
}
ImGuiIO& io = ImGui::GetIO();
if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) {
return false;
}
if (e.Command == "Jump") {
if (e.Value > 0) {
m_Movement.y = glm::max(e.Value, 1.f);
} else {
m_Movement.y = 0.f;
}
}
if (e.Command == "Crouch") {
if (e.Value > 0) {
m_Movement.y = glm::min(-e.Value, -1.f);
} else {
m_Movement.y = 0.f;
}
}
if (e.Command == "Sprint") {
if (e.Value > 0) {
m_SpeedMultiplier *= 2.f;
} else {
m_SpeedMultiplier /= 2.f;
}
}
return FirstPersonInputController::OnCommand(e);
}
protected:
ConfigFile* m_Config;
bool m_Enabled = false;
float m_SpeedMultiplier = 1.f;
EventRelay<EventContext, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e)
{
if (!m_Enabled) {
return false;
}
if (e.Button == GLFW_MOUSE_BUTTON_2) {
ImGuiIO& io = ImGui::GetIO();
if (!io.WantCaptureMouse) {
LockMouse();
}
}
return true;
}
EventRelay<EventContext, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e)
{
if (!m_Enabled) {
return false;
}
if (e.Button == GLFW_MOUSE_BUTTON_2) {
UnlockMouse();
}
return true;
}
EventRelay<EventContext, Events::MouseScroll> m_EMouseScroll;
bool OnMouseScroll(const Events::MouseScroll& e)
{
if (!m_Enabled) {
return false;
}
m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier);
m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier);
m_Config->SaveToDisk();
return true;
}
};
#endif
+15 -4
View File
@@ -1,7 +1,6 @@
#include "../Core/System.h"
#include "../Rendering/IRenderer.h"
#include "../Rendering/Camera.h"
#include "../Rendering/DebugCameraInputController.h"
#include "../Rendering/ESetCamera.h"
#include "../Core/World.h"
#include "../Core/SystemPipeline.h"
@@ -10,8 +9,10 @@
#include "../Core/EntityFileParser.h"
#include "../Core/EntityFileWriter.h"
#include "../Core/EMousePress.h"
#include "../Input/EInputCommand.h"
#include "EditorGUI.h"
#include "EditorStats.h"
#include "EditorCameraInputController.h"
class EditorSystem : public ImpureSystem
{
@@ -21,18 +22,24 @@ public:
void Update(double dt);
void Enable();
void Disable();
private:
IRenderer* m_Renderer;
RenderFrame* m_RenderFrame;
World* m_EditorWorld;
SystemPipeline* m_EditorWorldSystemPipeline;
Camera* m_EditorCamera;
EntityWrapper m_Camera = EntityWrapper::Invalid;
DebugCameraInputController<EditorSystem>* m_DebugCameraInputController;
//Camera* m_EditorCamera;
EntityWrapper m_EditorCamera = EntityWrapper::Invalid;
EntityWrapper m_ActualCamera = EntityWrapper::Invalid;
EditorCameraInputController<EditorSystem>* m_EditorCameraInputController;
EditorGUI* m_EditorGUI;
EditorStats* m_EditorStats;
// State
double m_LastTime = 0.f;
bool m_Enabled = true;
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
EntityWrapper m_Widget = EntityWrapper::Invalid;
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
@@ -56,4 +63,8 @@ private:
bool OnMousePress(const Events::MousePress& e);
EventRelay<EditorSystem, Events::WidgetDelta> m_EWidgetDelta;
bool OnWidgetDelta(const Events::WidgetDelta& e);
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
EventRelay<EditorSystem, Events::SetCamera> m_ESetCamera;
bool OnSetCamera(const Events::SetCamera& e);
};
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Events
struct InputCommand : Event
{
/** Numerical ID of the player. */
unsigned int PlayerID;
int PlayerID;
/** The command that was sent. */
std::string Command;
/** The value of the command. */
+103 -46
View File
@@ -9,62 +9,119 @@ template <typename EventContext>
class FirstPersonInputController : public InputController<EventContext>
{
public:
FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID)
: InputController(eventBroker)
, m_PlayerID(playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
}
FirstPersonInputController(EventBroker* eventBroker, int playerID);
const glm::quat Orientation() const { return m_Orientation; }
virtual const glm::vec3 Movement() const { return m_Movement; }
virtual const glm::vec3 Rotation() const { return m_Rotation; }
virtual bool Jumping() const { return m_Jumping; }
virtual bool Crouching() const { return m_Crouching; }
void LockMouse()
{
Events::LockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = true;
}
void LockMouse();
void UnlockMouse();
virtual bool OnCommand(const Events::InputCommand& e) override;
virtual void Reset();
void UnlockMouse()
{
Events::UnlockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = false;
}
protected:
const int m_PlayerID;
bool m_MouseLocked = false;
glm::vec3 m_Rotation;
glm::vec3 m_Movement;
bool m_Jumping = false;
bool m_Crouching = false;
virtual bool OnCommand(const Events::InputCommand& e) override
{
if (m_PlayerID != e.PlayerID) {
return false;
}
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse& e);
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse& e);
};
if (m_MouseLocked) {
if (e.Command == "Pitch") {
float val = glm::radians(e.Value);
m_Orientation = m_Orientation * glm::angleAxis<float>(-val, glm::vec3(1, 0, 0));
return true;
}
template <typename EventContext>
FirstPersonInputController<EventContext>::FirstPersonInputController(EventBroker* eventBroker, int playerID)
: InputController(eventBroker)
, m_PlayerID(playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
}
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
m_Orientation = glm::angleAxis<float>(-val, glm::vec3(0, 1, 0)) * m_Orientation;
return true;
}
}
template <typename EventContext>
void FirstPersonInputController<EventContext>::Reset()
{
m_Rotation = glm::vec3(0.f, 0.f, 0.f);
m_Jumping = false;
}
template <typename EventContext>
void FirstPersonInputController<EventContext>::LockMouse()
{
Events::LockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = true;
}
template <typename EventContext>
void FirstPersonInputController<EventContext>::UnlockMouse()
{
Events::UnlockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = false;
}
template <typename EventContext>
bool FirstPersonInputController<EventContext>::OnCommand(const Events::InputCommand& e)
{
if (m_PlayerID != e.PlayerID) {
return false;
}
protected:
const unsigned int m_PlayerID;
glm::quat m_Orientation;
bool m_MouseLocked = false;
if (e.Command == "Pitch") {
float val = glm::radians(e.Value);
m_Rotation.x += -val;
//m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi<float>(), glm::half_pi<float>());
}
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
};
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
m_Rotation.y += -val;
}
if (e.Command == "Forward" || e.Command == "Right") {
if (e.Command == "Forward") {
float val = glm::clamp(e.Value, -1.f, 1.f);
m_Movement.z = -val;
}
if (e.Command == "Right") {
float val = glm::clamp(e.Value, -1.f, 1.f);
m_Movement.x = val;
}
if (glm::length2(m_Movement) > 0) {
m_Movement = glm::normalize(m_Movement);
}
}
if (e.Command == "Jump") {
m_Jumping = e.Value > 0;
}
if (e.Command == "Crouch") {
m_Crouching = e.Value > 0;
}
return true;
}
template <typename EventContext>
bool FirstPersonInputController<EventContext>::OnUnlockMouse(const Events::UnlockMouse& e)
{
m_MouseLocked = false;
return true;
}
template <typename EventContext>
bool FirstPersonInputController<EventContext>::OnLockMouse(const Events::LockMouse& e)
{
m_MouseLocked = true;
return true;
}
#endif
+11 -8
View File
@@ -20,6 +20,7 @@
#include "Input/EInputCommand.h"
#include "Core/EPlayerDamage.h"
#include "Network/EInterpolate.h"
#include "Core/EPlayerSpawned.h"
class Client : public Network
{
@@ -39,14 +40,14 @@ private:
char readBuf[INPUTSIZE] = { 0 };
// Packet loss logic
unsigned int m_PacketID = 0;
unsigned int m_PreviousPacketID = 0;
unsigned int m_SendPacketID = 0;
PacketID m_PacketID = 0;
PacketID m_PreviousPacketID = 0;
PacketID m_SendPacketID = 0;
// Game logic
World* m_World;
std::string m_PlayerName;
int m_PlayerID = -1;
PlayerID m_PlayerID = -1;
EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max();
bool m_IsConnected = false;
// Server Client Lookup map
@@ -57,25 +58,27 @@ private:
std::unordered_map<EntityID, EntityID> m_ClientIDToServerID;
// Network logic
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
PlayerDefinition m_PlayerDefinitions[8];
SnapshotDefinitions m_NextSnapshot;
double m_DurationOfPingTime;
std::clock_t m_StartPingTime;
std::clock_t m_TimeSinceSentInputs;
unsigned int m_SendInputIntervalMs;
std::vector<Events::InputCommand> m_InputCommandBuffer;
// Private member functions
void readFromServer();
int receive(char* data, size_t length);
int receive(char* data);
void send(Packet& packet);
void connect();
void disconnect();
void ping();
void parseMessageType(Packet& packet);
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
void parseConnect(Packet& packet);
void parsePlayerConnected(Packet& packet);
void parsePing();
void parseServerPing();
void parseKick();
void parsePlayersSpawned(Packet& packet);
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
void parseSnapshot(Packet& packet);
void identifyPacketLoss();
@@ -0,0 +1,18 @@
#ifndef Events_PlayerDisconnected
#define Events_PlayerDisconnected
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
struct PlayerDisconnected : public Event
{
unsigned int PlayerID;
EntityID Entity;
};
}
#endif
+8 -7
View File
@@ -5,16 +5,17 @@
// Used to determine what type of message was sent.
enum class MessageType
{
Connect,
Disconnect,
ClientPing,
ServerPing,
Message,
Snapshot,
Connect,
Disconnect,
Ping,
Message,
Snapshot,
OnInputCommand,
OnPlayerDamage,
PlayerConnected,
BecomePlayer
BecomePlayer,
Kick,
OnPlayerSpawned
};
#endif
+21 -2
View File
@@ -1,13 +1,21 @@
#ifndef Network_h__
#define Network_h__
#include <ctime>
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Network/Packet.h"
#include "Network/NetworkData.h"
#include "Core/ResourceManager.h"
#include "Core/ConfigFile.h"
#include <fstream>
#include <iostream>
#define MAXCONNECTIONS 8
#define INPUTSIZE 4097
#define TIMEOUTMS 15000
typedef unsigned int PlayerID;
typedef unsigned int PacketID;
typedef unsigned int UserID;
class Network
{
@@ -15,6 +23,17 @@ public:
virtual ~Network() { };
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
virtual void Update() = 0;
protected:
// For Debug
bool isReadingData = false;
NetworkData m_NetworkData;
unsigned int m_SaveDataIntervalMs = 1000;
std::clock_t m_SaveDataTimer;
unsigned int m_MaxConnections;
unsigned int m_TimeoutMs;
void saveToFile();
void updateNetworkData();
void initialize();
};
#endif
+18
View File
@@ -0,0 +1,18 @@
#ifndef NetworkData_h__
#define NetworkData_h__
#include <vector>
struct NetworkData {
unsigned int TotalTime = 0;
unsigned int TotalDataReceived = 0;
unsigned int TotalDataSent = 0;
unsigned int AmountOfMessagesReceived = 0;
unsigned int AmountOfMessagesSent = 0;
// Interval based
unsigned int DataReceivedThisInterval = 0;
unsigned int DataSentThisInterval = 0;
// pair: first=reveived, second=send
std::vector<std::pair<unsigned int, unsigned int>> BandwidthBytes;
};
#endif
+2
View File
@@ -55,12 +55,14 @@ public:
char* Data() { return m_Data; };
unsigned int DataReadSize() { return m_ReturnDataOffset; }
unsigned int MaxSize() { return m_MaxPacketSize; }
unsigned int HeaderSize() { return m_HeaderSize; }
private:
char* m_Data;
unsigned int m_ReturnDataOffset = 0;
int m_Offset = 0;
unsigned int m_MaxPacketSize = 512;
unsigned int m_HeaderSize = 0;
void resizeData();
};
+16 -10
View File
@@ -14,6 +14,8 @@
#include "../Network/Network.h"
#include "Input/EInputCommand.h"
#include "Core/EPlayerDamage.h"
#include "Network/EPlayerDisconnected.h"
#include "Core/EPlayerSpawned.h"
class Server : public Network
{
@@ -29,7 +31,7 @@ private:
boost::asio::ip::udp::socket m_Socket;
// Sending messages to client logic
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
PlayerDefinition m_PlayerDefinitions[8]; //
std::vector<PlayerDefinition> m_ConnectedUsers;
char readBuffer[INPUTSIZE] = { 0 };
int bytesRead = 0;
@@ -38,8 +40,8 @@ private:
std::clock_t previousSnapshotMessage = std::clock();
std::clock_t timOutTimer = std::clock();
// How often we send messages (milliseconds)
int intervalMs = 1000;
int snapshotInterval = 50;
int pingIntervalMs;
int snapshotInterval;
int checkTimeOutInterval = 100;
//Timers
@@ -50,32 +52,36 @@ private:
EventBroker* m_EventBroker;
// Packet loss logic
unsigned int m_PacketID = 0;
unsigned int m_PreviousPacketID = 0;
PacketID m_PacketID = 0;
PacketID m_PreviousPacketID = 0;
// Private member functions
int receive(char* data, size_t length);
int receive(char* data);
void readFromClients();
void send(Packet& packet, int playerID);
void send(Packet& packet, UserID user);
void send(PlayerID player, Packet& packet);
void send(Packet& packet);
void broadcast(Packet& packet);
void sendSnapshot();
void sendPing();
void checkForTimeOuts();
void disconnect(int i);
void disconnect(UserID user);
void parseMessageType(Packet& packet);
void parseOnInputCommand(Packet& packet);
void parseOnPlayerDamage(Packet& packet);
void parseConnect(Packet& packet);
void parseDisconnect();
void parseClientPing();
void parseServerPing();
void parsePing();
void identifyPacketLoss();
void createPlayer();
int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
void kick(PlayerID player);
PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
// Debug event
EventRelay<Server, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
};
#endif
@@ -1,84 +0,0 @@
#ifndef DebugCameraInputController_h__
#define DebugCameraInputController_h__
#include <imgui/imgui.h>
#include "../Input/FirstPersonInputController.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
template <typename EventContext>
class DebugCameraInputController : public FirstPersonInputController<EventContext>
{
public:
DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID)
: FirstPersonInputController(eventBroker, playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &DebugCameraInputController::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &DebugCameraInputController::OnMouseRelease);
}
void SetPosition(const glm::vec3 position) { m_Position = position; }
void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; }
const glm::vec3 Position() const { return m_Position; }
void SetBaseSpeed(float speed) { m_BaseSpeed = speed; }
virtual bool OnCommand(const Events::InputCommand& e) override
{
ImGuiIO& io = ImGui::GetIO();
if (!io.WantCaptureKeyboard) {
if (e.Command == "Right") {
float value = std::max(-1.f, std::min(e.Value, 1.f));
m_Velocity.x = value;
}
if (e.Command == "Forward") {
float value = std::max(-1.f, std::min(e.Value, 1.f));
m_Velocity.z = -value;
}
if (e.Command == "Sprint") {
if (e.Value > 0.f) {
m_Speed = m_BaseSpeed * 2.f * (e.Value);
} else {
m_Speed = m_BaseSpeed;
}
}
}
return FirstPersonInputController::OnCommand(e);
}
void Update(double dt)
{
if (glm::length2(m_Velocity) > 0) {
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt);
}
}
protected:
glm::vec3 m_Position = glm::vec3(0, 0, 0);
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
float m_BaseSpeed = 2.0f;
float m_Speed = m_BaseSpeed;
EventRelay<EventContext, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e)
{
if (e.Button == GLFW_MOUSE_BUTTON_2) {
ImGuiIO& io = ImGui::GetIO();
if (!io.WantCaptureMouse) {
LockMouse();
}
}
return true;
}
EventRelay<EventContext, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e)
{
if (e.Button == GLFW_MOUSE_BUTTON_2) {
UnlockMouse();
}
return true;
}
};
#endif
+53
View File
@@ -0,0 +1,53 @@
#ifndef DrawBloomPass_h__
#define DrawBloomPass_h__
#include "IRenderer.h"
#include "DrawBloomPassState.h"
//#include "LightCullingPass.h" Finalpass om den skall skickas in
#include "FrameBuffer.h"
#include "ShaderProgram.h"
//#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawBloomPass
{
public:
DrawBloomPass(IRenderer* renderer /* ,Texture or finalpass*/ );
~DrawBloomPass() { }
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void InitializeBuffers();
void ClearBuffer();
void FillGaussianBuffer(FrameBuffer* fb);
void Draw(GLuint texture);
//Getters
//Return the blurred result of the texture that was sent into draw
GLuint GaussianTexture() const { return m_GaussianTexture_vert; }
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
Texture* m_WhiteTexture;
Model* m_ScreenQuad;
const IRenderer* m_Renderer;
//const LightCullingPass* m_LightCullingPass
GLuint m_iterations = 9;
GLuint m_GaussianTexture_horiz;
GLuint m_GaussianTexture_vert;
FrameBuffer m_GaussianFrameBuffer_horiz;
FrameBuffer m_GaussianFrameBuffer_vert;
ShaderProgram* m_GaussianProgram_horiz;
ShaderProgram* m_GaussianProgram_vert;
};
#endif
@@ -0,0 +1,15 @@
#ifndef DrawBloomPassState_h__
#define DrawBloomPassState_h__
#include "Rendering/RenderState.h"
class DrawBloomPassState : public RenderState
{
public:
DrawBloomPassState();
~DrawBloomPassState();
private:
};
#endif
@@ -0,0 +1,29 @@
#ifndef DrawColorCorrectionPass_h__
#define DrawColorCorrectionPass_h__
#include "IRenderer.h"
#include "DrawScreenQuadPassState.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
//#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawColorCorrectionPass
{
public:
DrawColorCorrectionPass(IRenderer* renderer);
~DrawColorCorrectionPass() { }
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(GLuint sceneTexture, GLuint bloomTexture);
private:
const IRenderer* m_Renderer;
ShaderProgram* m_ColorCorrectionProgram;
Model* m_ScreenQuad;
GLfloat m_Exposure;
};
#endif
+13 -3
View File
@@ -17,17 +17,27 @@ public:
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
void ClearBuffer();
//Getters
//Return the texture that is used in later stages to apply the bloom effect
GLuint BloomTexture() const { return m_BloomTexture; }
//Return the texture with diffuse and lighting of the scene.
GLuint SceneTexture() const { return m_SceneTexture; }
FrameBuffer* FinalPassFrameBuffer() { return &m_FinalPassFrameBuffer; }
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const;
Texture* m_WhiteTexture;
Texture* m_NeutralNormalMap;
Texture* m_BlackTexture;
FrameBuffer m_FinalPassFrameBuffer;
GLuint m_BloomTexture;
GLuint m_SceneTexture;
GLuint m_DepthBuffer;
const IRenderer* m_Renderer;
const LightCullingPass* m_LightCullingPass;
@@ -6,7 +6,7 @@
class DrawFinalPassState : public RenderState
{
public:
DrawFinalPassState();
DrawFinalPassState(GLuint frameBuffer);
~DrawFinalPassState();
private:
@@ -0,0 +1,28 @@
#ifndef DrawScreenQuadPass_h__
#define DrawScreenQuadPass_h__
#include "IRenderer.h"
#include "DrawScreenQuadPassState.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
//#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawScreenQuadPass
{
public:
DrawScreenQuadPass(IRenderer* renderer);
~DrawScreenQuadPass() { }
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(GLuint texture);
private:
const IRenderer* m_Renderer;
ShaderProgram* m_DrawQuadProgram;
Model* m_ScreenQuad;
};
#endif
@@ -0,0 +1,15 @@
#ifndef DrawScreenQuadPassState_h__
#define DrawScreenQuadPassState_h__
#include "Rendering/RenderState.h"
class DrawScreenQuadPassState : public RenderState
{
public:
DrawScreenQuadPassState();
~DrawScreenQuadPassState();
private:
};
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef Font_h__
#define Font_h__
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include "../OpenGL.h"
#include "../GLM.h"
#include "../Core/ResourceManager.h"
class Font : public Resource
{
friend class ResourceManager;
private:
Font(std::string path);
public:
struct Character {
GLuint TextureID; // ID handle of the glyph texture
glm::ivec2 Size; // Size of glyph
glm::ivec2 Bearing; // Offset from baseline to left/top of glyph
GLuint Advance; // Offset to advance to next glyph
};
int FontSize = 16;
~Font();
std::map<GLchar, Character> m_Characters;
};
#endif
+3 -36
View File
@@ -11,49 +11,16 @@
#include "Camera.h"
#include "RenderJob.h"
#include "ModelJob.h"
#include "TextJob.h"
#include "PointLightJob.h"
#include "DirectionalLightJob.h"
/*
struct SpriteJob : RenderJob
{
unsigned int ShaderID = 0;
unsigned int TextureID = 0;
glm::mat4 ModelMatrix;
const Texture* DiffuseTexture = nullptr;
const Texture* NormalTexture = nullptr;
const Texture* SpecularTexture = nullptr;
glm::vec4 Color;
void CalculateHash() override
{
Hash = TextureID;
}
};
struct PointLightJob : RenderJob
{
glm::vec4 Position;
glm::vec4 Color;
float Radius;
float Intensity;
float Falloff;
float padding = 123;
void CalculateHash() override
{
Hash = 0;
}
};
*/
struct RenderScene
{
::Camera* Camera = nullptr;
std::list<std::shared_ptr<RenderJob>> ForwardJobs;
std::list<std::shared_ptr<RenderJob>> PointLightJobs;
std::list<std::shared_ptr<RenderJob>> TextJobs;
std::list<std::shared_ptr<RenderJob>> DirectionalLightJobs;
Rectangle Viewport;
bool ClearDepth = false;
@@ -62,6 +29,7 @@ struct RenderScene
{
ForwardJobs.clear();
PointLightJobs.clear();
TextJobs.clear();
DirectionalLightJobs.clear();
}
};
@@ -98,5 +66,4 @@ public:
private:
int m_Size = 0;
};
#endif
+6 -1
View File
@@ -15,7 +15,7 @@
#include "Renderer.h"
#include "PointLightJob.h"
#include "../Core/Transform.h"
#include "DebugCameraInputController.h"
#include "../Core/EPlayerSpawned.h"
class RenderSystem : public ImpureSystem
{
@@ -30,9 +30,11 @@ private:
RenderFrame* m_RenderFrame;
Camera* m_Camera;
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
bool OnSetCamera(Events::SetCamera &event);
void fillText(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
@@ -40,6 +42,9 @@ private:
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs);
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs);
EventRelay<RenderSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
};
#endif
+13 -3
View File
@@ -13,10 +13,15 @@
#include "PickingPass.h"
#include "LightCullingPass.h"
#include "DrawFinalPass.h"
#include "DrawScreenQuadPass.h"
#include "DrawBloomPass.h"
#include "DrawColorCorrectionPass.h"
#include "../Core/EventBroker.h"
#include "ImGuiRenderPass.h"
#include "Camera.h"
#include "../Core/Transform.h"
#include "imgui/imgui.h"
#include "TextPass.h"
class Renderer : public IRenderer
{
@@ -34,6 +39,7 @@ public:
private:
//----------------------Variables----------------------//
EventBroker* m_EventBroker;
TextPass* m_TextPass;
Texture* m_ErrorTexture;
Texture* m_WhiteTexture;
@@ -42,10 +48,15 @@ private:
Model* m_UnitQuad;
Model* m_UnitSphere;
int m_DebugTextureToDraw = 0;
PickingPass* m_PickingPass;
LightCullingPass* m_LightCullingPass;
ImGuiRenderPass* m_ImGuiRenderPass;
DrawFinalPass* m_DrawFinalPass;
DrawScreenQuadPass* m_DrawScreenQuadPass;
DrawBloomPass* m_DrawBloomPass;
DrawColorCorrectionPass* m_DrawColorCorrectionPass;
//----------------------Functions----------------------//
void InitializeWindow();
@@ -55,14 +66,13 @@ private:
//TODO: Renderer: Get InputUpdate out of renderer
void InputUpdate(double dt);
//void PickingPass(RenderQueueCollection& rq);
void DrawScreenQuad(GLuint textureToDraw);
//void DrawScreenQuad(GLuint textureToDraw);
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j) { return (i->Depth < j->Depth); }
void SortRenderJobsByDepth(RenderScene &scene);
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
//--------------------ShaderPrograms-------------------//
ShaderProgram* m_BasicForwardProgram;
ShaderProgram* m_DrawScreenQuadProgram;
ShaderProgram* m_BasicForwardProgram;
};
#endif
+58
View File
@@ -0,0 +1,58 @@
#ifndef TextJob_h__
#define TextJob_h__
#include <cstdint>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ComponentWrapper.h"
#include "Texture.h"
#include "RenderJob.h"
#include "../Core/ResourceManager.h"
#include "Font.h"
struct TextJob : RenderJob
{
TextJob(glm::mat4 matrix, Font* font, ComponentWrapper textComponent)
: RenderJob()
{
Matrix = matrix;
Color = (glm::vec4)textComponent["Color"];
Content = (std::string)textComponent["Content"];
Resource = font;
if ((int)textComponent["Alignment"] == textComponent["Alignment"].Enum("Left")) {
Alignment = AlignmentEnum::Left;
} else if ((int)textComponent["Alignment"] == textComponent["Alignment"].Enum("Right")) {
Alignment = AlignmentEnum::Right;
} else if ((int)textComponent["Alignment"] == textComponent["Alignment"].Enum("Center")) {
Alignment = AlignmentEnum::Center;
} else {
LOG_ERROR("Text alignment invalid");
Alignment = AlignmentEnum::Left;
}
};
enum class AlignmentEnum
{
Left,
Right,
Center
};
glm::mat4 Matrix;
glm::vec4 Color;
std::string Content;
Font* Resource;
AlignmentEnum Alignment;
void CalculateHash() override
{
Hash = 0;
}
};
#endif
+33
View File
@@ -0,0 +1,33 @@
#ifndef TextRenderer_h__
#define TextRenderer_h__
#include <ft2build.h>
#include FT_FREETYPE_H
#include "../OpenGL.h"
#include "../GLM.h"
#include "ShaderProgram.h"
#include "Font.h"
#include "../Core/ResourceManager.h"
#include "RenderQueue.h"
#include "TextPassState.h"
#include "FrameBuffer.h"
class TextPass
{
public:
TextPass();
void Initialize();
void Update();
void Draw(RenderScene& scene, FrameBuffer& frameBuffer);
private:
void renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix);
Font* font;
GLuint VAO, VBO;
ShaderProgram* m_TextProgram;
};
#endif
+15
View File
@@ -0,0 +1,15 @@
#ifndef TextPassState_h__
#define TextPassState_h__
#include "Rendering/RenderState.h"
class TextPassState : public RenderState
{
public:
TextPassState(GLuint frameBuffer);
~TextPassState();
private:
};
#endif
+1
View File
@@ -18,6 +18,7 @@ public:
void Bind(GLenum textureUnit = GL_TEXTURE0);
GLuint m_Texture = 0;
};
#endif
@@ -0,0 +1,17 @@
#ifndef CommonFuntions_h__
#define CommonFuntions_h__
#include "../../Common.h"
#include "../../OpenGL.h"
#include "../../GLM.h"
class CommonFuntions
{
public:
CommonFuntions() = delete;
private:
};
#endif
+1
View File
@@ -19,6 +19,7 @@
#include "Rendering/RenderSystem.h"
#include "Core/EntityFileParser.h"
#include "Core/Octree.h"
#include "Rendering/Font.h"
#include "Systems/InterpolationSystem.h"
// Network
#include <boost/thread.hpp>
+9 -9
View File
@@ -10,11 +10,12 @@
#include "Common.h"
#include "Core/System.h"
#include "Core/EventBroker.h"
#include "Core/ResourceManager.h"
#include "Core/ConfigFile.h"
#include "Core/EPlayerSpawned.h"
#include "Network/EInterpolate.h"
#define SNAPSHOTINTERVAL 0.05f
class InterpolationSystem : public PureSystem
{
struct Transform
@@ -25,29 +26,28 @@ class InterpolationSystem : public PureSystem
double interpolationTime;
};
public:
InterpolationSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Transform")
{
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
}
InterpolationSystem(World* world, EventBroker* eventBroker);
~InterpolationSystem() { }
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override;
private:
std::unordered_map<EntityID, Transform> m_NextTransform;
std::unordered_map<EntityID, Transform> m_LastReceivedTransform;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
//glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime);
template <typename T>
T vectorInterpolation(T prev, T next, double currentTime)
{
T difference = next - prev;
T vector = (difference / SNAPSHOTINTERVAL) * static_cast<float>(currentTime);
T vector = (difference / m_SnapshotInterval) * static_cast<float>(currentTime);
return vector;
}
float m_SnapshotInterval;
EventRelay<InterpolationSystem, Events::Interpolate> m_EInterpolate;
bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e);
EventRelay<InterpolationSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
};
#endif
+14 -5
View File
@@ -1,14 +1,23 @@
#include "Common.h"
#include "GLM.h"
#include "Core/System.h"
#include "Core/EPlayerSpawned.h"
#include "Input/FirstPersonInputController.h"
#include <imgui/imgui.h>
class PlayerMovementSystem : public PureSystem
class PlayerMovementSystem : public ImpureSystem, PureSystem
{
public:
PlayerMovementSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Player")
{ }
PlayerMovementSystem(World* world, EventBroker* eventBroker);
~PlayerMovementSystem();
virtual void Update(double dt) override;
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt);
private:
// State
std::unordered_map<EntityWrapper, FirstPersonInputController<PlayerMovementSystem>*> m_PlayerInputControllers;
EventRelay<PlayerMovementSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
};
+15 -2
View File
@@ -2,6 +2,9 @@
#include "Input/EInputCommand.h"
#include "Systems/SpawnerSystem.h"
#include "Events/ESpawnerSpawn.h"
#include "Core/EPlayerSpawned.h"
#include "Rendering/ESetCamera.h"
#include "Core/ConfigFile.h"
class PlayerSpawnSystem : public ImpureSystem
{
@@ -11,8 +14,18 @@ public:
virtual void Update(double dt) override;
private:
struct SpawnRequest
{
int PlayerID;
ComponentInfo::EnumType Team;
};
bool m_NetworkEnabled = false;
std::vector<SpawnRequest> m_SpawnRequests;
std::map<int, EntityWrapper> m_PlayerEntities;
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
std::vector<int> m_SpawnRequests;
EventRelay<PlayerSpawnSystem, Events::PlayerSpawned> m_OnPlayerSpawnerd;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
};
+8 -1
View File
@@ -1,11 +1,13 @@
[Debug]
LogLevel=1
LoadMap=
EditorEnabled=false
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
; if false -> Use pool allocation.
DisableMemoryPool=false
[Editor]
CameraSpeed=3
[Video]
Fullscreen=false
VSYNC=false
@@ -19,6 +21,11 @@ IsServer=false
Name=Bob
Address=127.0.0.1
Port=13
MaxConnections=8
SnapshotInterval=0.05
SendInputIntervalMs=33
PingIntervalMs= 1000
TimeoutMs=15000
[Multithreading]
ResourceLoading=true
+1
View File
@@ -6,6 +6,7 @@
<xs:include schemaLocation="Components/Model.xsd"/>
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
<xs:include schemaLocation="Components/Player.xsd"/>
<xs:include schemaLocation="Components/Text.xsd"/>
<xs:include schemaLocation="Components/Camera.xsd"/>
<xs:include schemaLocation="Components/AABB.xsd"/>
<xs:include schemaLocation="Components/PointLight.xsd"/>
+2 -5
View File
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
<Velocity X="0" Y="0" Z="0"/>
<Forward>false</Forward>
<Left>false</Left>
<Back>false</Back>
<Right>false</Right>
<MovementSpeed>3</MovementSpeed>
<CrouchSpeed>1.5</CrouchSpeed>
</Player>
+2 -5
View File
@@ -9,11 +9,8 @@
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
<xs:element name="Forward" type="t:bool" minOccurs="0"/>
<xs:element name="Left" type="t:bool" minOccurs="0"/>
<xs:element name="Back" type="t:bool" minOccurs="0"/>
<xs:element name="Right" type="t:bool" minOccurs="0"/>
<xs:element name="MovementSpeed" type="t:float" minOccurs="0"/>
<xs:element name="CrouchSpeed" type="t:float" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Text.xsd">
<Content>Text</Content>
<Resource></Resource>
<Color R="1" G="1" B="1" A="1"/>
<Visible>true</Visible>
<Alignment><Center/></Alignment>
</Text>
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:complexType name="AlignmentEnum" mixed="true">
<xs:complexContent>
<xs:extension base="t:enum">
<xs:choice>
<xs:element name="Right" type="xs:integer" fixed="0" minOccurs="0"/>
<xs:element name="Left" type="xs:integer" fixed="1" minOccurs="0"/>
<xs:element name="Center" type="xs:integer" fixed="2" minOccurs="0"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="Text">
<xs:annotation>
<xs:documentation>A visible font loaded from disk</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Content" type="t:string" minOccurs="0">
<xs:annotation><xs:documentation>the content of the string printed</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Resource" type="t:string" minOccurs="0">
<xs:annotation><xs:documentation>The asset file, font resolution, example: Fonts/font.ttf,16</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Color" type="t:Color" minOccurs="0">
<xs:annotation><xs:documentation>Color</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Visible" type="t:bool" minOccurs="0">
<xs:annotation><xs:documentation>Wether the text is visible or not</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Alignment" type="AlignmentEnum" minOccurs="0">
<xs:annotation><xs:documentation>Text alignment</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
+143 -31
View File
@@ -6,66 +6,178 @@
</Components>
<Children>
<Entity>
<Components>
<c:Camera/>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity>
<Entity name="Ground">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0.513725519" G="0" R="1"/>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="2" Z="0"/>
<Scale X="5" Y="1" Z="5"/>
<Position X="7" Y="-0.727000058" Z="-1.22800004"/>
<Scale X="50" Y="1.45100009" Z="50"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Player">
<Entity name="RedSpawn">
<Components>
<c:AABB>
<Origin X="0" Y="0.773000062" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:Collidable/>
<c:Physics/>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Player/>
<c:PlayerSpawn/>
<c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner>
<c:Team>
<Team>
<Red/>
</Team>
</c:Team>
<c:Transform>
<Position X="0" Y="2.52699995" Z="0.0542778969"/>
<Position X="0.300000012" Y="0.0270000007" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Color A="1" B="0" G="0" R="1"/>
</c:Model>
<c:Transform>
<Position X="0.800000012" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Color A="1" B="0.0117647061" G="0" R="1"/>
</c:Model>
<c:Transform>
<Position X="-0.600000024" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="DirectionalLight">
<Components>
<c:DirectionalLight/>
<c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource>
</c:Model>
<c:Transform>
<Position X="-6.00145912" Y="1.42697716" Z="3.04144025"/>
<Orientation X="5.69400024" Y="841.179565" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Entity name="ObstacleCourse">
<Components>
<c:Model>
<Resource>Models/Test/ObstacleCourse.obj</Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity name="ObstacleCoursePlayerBox">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Physics>
<Velocity X="0" Y="-0.0934068039" Z="0"/>
</c:Physics>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0" G="1" R="1"/>
<Visible>false</Visible>
</c:Model>
<c:Player/>
<c:Transform>
<Position X="0" Y="4.15580511" Z="0"/>
<Scale X="0.704558551" Y="0.115156889" Z="1"/>
<Position X="6.32800007" Y="0.807000041" Z="-2.2750001"/>
<Scale X="1" Y="1.60000002" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="ObstacleCourse1uHigh">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="9.11900043" Y="0.5" Z="-2.10900021"/>
<Scale X="1" Y="1" Z="8.1960001"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="ObstacleCourseWhoTheFuckKnows">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="13.2370005" Y="1.28600001" Z="-1.71700013"/>
<Scale X="2.58000016" Y="2.58300018" Z="21.1860008"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="BlueSpawn">
<Components>
<c:PlayerSpawn/>
<c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner>
<c:Team>
<Team>
<Blue/>
</Team>
</c:Team>
<c:Transform>
<Position X="0.300000012" Y="0.0270000007" Z="6.67400026"/>
<Orientation X="0" Y="3.20700026" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Color A="1" B="1" G="0.254901975" R="0"/>
</c:Model>
<c:Transform>
<Position X="0.800000012" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Color A="1" B="1" G="0.254901975" R="0"/>
</c:Model>
<c:Transform>
<Position X="-0.600000024" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+112 -9
View File
@@ -2,17 +2,120 @@
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:AABB/>
<c:Physics/>
<c:AABB>
<Origin X="0" Y="0.772000015" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Player/>
<c:Transform/>
<c:Model/>
<c:Physics>
<Velocity X="8.33307467e-09" Y="0" Z="9.82836834e-09"/>
</c:Physics>
<c:Player>
<MovementSpeed>5</MovementSpeed>
</c:Player>
<c:Team>
<Team>
<Red/>
</Team>
</c:Team>
<c:Transform>
<Position X="2.84928203" Y="0.0264999866" Z="7.31610918"/>
<Orientation X="0" Y="2.14675093" Z="0"/>
</c:Transform>
</Components>
<Children/>
<Children>
<Entity name="Camera">
<Components>
<c:Camera/>
<c:Transform>
<Position X="0" Y="1.37700009" Z="0"/>
<Orientation X="0.921535373" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="PlayerName">
<Components>
<c:Text>
<Resource>Fonts/DroidSans.ttf,100</Resource>
<Color A="1" B="0" G="1" R="0"/>
<Visible>false</Visible>
</c:Text>
<c:Transform>
<Position X="0" Y="0.247910097" Z="-0.447844714"/>
<Scale X="0.100000001" Y="0.113000005" Z="0.5"/>
<Orientation X="0" Y="3.14199996" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="CameraModel">
<Components>
<c:Model>
<Resource>Models/Camera.obj</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
<Scale X="1.30000007" Y="1.50000012" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="ThirdPersonCamera">
<Components>
<c:Camera/>
<c:Model>
<Resource>Models/Camera.obj</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="-0.284000009" Y="1.83800006" Z="1.18900001"/>
<Orientation X="5.95600033" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="PlayerModel">
<Components>
<c:Model>
<Resource>Models/AssaultHeadless.obj</Resource>
</c:Model>
<c:Transform>
<Orientation X="0" Y="3.14159274" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="AABBStanding">
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="0.427450985" B="1" G="1" R="1"/>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="0.772000015" Z="0"/>
<Scale X="1" Y="1.60000002" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="AABBCrouching">
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="0.745098054" B="1" G="0" R="1"/>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="0.772000015" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+259 -55
View File
@@ -1,58 +1,262 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd" xmlns:c="components">
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform>
<Position X="0" Y="0" Z="0"/>
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="1" Z="10"/>
</c:Transform>
<c:Model>
<Resource>Models/Camera.obj</Resource>
</c:Model>
<c:Camera>
<Name>MainCamera</Name>
</c:Camera>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="5" Y="1" Z="5"/>
</c:Transform>
<c:Model>
<Resource>Models/Camera.obj</Resource>
</c:Model>
<c:Camera>
<Name>ActionCamera</Name>
</c:Camera>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="-1" Z="0"/>
<Scale X="100" Y="1" Z="100"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitPlane.obj</Resource>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0" Z="0"/>
</c:Transform>
<c:Model>
<Resource>An error</Resource>
</c:Model>
</Components>
</Entity>
</Children>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Camera>
<Name>ActionCamera</Name>
</c:Camera>
<c:Model>
<Resource>Models/Camera.obj</Resource>
</c:Model>
<c:Transform>
<Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/>
<Orientation X="-0.733036518" Y="0.000105090476" Z="5.12391125e-07"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Text>
<Content>Camera #2</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>0</Alignment>
</c:Text>
<c:Transform>
<Position X="0.700063765" Y="0.310270816" Z="-1"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitPlane.obj</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="-1" Z="0.600000024"/>
<Scale X="100" Y="1" Z="100"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>Models/Assault.obj</Resource>
</c:Model>
<c:Transform>
<Position X="-2.5" Y="0" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Text>
<Content>Welcome!</Content>
<Resource>Fonts/DroidSans.ttf,1280</Resource>
</c:Text>
<c:Transform>
<Position X="0" Y="0" Z="0.700000048"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:RaptorCopter>
<Speed>2</Speed>
<Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="2.37320328" Z="0"/>
<Orientation X="0" Y="8252.15918" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="0" R="1"/>
<Radius>6</Radius>
<Intensity>0.5</Intensity>
</c:PointLight>
<c:Transform>
<Position X="-2.5" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="0" R="1"/>
<Radius>8</Radius>
</c:PointLight>
<c:Transform>
<Position X="-5" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="1" R="1"/>
<Radius>6</Radius>
<Intensity>0.5</Intensity>
</c:PointLight>
<c:Transform>
<Position X="0" Y="0" Z="-2.5"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="1" R="0"/>
<Radius>8</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="0" Z="-5"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="1" R="0"/>
<Radius>6</Radius>
<Intensity>0.5</Intensity>
</c:PointLight>
<c:Transform>
<Position X="0" Y="0" Z="2.5"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="0.00784313772" R="0"/>
<Radius>8</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="0" Z="5"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Radius>6</Radius>
<Intensity>0.5</Intensity>
</c:PointLight>
<c:Transform>
<Position X="2.5" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Radius>8</Radius>
</c:PointLight>
<c:Transform>
<Position X="5" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>Models/Assault.obj</Resource>
</c:Model>
<c:Transform>
<Position X="2.5" Y="0" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Camera>
<Name>MainCamera</Name>
</c:Camera>
<c:Listener/>
<c:Model>
<Resource>Models/Camera.obj</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="-1.27354908" Y="5.18422079" Z="10.6223917"/>
<Orientation X="-0.436328411" Y="-0.0523675606" Z="1.67869363e-08"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Text>
<Content>Taiwan #1</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>0</Alignment>
</c:Text>
<c:Transform>
<Position X="0.716896772" Y="0.296712071" Z="-1"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:DirectionalLight>
<Color A="1" B="0.996078432" G="1" R="1"/>
<Intensity>0.80000001192092896</Intensity>
</c:DirectionalLight>
<c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource>
</c:Model>
<c:Transform>
<Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/>
<Orientation X="-0.859663308" Y="-0.100310192" Z="-0.404723018"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
</c:Model>
<c:Transform>
<Position X="-5.4082036" Y="0" Z="-1.84950542"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+3
View File
@@ -16,6 +16,9 @@
<xs:simpleType name="double">
<xs:restriction base="xs:decimal"></xs:restriction>
</xs:simpleType>
<xs:simpleType name="float">
<xs:restriction base="xs:decimal"></xs:restriction>
</xs:simpleType>
<xs:simpleType name="string">
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
+1
View File
@@ -16,6 +16,7 @@
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/>
<xs:element ref="c:Camera" minOccurs="0"/>
<xs:element ref="c:Text" minOccurs="0"/>
<xs:element ref="c:AABB" minOccurs="0"/>
<xs:element ref="c:Trigger" minOccurs="0"/>
<xs:element ref="c:Health" minOccurs="0"/>
@@ -0,0 +1,32 @@
#version 430
layout (binding = 0) uniform sampler2D SceneTexture;
layout (binding = 1) uniform sampler2D BloomTexture;
uniform float Exposure;
in VertexData{
vec2 TextureCoordinate;
}Input;
out vec4 fragmentColor;
void main()
{
const float gamma = 2.2;
vec4 hdrColor = texture(SceneTexture, Input.TextureCoordinate);
vec4 bloomColor = texture(BloomTexture, Input.TextureCoordinate);
hdrColor += bloomColor;
//Toon mapping thingy
vec3 result = vec3(1.0) - exp(-hdrColor.rgb * Exposure);
//gamme correction
result = pow(result, vec3(1.0 / gamma));
fragmentColor = vec4(result, 1.0);
//fragmentColor = hdrColor;
//fragmentColor = bloomColor;
//fragmentColor = vec4(1,0.5,0.7,1);
}
@@ -0,0 +1,13 @@
#version 430
layout (location = 0) in vec3 Position;
out VertexData{
vec2 TextureCoordinate;
}Output;
void main()
{
gl_Position = vec4(Position, 1.0);
Output.TextureCoordinate = (vec2(Position) + 1) / 2;
}
+32 -26
View File
@@ -5,8 +5,8 @@ uniform mat4 V;
uniform mat4 P;
uniform vec4 Color;
uniform vec2 ScreenDimensions;
layout(binding = 0) uniform sampler2D DiffuseTexture;
layout(binding = 1) uniform sampler2D NormalMapTexture;
layout (binding = 0) uniform sampler2D DiffuseTexture;
layout (binding = 1) uniform sampler2D GlowMap;
#define TILE_SIZE 16
@@ -45,13 +45,12 @@ layout (std430, binding = 4) buffer LightIndexBuffer
in VertexData{
vec3 Position;
vec3 Normal;
vec3 Tangent;
vec3 BiTangent;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Input;
out vec4 fragmentColor;
out vec4 sceneColor;
out vec4 bloomColor;
vec4 scene_ambient = vec4(0.3,0.3,0.3,1);
@@ -99,18 +98,13 @@ LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensi
return result;
}
vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textureCoordinate, sampler2D normalMap)
{
mat3 TBN = mat3(tangent, bitangent, normal);
vec3 NormalMap = texture(normalMap, textureCoordinate).xyz * 2.0 - vec3(1.0);
return vec4(TBN * normalize(NormalMap), 0.0);
}
void main()
{
vec4 texel = texture2D(DiffuseTexture, Input.TextureCoordinate);
vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate);
vec4 glowTexel = texture2D(GlowMap, Input.TextureCoordinate);
vec4 position = V * M * vec4(Input.Position, 1.0);
vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, NormalMapTexture);
vec4 normal = normalize(V * vec4(Input.Normal, 0.0));
vec4 viewVec = normalize(-position);
vec2 tilePos;
@@ -129,30 +123,42 @@ void main()
int l = int(LightIndex[i]);
LightSource light = LightSources.List[l];
LightResult result;
LightResult light_result;
//These if statements should be removed.
if(light.Type == 1) { // point
result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff);
light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff);
} else if (light.Type == 2) { //Directional
result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
}
totalLighting.Diffuse += result.Diffuse;
totalLighting.Specular += result.Specular;
totalLighting.Diffuse += light_result.Diffuse;
totalLighting.Specular += light_result.Specular;
}
//sceneColor += Input.DiffuseColor;
vec4 color_result = Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color;
//bloomColor = vec4(0.3, 0.8, 0.6, 1.0);
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
//These if statements should be removed if they are slow.
color_result += glowTexel;
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0);
/*
if(color_result.x > 1 || color_result.y > 1 || color_result.z > 1) {
bloomColor = vec4(color_result.xyz, 1.0);
} else {
bloomColor = vec4(0.0, 0.0, 0.0, 1.0);
} */
//fragmentColor += Input.DiffuseColor;
fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color;
//fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color;
//fragmentColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1);
//fragmentColor = texel * Input.DiffuseColor * Color;
//fragmentColor += vec4(currentTile/3600.f, 0, 0, 1);
//sceneColor += Input.DiffuseColor * (totalLighting.Diffuse) * diffuseTexel * Color;
//sceneColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1);
//sceneColor = diffuseTexel * Input.DiffuseColor * Color;
//sceneColor += vec4(currentTile/3600.f, 0, 0, 1);
//Tiled Debug Code
/*
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) {
fragmentColor += vec4(0.5, 0, 0, 0);
sceneColor += vec4(0.5, 0, 0, 0);
} else {
fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1);
sceneColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1);
}
*/
}
-4
View File
@@ -19,8 +19,6 @@ layout(location = 10) in vec4 BoneWeights2;
out VertexData{
vec3 Position;
vec3 Normal;
vec3 Tangent;
vec3 BiTangent;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output;
@@ -32,7 +30,5 @@ void main()
Output.Position = Position;
Output.TextureCoordinate = TextureCoords;
Output.Normal = vec3(M * vec4(Normal, 0.0));
Output.Tangent = vec3(M * vec4(Tangent, 0.0));
Output.BiTangent = vec3(M * vec4(BiTangent, 0.0));
Output.DiffuseColor = DiffuseVertexColor;
}
@@ -0,0 +1,23 @@
#version 430
layout (binding = 0) uniform sampler2D Texture;
in VertexData{
vec2 TextureCoordinate;
}Input;
out vec4 fragmentColor;
uniform float weight[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
void main()
{
vec2 tex_offset = 1.0 / textureSize(Texture, 0);
vec3 result = texture(Texture, Input.TextureCoordinate).rgb * weight[0];
for(int i = 1; i < 5; ++i) {
result += texture(Texture, Input.TextureCoordinate + vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
result += texture(Texture, Input.TextureCoordinate - vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
}
fragmentColor = vec4(result, 1.0);
}
@@ -0,0 +1,13 @@
#version 430
layout (location = 0) in vec3 Position;
out VertexData{
vec2 TextureCoordinate;
}Output;
void main()
{
gl_Position = vec4(Position, 1.0);
Output.TextureCoordinate = (vec2(Position) + 1) / 2;
}
+23
View File
@@ -0,0 +1,23 @@
#version 430
layout (binding = 0) uniform sampler2D Texture;
in VertexData{
vec2 TextureCoordinate;
}Input;
out vec4 fragmentColor;
uniform float weight[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
void main()
{
vec2 tex_offset = 1.0 / textureSize(Texture, 0);
vec3 result = texture(Texture, Input.TextureCoordinate).rgb * weight[0];
for(int i = 1; i < 5; ++i) {
result += texture(Texture, Input.TextureCoordinate + vec2(0.0, tex_offset.y * i)).rgb * weight[i];
result += texture(Texture, Input.TextureCoordinate - vec2(0.0, tex_offset.y * i)).rgb * weight[i];
}
fragmentColor = vec4(result, 1.0);
}
+13
View File
@@ -0,0 +1,13 @@
#version 430
layout (location = 0) in vec3 Position;
out VertexData{
vec2 TextureCoordinate;
}Output;
void main()
{
gl_Position = vec4(Position, 1.0);
Output.TextureCoordinate = (vec2(Position) + 1) / 2;
}
+17
View File
@@ -0,0 +1,17 @@
#version 430
in vec2 TexCoords;
out vec4 color;
uniform sampler2D text;
uniform vec4 textColor;
out vec4 sceneColor;
out vec4 bloomColor;
void main()
{
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
vec4 color_result = textColor * sampled;
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0) * sampled;
}
+13
View File
@@ -0,0 +1,13 @@
#version 430
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
out vec2 TexCoords;
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
void main()
{
gl_Position = P * V * M * vec4(vertex.xy, 0.0, 1.0);
TexCoords = vertex.zw;
}
+3
View File
@@ -8,6 +8,7 @@ find_package(assimp REQUIRED)
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(Xerces REQUIRED)
find_package(Freetype REQUIRED)
# Because FindOpenAL is retarded
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/OpenAL")
find_package(OpenAL REQUIRED)
@@ -25,6 +26,7 @@ include_directories(
${assimp_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS}
${Xerces_INCLUDE_DIRS}
${FREETYPE_INCLUDE_DIRS}
${OPENAL_INCLUDE_DIR}
${X11_INCLUDE_DIRS}
)
@@ -126,6 +128,7 @@ set(LIBRARIES
${assimp_LIBRARIES}
${PNG_LIBRARIES}
${Xerces_LIBRARIES}
${FREETYPE_LIBRARIES}
${OPENAL_LIBRARY}
${X11_LIBRARIES}
)
+1 -1
View File
@@ -31,7 +31,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
}
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
(glm::vec3&)cTransform["Position"] += resolutionVector;
cPhysics["Velocity"] = glm::vec3(0, 0, 0);
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
}
}
+31
View File
@@ -5,6 +5,9 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Inv
bool EntityWrapper::HasComponent(const std::string& componentName)
{
if (!Valid()) {
return false;
}
return World->HasComponent(ID, componentName);
}
@@ -17,6 +20,34 @@ EntityWrapper EntityWrapper::Parent()
}
}
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
{
auto itPair = this->World->GetChildren(this->ID);
if (itPair.first == itPair.second) {
return EntityWrapper::Invalid;
}
for (auto it = itPair.first; it != itPair.second; ++it) {
if (this->World->GetName(it->second) == name) {
return EntityWrapper(this->World, it->second);
}
}
return EntityWrapper::Invalid;
}
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
{
EntityWrapper entity = *this;
while (entity.Parent().Valid()) {
entity = entity.Parent();
if (entity == potentialParent) {
return true;
}
}
return false;
}
bool EntityWrapper::Valid()
{
if (this->World == nullptr) {
+1 -1
View File
@@ -276,7 +276,7 @@ std::vector<int> Child::childIndicesContainingBox(const AABB& box) const
}
}
inline bool Child::hasChildren() const
bool Child::hasChildren() const
{
return m_Children[0] != nullptr;
}
+20
View File
@@ -1,5 +1,10 @@
#include "Core/Transform.h"
glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
{
return AbsolutePosition(entity.World, entity.ID);
}
glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
{
glm::vec3 position;
@@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
return position;
}
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
{
return AbsoluteOrientation(entity.World, entity.ID);
}
glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
{
glm::quat orientation;
@@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
return orientation;
}
glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
{
return AbsoluteScale(entity.World, entity.ID);
}
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
{
glm::vec3 scale(1.f);
@@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
return scale;
}
glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
{
return ModelMatrix(entity.ID, entity.World);
}
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
{
glm::vec3 position = Transform::AbsolutePosition(world, entity);
+77 -17
View File
@@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
m_ActualCamera = m_EditorCamera;
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform");
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera");
m_EditorCameraInputController = new EditorCameraInputController<EditorSystem>(m_EventBroker, -1);
m_EditorGUI = new EditorGUI(m_World, m_EventBroker);
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
@@ -33,38 +34,70 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera);
m_EditorStats = new EditorStats();
Events::SetCamera e;
e.CameraEntity = m_Camera;
m_EventBroker->Publish(e);
if (m_Enabled) {
Enable();
}
}
EditorSystem::~EditorSystem()
{
delete m_EditorStats;
delete m_EditorGUI;
delete m_DebugCameraInputController;
delete m_EditorCameraInputController;
delete m_EditorWorldSystemPipeline;
delete m_EditorWorld;
}
void EditorSystem::Update(double dt)
{
m_EventBroker->Process<EditorGUI>();
m_EditorGUI->Draw();
m_EditorStats->Draw(dt);
double now = glfwGetTime();
double actualDelta = now - m_LastTime;
m_LastTime = now;
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
if (m_Enabled) {
m_EventBroker->Process<EditorGUI>();
m_EditorGUI->Draw();
m_EditorStats->Draw(actualDelta);
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
}
m_EditorWorldSystemPipeline->Update(actualDelta);
ComponentWrapper& cameraTransform = m_EditorCamera["Transform"];
glm::vec3& ori = cameraTransform["Orientation"];
ori.x = m_EditorCameraInputController->Rotation().x;
ori.y = m_EditorCameraInputController->Rotation().y;
glm::vec3& pos = cameraTransform["Position"];
pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta;
}
}
m_EditorWorldSystemPipeline->Update(dt);
void EditorSystem::Enable()
{
m_EditorCameraInputController->Enable();
m_EventBroker->Publish(Events::UnlockMouse());
Events::SetCamera e;
e.CameraEntity = m_EditorCamera;
m_EventBroker->Publish(e);
(glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera);
m_Enabled = true;
}
m_DebugCameraInputController->Update(dt);
m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position();
m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation());
void EditorSystem::Disable()
{
m_EditorCameraInputController->Disable();
m_EventBroker->Publish(Events::LockMouse());
Events::SetCamera e;
e.CameraEntity = m_ActualCamera;
m_EventBroker->Publish(e);
m_Enabled = false;
}
void EditorSystem::OnEntitySelected(EntityWrapper entity)
@@ -148,6 +181,33 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
return true;
}
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
{
if (e.PlayerID != -1) {
return false;
}
if (e.Command == "ToggleEditor" && e.Value > 0) {
if (m_Enabled) {
Disable();
} else {
Enable();
}
}
return true;
}
bool EditorSystem::OnSetCamera(const Events::SetCamera& e)
{
if (m_Enabled && e.CameraEntity != m_EditorCamera) {
m_ActualCamera = e.CameraEntity;
Events::SetCamera e2;
e2.CameraEntity = m_EditorCamera;
m_EventBroker->Publish(e2);
}
return true;
}
EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath)
{
if (parent.World == nullptr) {
+65 -24
View File
@@ -5,14 +5,20 @@ using namespace boost::asio::ip;
Client::Client(ConfigFile* config) : m_Socket(m_IOService)
{
Network::initialize();
// Asumes root node is EntityID 0
insertIntoServerClientMaps(0, 0);
// Init timer
m_TimeSinceSentInputs = std::clock();
// Default is local host
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
int port = config->Get<int>("Networking.Port", 13);
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
// Set up network stream
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
}
Client::~Client()
@@ -37,19 +43,24 @@ void Client::Update()
readFromServer();
if (m_IsConnected) {
hasServerTimedOut();
// Don't sent 1 input in 1 packet, bunch em up.
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
sendInputCommands();
m_TimeSinceSentInputs = std::clock();
}
}
Network::Update();
}
void Client::readFromServer()
{
while (m_Socket.available()) {
bytesRead = receive(readBuf, INPUTSIZE);
bytesRead = receive(readBuf);
if (bytesRead > 0) {
Packet packet(readBuf, bytesRead);
parseMessageType(packet);
}
}
sendInputCommands();
}
void Client::parseMessageType(Packet& packet)
@@ -66,12 +77,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::Connect:
parseConnect(packet);
break;
case MessageType::ClientPing:
case MessageType::Ping:
parsePing();
break;
case MessageType::ServerPing:
parseServerPing();
break;
case MessageType::Message:
break;
case MessageType::Snapshot:
@@ -81,6 +89,13 @@ void Client::parseMessageType(Packet& packet)
break;
case MessageType::PlayerConnected:
parsePlayerConnected(packet);
break;
case MessageType::Kick:
parseKick();
break;
case MessageType::OnPlayerSpawned:
parsePlayersSpawned(packet);
break;
default:
break;
}
@@ -99,11 +114,6 @@ void Client::parsePlayerConnected(Packet & packet)
}
void Client::parsePing()
{
}
void Client::parseServerPing()
{
// Might miss connect message so set it here instead.
m_IsConnected = true;
@@ -112,11 +122,26 @@ void Client::parseServerPing()
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
m_StartPingTime = std::clock();
Packet packet(MessageType::ServerPing, m_SendPacketID);
Packet packet(MessageType::Ping, m_SendPacketID);
packet.WriteString("Ping recieved");
send(packet);
}
void Client::parseKick()
{
LOG_WARNING("You have been kicked from the server.");
m_IsConnected = false;
}
void Client::parsePlayersSpawned(Packet& packet)
{
Events::PlayerSpawned e;
e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
e.PlayerID = -1;
m_EventBroker->Publish(e);
}
// Fields with strings will not work right now
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
{
@@ -153,8 +178,12 @@ void Client::parseSnapshot(Packet& packet)
{
std::string componentType = packet.ReadString();
while (packet.DataReadSize() < packet.Size()) {
// HACK
std::string entityName = packet.ReadString();
// Components EntityID
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>();
// HACK
m_World->SetName(receivedEntityID, entityName);
// Parents EntityID
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>();
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
@@ -211,15 +240,20 @@ void Client::parseSnapshot(Packet& packet)
}
}
int Client::receive(char* data, size_t length)
int Client::receive(char* data)
{
boost::system::error_code error;
int bytesReceived = m_Socket.receive_from(boost
::asio::buffer((void*)data, length),
::asio::buffer((void*)data, INPUTSIZE),
m_ReceiverEndpoint,
0, error);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataReceived += bytesReceived;
m_NetworkData.DataReceivedThisInterval += bytesReceived;
m_NetworkData.AmountOfMessagesReceived++;
}
if (error) {
//LOG_ERROR("receive: %s", error.message().c_str());
}
@@ -232,6 +266,12 @@ void Client::send(Packet& packet)
packet.Data(),
packet.Size()),
m_ReceiverEndpoint, 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
}
void Client::connect()
@@ -250,14 +290,6 @@ void Client::disconnect()
send(packet);
}
void Client::ping()
{
//Packet packet(MessageType::Connect, m_SendPacketID);
//packet.WriteString("Ping");
//m_StartPingTime = std::clock();
//send(packet);
}
bool Client::OnInputCommand(const Events::InputCommand & e)
{
if (e.Command == "ConnectToServer") { // Connect for now
@@ -275,6 +307,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
if (e.Value > 0) {
becomePlayer();
}
} else if (e.Command == "LogNetworkBandwidth") {
if (e.Value > 0) {
// Save to file if we no longer want to read data.
if (isReadingData) {
saveToFile();
}
isReadingData = !isReadingData;
m_SaveDataTimer = std::clock();
}
} else {
m_InputCommandBuffer.push_back(e);
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
@@ -305,7 +346,7 @@ bool Client::hasServerTimedOut()
{
// Time in ms
float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
if (timeSincePing > TIMEOUTMS) {
if (timeSincePing > m_TimeoutMs) {
// Clear everything and go to menu.
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
m_IsConnected = false;
+68
View File
@@ -0,0 +1,68 @@
#include "Network/Network.h"
void Network::Update()
{
updateNetworkData();
}
void Network::saveToFile()
{
std::ofstream outfile;
time_t t = time(0);
// get time now
struct tm * now = localtime(&t);
// Get current time and date
std::string dateAndTime = "BandwidthData - " + std::to_string(now->tm_year + 1900) + '-'
+ std::to_string(now->tm_mon + 1) + '-'
+ std::to_string(now->tm_mday) + '_'
+ std::to_string(now->tm_hour) + "h."
+ std::to_string(now->tm_min) + "m."
+ std::to_string(now->tm_sec) + 's';
outfile.open(dateAndTime + ".csv");
outfile << "Total time," + std::to_string(m_NetworkData.TotalTime) + "\n";
outfile << "Total data received," + std::to_string(m_NetworkData.TotalDataReceived) + "\n";
outfile << "Total data sent," + std::to_string(m_NetworkData.TotalDataSent) + "\n";
outfile << "Total messages received," + std::to_string(m_NetworkData.AmountOfMessagesReceived) + "\n";
outfile << "Total messages sent," + std::to_string(m_NetworkData.AmountOfMessagesSent) + "\n";
float messagesReceivedPerSec = (float)m_NetworkData.AmountOfMessagesReceived / (m_NetworkData.TotalTime / 1000);
float messagesSentPerSec = (float)m_NetworkData.AmountOfMessagesSent / (m_NetworkData.TotalTime / 1000);
float dataReceivedPerSec = (float)m_NetworkData.TotalDataReceived / (m_NetworkData.TotalTime / 1000);
float dataSentPerSec = (float)m_NetworkData.TotalDataSent / (m_NetworkData.TotalTime / 1000);
outfile << "Avarage messages received / s: " + std::to_string(messagesReceivedPerSec) + "\n";
outfile << "Avarage messages sents / s: " + std::to_string(messagesSentPerSec) + "\n";
outfile << "Avarage data received B/s: " + std::to_string(dataReceivedPerSec) + "\n";
outfile << "Avarage data sents B/s: " + std::to_string(dataSentPerSec) + "\n";
outfile << "time, avg receive B, avg send B\n";
for (int i = 0; i < m_NetworkData.BandwidthBytes.size(); i++) {
outfile << std::to_string(i) + ",";
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].first) + ",";
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].second) + "\n";
}
outfile.close();
}
void Network::updateNetworkData()
{
std::clock_t currentTime = std::clock();
// Send snapshot
if (m_SaveDataIntervalMs < (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC)) {
// Set values
m_NetworkData.TotalTime += (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC);
m_NetworkData.BandwidthBytes.push_back(std::pair<unsigned int, unsigned int>(m_NetworkData.DataReceivedThisInterval, m_NetworkData.DataSentThisInterval));
// Reset interval stuff
m_SaveDataTimer = std::clock();
m_NetworkData.DataSentThisInterval = 0;
m_NetworkData.DataReceivedThisInterval = 0;
}
}
void Network::initialize()
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_MaxConnections = config->Get<int>("Networking.MaxConnections", 8);
m_TimeoutMs = config->Get<int>("Networking.TimeoutMs", 20000);
}
+1
View File
@@ -39,6 +39,7 @@ void Packet::Init(MessageType type, unsigned int & packetID)
Packet::WritePrimitive<int>(messageType);
Packet::WritePrimitive<int>(packetID);
packetID++;
m_HeaderSize = m_Offset;
}
void Packet::WriteString(const std::string& str)
+114 -39
View File
@@ -1,7 +1,13 @@
#include "Network/Server.h"
Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13))
{ }
Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))
{
Network::initialize();
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05);
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
}
Server::~Server()
{
@@ -14,7 +20,8 @@ void Server::Start(World* world, EventBroker* eventBroker)
m_EventBroker = eventBroker;
// Subscribe to events
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
for (size_t i = 0; i < m_MaxConnections; i++) {
m_PlayerDefinitions[i].StopTime = std::clock();
}
LOG_INFO("I am Server. BIP BOP\n");
@@ -24,14 +31,17 @@ void Server::Update()
{
readFromClients();
m_EventBroker->Process<Server>();
}
if (isReadingData) {
Network::Update();
}
}
void Server::readFromClients()
{
while (m_Socket.available()) {
try {
bytesRead = receive(readBuffer, INPUTSIZE);
bytesRead = receive(readBuffer);
Packet packet(readBuffer, bytesRead);
parseMessageType(packet);
} catch (const std::exception& err) {
@@ -46,7 +56,7 @@ void Server::readFromClients()
}
// Send pings each
if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
sendPing();
previousePingMessage = currentTime;
}
@@ -70,11 +80,8 @@ void Server::parseMessageType(Packet& packet)
case MessageType::Connect:
parseConnect(packet);
break;
case MessageType::ClientPing:
//parseClientPing();
break;
case MessageType::ServerPing:
parseServerPing();
case MessageType::Ping:
parsePing();
break;
case MessageType::Message:
break;
@@ -97,21 +104,47 @@ void Server::parseMessageType(Packet& packet)
}
}
int Server::receive(char * data, size_t length)
int Server::receive(char * data)
{
length = m_Socket.receive_from(
unsigned int length = m_Socket.receive_from(
boost::asio::buffer((void*)data
, length)
, INPUTSIZE)
, m_ReceiverEndpoint, 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataReceived += length;
m_NetworkData.DataReceivedThisInterval += length;
m_NetworkData.AmountOfMessagesReceived++;
}
return length;
}
void Server::send(Packet& packet, int userID)
void Server::send(Packet& packet, UserID user)
{
int bytesSent = m_Socket.send_to(
boost::asio::buffer(packet.Data(), packet.Size()),
m_ConnectedUsers[userID].Endpoint,
m_ConnectedUsers[user].Endpoint,
0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
}
void Server::send(PlayerID player, Packet& packet)
{
int bytesSent = m_Socket.send_to(
boost::asio::buffer(packet.Data(), packet.Size()),
m_PlayerDefinitions[player].Endpoint,
0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
}
void Server::send(Packet & packet)
@@ -122,6 +155,11 @@ void Server::send(Packet & packet)
packet.Size()),
m_ReceiverEndpoint,
0);
if (isReadingData) {
// Network Debug data
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
}
}
void Server::broadcast(Packet& packet)
@@ -143,9 +181,12 @@ void Server::sendSnapshot()
Packet packet(MessageType::Snapshot);
ComponentPool* componentPool = it.second;
ComponentInfo componentInfo = componentPool->ComponentInfo();
// Component Type
packet.WriteString(componentInfo.Name);
for (auto& componentWrapper : *componentPool) {
// HACK: Send entity name
packet.WriteString(m_World->GetName(componentWrapper.EntityID));
// Components EntityID
packet.WritePrimitive(componentWrapper.EntityID);
// Parents EntityID
@@ -160,7 +201,9 @@ void Server::sendSnapshot()
}
}
}
broadcast(packet);
if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) {
broadcast(packet);
}
}
}
@@ -174,7 +217,7 @@ void Server::sendPing()
}
}
// Create ping message
Packet packet(MessageType::ServerPing);
Packet packet(MessageType::Ping);
packet.WriteString("Ping from server");
// Time message
m_StartPingTime = std::clock();
@@ -191,7 +234,7 @@ void Server::checkForTimeOuts()
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
int stopPing = 1000 * m_ConnectedUsers[i].StopTime /
static_cast<double>(CLOCKS_PER_SEC);
if (startPing > stopPing + TIMEOUTMS) {
if (startPing > stopPing + m_TimeoutMs) {
LOG_INFO("User %i timed out!", i);
disconnect(i);
}
@@ -199,35 +242,40 @@ void Server::checkForTimeOuts()
}
}
void Server::disconnect(int i)
void Server::disconnect(UserID user)
{
//broadcast("A player disconnected");
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str());
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].Name.c_str());
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint();
m_PlayerDefinitions[i].EntityID = -1;
m_PlayerDefinitions[i].Name = "";
m_PlayerDefinitions[i].PacketID = 0;
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i);
Events::PlayerDisconnected e;
e.Entity = m_PlayerDefinitions[user].EntityID;
e.PlayerID = user;
m_EventBroker->Publish(e);
m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint();
m_PlayerDefinitions[user].EntityID = -1;
m_PlayerDefinitions[user].Name = "";
m_PlayerDefinitions[user].PacketID = 0;
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + user);
}
void Server::parseOnInputCommand(Packet& packet)
{
int playerID = -1;
PlayerID player = -1;
// Check which player it was who sent the message
for (int i = 0; i < MAXCONNECTIONS; i++) {
for (int i = 0; i < m_MaxConnections; i++) {
// if the player is connected set playerID to the correct PlayerID
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()
&& m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
playerID = i;
player = i;
break;
}
}
if (playerID != -1) {
if (player != -1) {
while (packet.DataReadSize() < packet.Size()) {
Events::InputCommand e;
e.Command = packet.ReadString();
e.PlayerID = playerID; // Set correct player id
e.PlayerID = player; // Set correct player id
e.Value = packet.ReadPrimitive<float>();
m_EventBroker->Publish(e);
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
@@ -292,17 +340,17 @@ void Server::parseDisconnect()
void Server::parseClientPing()
{
LOG_INFO("%i: Parsing ping", m_PacketID);
int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
if (playerID == -1) {
PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
if (player == -1) {
return;
}
// Return ping
Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID);
Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID);
packet.WriteString("Ping received");
send(packet);
}
void Server::parseServerPing()
void Server::parsePing()
{
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
@@ -328,7 +376,7 @@ void Server::createPlayer()
LOG_WARNING("Already connected!");
return;
}
int userIndex;
UserID userIndex;
for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) {
if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() &&
m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) {
@@ -340,7 +388,7 @@ void Server::createPlayer()
LOG_WARNING("Not a recognized user!");
return;
}
for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) {
for (PlayerID playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) {
if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) {
m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex];
EntityID entityID = m_World->CreateEntity();
@@ -358,9 +406,16 @@ void Server::createPlayer()
}
int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
void Server::kick(PlayerID player)
{
for (int i = 0; i < MAXCONNECTIONS; i++) {
disconnect(player);
Packet packet = Packet(MessageType::Kick);
send(packet);
}
PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
{
for (int i = 0; i < m_MaxConnections; i++) {
if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() &&
m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) {
return i;
@@ -372,5 +427,25 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
bool Server::OnInputCommand(const Events::InputCommand & e)
{
//LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
if (e.Command == "LogNetworkBandwidth" && e.Value > 0) {
if (isReadingData) {
saveToFile();
}
isReadingData = !isReadingData;
m_SaveDataTimer = std::clock();
}
if (e.Command == "KickPlayer" && e.Value > 0) {
kick(0);
}
return true;
}
bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e)
{
Packet packet = Packet(MessageType::OnPlayerSpawned);
packet.WritePrimitive<EntityID>(e.Player.ID);
packet.WritePrimitive<EntityID>(e.Spawner.ID);
send(e.PlayerID, packet);
return false;
}
+134
View File
@@ -0,0 +1,134 @@
#include "Rendering/DrawBloomPass.h"
DrawBloomPass::DrawBloomPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
InitializeTextures();
InitializeBuffers();
InitializeShaderPrograms();
}
void DrawBloomPass::InitializeTextures()
{
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
}
void DrawBloomPass::InitializeShaderPrograms()
{
m_GaussianProgram_horiz = ResourceManager::Load<ShaderProgram>("##GaussianProgramHoriz");
m_GaussianProgram_horiz->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Gaussian_horiz.vert.glsl")));
m_GaussianProgram_horiz->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Gaussian_horiz.frag.glsl")));
m_GaussianProgram_horiz->Compile();
m_GaussianProgram_horiz->Link();
m_GaussianProgram_vert = ResourceManager::Load<ShaderProgram>("##GaussianProgramVert");
m_GaussianProgram_vert->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Gaussian_vert.vert.glsl")));
m_GaussianProgram_vert->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Gaussian_vert.frag.glsl")));
m_GaussianProgram_vert->Compile();
m_GaussianProgram_vert->Link();
}
void DrawBloomPass::InitializeBuffers()
{
GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
m_GaussianFrameBuffer_horiz.Generate();
GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
m_GaussianFrameBuffer_vert.Generate();
}
void DrawBloomPass::ClearBuffer()
{
m_GaussianFrameBuffer_horiz.Bind();
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GaussianFrameBuffer_horiz.Unbind();
m_GaussianFrameBuffer_vert.Bind();
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GaussianFrameBuffer_vert.Unbind();
}
void DrawBloomPass::Draw(GLuint texture)
{
GLERROR("DrawBloomPass::Draw: Pre");
DrawBloomPassState state;
GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle();
GLuint shaderHandle_vert = m_GaussianProgram_vert->GetHandle();
//Horizontal pass, first use the given texture then save it to the horizontal framebuffer.
m_GaussianFrameBuffer_horiz.Bind();
m_GaussianProgram_horiz->Bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
//Iterate some times to make it more gaussian.
for (int i = 1; i < m_iterations; i++) {
//Vertical pass
m_GaussianFrameBuffer_vert.Bind();
m_GaussianProgram_vert->Bind();
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
//horizontal pass
m_GaussianFrameBuffer_horiz.Bind();
m_GaussianProgram_horiz->Bind();
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
}
//final vertical gaussian after the iterations are done
m_GaussianFrameBuffer_vert.Bind();
m_GaussianProgram_vert->Bind();
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
GLERROR("DrawBloomPass::Draw: END");
}
void DrawBloomPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
{
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution
GLERROR("Texture initialization failed");
}
@@ -0,0 +1,15 @@
#include "Rendering/DrawBloomPassState.h"
DrawBloomPassState::DrawBloomPassState()
{
//BindFramebuffer(0);
Disable(GL_BLEND);
Disable(GL_DEPTH_TEST);
Disable(GL_CULL_FACE);
}
DrawBloomPassState::~DrawBloomPassState()
{
}
@@ -0,0 +1,41 @@
#include "Rendering/DrawColorCorrectionPass.h"
DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_Exposure = 1; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
InitializeShaderPrograms();
}
void DrawColorCorrectionPass::InitializeShaderPrograms()
{
m_ColorCorrectionProgram = ResourceManager::Load<ShaderProgram>("#ColorCorrectionProgram");
m_ColorCorrectionProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawColorCorrection.vert.glsl")));
m_ColorCorrectionProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawColorCorrection.frag.glsl")));
m_ColorCorrectionProgram->Compile();
m_ColorCorrectionProgram->Link();
}
void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture)
{
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("DrawScreenQuadPass::Draw: Pre");
DrawScreenQuadPassState state = DrawScreenQuadPassState();
m_ColorCorrectionProgram->Bind();
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(glGetUniformLocation(m_ColorCorrectionProgram->GetHandle(), "Exposure"), m_Exposure);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sceneTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, bloomTexture);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
}
+68 -13
View File
@@ -6,12 +6,31 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling
m_LightCullingPass = lightCullingPass;
InitializeTextures();
InitializeShaderPrograms();
InitializeFrameBuffers();
}
void DrawFinalPass::InitializeTextures()
{
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
m_NeutralNormalMap = ResourceManager::Load<Texture>("Textures/Core/NeutralNormalMap.png");
m_BlackTexture = ResourceManager::Load<Texture>("Textures/Core/Black.png");
}
void DrawFinalPass::InitializeFrameBuffers()
{
glGenRenderbuffers(1, &m_DepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
//GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
//GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_FLOAT, 4);
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0)));
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1)));
m_FinalPassFrameBuffer.Generate();
}
void DrawFinalPass::InitializeShaderPrograms()
@@ -20,6 +39,8 @@ void DrawFinalPass::InitializeShaderPrograms()
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ForwardPlus.vert.glsl")));
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/ForwardPlus.frag.glsl")));
m_ForwardPlusProgram->Compile();
m_ForwardPlusProgram->BindFragDataLocation(0, "sceneColor");
m_ForwardPlusProgram->BindFragDataLocation(1, "bloomColor");
m_ForwardPlusProgram->Link();
}
@@ -27,7 +48,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
{
GLERROR("DrawFinalPass::Draw: Pre");
DrawFinalPassState state;
DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle());
m_ForwardPlusProgram->Bind();
GLuint shaderHandle = m_ForwardPlusProgram->GetHandle();
@@ -52,22 +73,20 @@ void DrawFinalPass::Draw(RenderScene& scene)
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
glActiveTexture(GL_TEXTURE0);
if(modelJob->DiffuseTexture != nullptr) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture);
} else {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
}
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
if (modelJob->NormalTexture != nullptr) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, modelJob->NormalTexture->m_Texture);
}
else {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_NeutralNormalMap->m_Texture);
}
/*if(modelJob->GlowMap != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
} else {
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
}*/
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
@@ -76,6 +95,42 @@ void DrawFinalPass::Draw(RenderScene& scene)
continue;
}
}
m_FinalPassFrameBuffer.Unbind();
GLERROR("DrawFinalPass::Draw: END");
delete state;
}
void DrawFinalPass::ClearBuffer()
{
m_FinalPassFrameBuffer.Bind();
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_FinalPassFrameBuffer.Unbind();
}
void DrawFinalPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
{
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution
GLERROR("Texture initialization failed");
}
void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const
{
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexStorage2D(GL_TEXTURE_2D, numMipMaps, GL_RGBA8, dimensions.x, dimensions.y);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dimensions.x, dimensions.y, format, type, texture);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
GLERROR("MipMap Texture initialization failed");
}
+3 -3
View File
@@ -1,14 +1,14 @@
#include "Rendering/DrawFinalPassState.h"
DrawFinalPassState::DrawFinalPassState()
DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer)
{
BindFramebuffer(0);
BindFramebuffer(frameBuffer);
Enable(GL_BLEND);
BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
ClearColor(glm::vec4(200.f / 255, 0.f / 255, 200.f / 255, 0.f));
ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));
}
DrawFinalPassState::~DrawFinalPassState()
@@ -0,0 +1,37 @@
#include "Rendering/DrawScreenQuadPass.h"
DrawScreenQuadPass::DrawScreenQuadPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
InitializeShaderPrograms();
}
void DrawScreenQuadPass::InitializeShaderPrograms()
{
m_DrawQuadProgram = ResourceManager::Load<ShaderProgram>("#DrawScreenQuadProgram");
m_DrawQuadProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
m_DrawQuadProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
m_DrawQuadProgram->Compile();
m_DrawQuadProgram->Link();
}
void DrawScreenQuadPass::Draw(GLuint texture)
{
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("DrawScreenQuadPass::Draw: Pre");
DrawScreenQuadPassState state = DrawScreenQuadPassState();
m_DrawQuadProgram->Bind();
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
}
@@ -0,0 +1,18 @@
#include "Rendering/DrawScreenQuadPassState.h"
DrawScreenQuadPassState::DrawScreenQuadPassState()
{
GLERROR("---");
BindFramebuffer(0);
GLERROR("---");
Disable(GL_DEPTH_TEST);
Disable(GL_CULL_FACE);
Disable(GL_BLEND);
ClearColor(glm::vec4(0.f));
}
DrawScreenQuadPassState::~DrawScreenQuadPassState()
{
}
+108
View File
@@ -0,0 +1,108 @@
#include "Rendering/Font.h"
Font::Font(std::string path)
{
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
boost::char_separator<char> sep(",");
tokenizer tok(path, sep);
tokenizer::iterator it = tok.begin();
std::string filePath = "";
if (it != tok.end()) {
filePath = (*it).c_str();
it++;
if (it != tok.end()) {
if((*it).c_str() == "") {
throw std::runtime_error("");
}
try {
FontSize = boost::lexical_cast<int>((*it).c_str());
} catch (boost::bad_lexical_cast const&) {
LOG_ERROR("input string did not have a valid font resolution");
throw std::runtime_error("");
}
}
} else {
throw std::runtime_error("");;
}
FT_Library library;
FT_Face face;
if (FT_Init_FreeType(&library)) {
LOG_ERROR("FreeType error: init failed");
throw std::runtime_error("");;
}
if (FT_New_Face(library, filePath.c_str(), 0, &face)) {
LOG_ERROR("FreeType error: loading font");
throw std::runtime_error("");;
}
FT_Set_Char_Size(face, 0, FontSize*64, 300, 300); // temp
FT_Set_Pixel_Sizes(face, 0, FontSize); //
if (FT_Load_Char(face, 'X', FT_LOAD_RENDER)) {
LOG_ERROR("FreeType error: loading char");
throw std::runtime_error("");;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (GLubyte c = 0; c < 128; c++) {
//Load character glyph
if (FT_Load_Char(face, c, FT_LOAD_RENDER)) {
continue;
}
//Generate texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
// Set texture options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Now store character for later use
Character character = {
texture,
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
face->glyph->advance.x
};
m_Characters.insert(std::pair<GLchar, Character>(c, character));
}
FT_Done_Face(face);
FT_Done_FreeType(library);
GLERROR("Font Load");
}
Font::~Font()
{
for (auto c : m_Characters) {
glDeleteTextures(1, &c.second.TextureID);
}
}
+3 -4
View File
@@ -55,8 +55,9 @@ void FrameBuffer::Generate()
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
GLERROR("FrameBuffer generate: glFramebufferRenderbuffer");
if ( (*it)->m_Attachment != GL_COLOR_ATTACHMENT0 ||
(*it)->m_Attachment != GL_COLOR_ATTACHMENT1 ||
(*it)->m_Attachment != GL_DEPTH_ATTACHMENT ||
(*it)->m_Attachment != GL_STENCIL_ATTACHMENT)
(*it)->m_Attachment != GL_STENCIL_ATTACHMENT) //TODO: Viktor: Fixa detta
{
LOG_ERROR("RenderBuffer Attachment not valid.");
}
@@ -69,10 +70,8 @@ void FrameBuffer::Generate()
}
}
GLenum* bufferTextures = &attachments[0];
glDrawBuffers(1, bufferTextures);
glDrawBuffers(attachments.size(), bufferTextures);
if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus);
+31 -36
View File
@@ -47,61 +47,56 @@ void PickingPass::Draw(RenderScene& scene)
{
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
//TODO: Render: Add code for more jobs than modeljobs.
GLuint ShaderHandle = m_PickingProgram->GetHandle();
m_PickingProgram->Bind();
if (scene.ClearDepth) {
glClear(GL_DEPTH_BUFFER_BIT);
}
m_Camera = scene.Camera;
m_Camera = scene.Camera;
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) {
int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] };
if (modelJob) {
int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] };
PickingInfo pickInfo;
pickInfo.Entity = modelJob->Entity;
pickInfo.World = modelJob->World;
pickInfo.Camera = scene.Camera;
PickingInfo pickInfo;
pickInfo.Entity = modelJob->Entity;
pickInfo.World = modelJob->World;
pickInfo.Camera = scene.Camera;
auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera));
if (color != m_EntityColors.end()) {
pickColor[0] = color->second[0];
pickColor[1] = color->second[1];
auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera));
if (color != m_EntityColors.end()) {
pickColor[0] = color->second[0];
pickColor[1] = color->second[1];
} else {
m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]);
if (m_ColorCounter[0] > 255) {
m_ColorCounter[0] = 0;
m_ColorCounter[1]++;
} else {
m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]);
if (m_ColorCounter[0] > 255) {
m_ColorCounter[0] = 0;
m_ColorCounter[1]++;;
} else {
m_ColorCounter[0]++;;
}
m_ColorCounter[0]++;
}
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex);
}
}
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex);
}
}
m_PickingBuffer.Unbind();
GLERROR("PickingPass Error");
delete state;
}
@@ -8,6 +8,7 @@ PickingPassState::PickingPassState(GLuint frameBuffer)
GLERROR("---3");
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
Disable(GL_BLEND);
glm::vec4 clearColor = glm::vec4(0.f);
//ClearColor(clearColor);
+58 -4
View File
@@ -7,6 +7,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender
{
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned);
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
}
@@ -46,6 +47,13 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
continue;
}
EntityWrapper entity(m_World, modelComponent.EntityID);
// Don't render the local player
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
continue;
}
Model* model;
try {
model = ResourceManager::Load<::Model, true>(resource);
@@ -68,6 +76,14 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
}
}
bool RenderSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
{
if (e.PlayerID == -1) {
m_LocalPlayer = e.Player;
}
return true;
}
void RenderSystem::fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
{
auto pointLights = m_World->GetComponents("PointLight");
@@ -110,6 +126,42 @@ void RenderSystem::fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>&
}
}
void RenderSystem::fillText(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
{
auto texts = world->GetComponents("Text");
if (texts == nullptr) {
return;
}
for (auto& textComponent : *texts) {
bool visible = textComponent["Visible"];
if (!visible) {
continue;
}
std::string resource = textComponent["Resource"];
if (resource.empty()) {
continue;
}
Font* font;
try {
font = ResourceManager::Load<Font>(resource);
} catch (const std::exception&) {
try {
font = ResourceManager::Load<Font>("Fonts/DroidSans.ttf,16");
} catch (const std::exception&) {
continue;
}
}
glm::mat4 modelMatrix = Transform::ModelMatrix(textComponent.EntityID, world);
std::shared_ptr<TextJob> modelJob = std::shared_ptr<TextJob>(new TextJob(modelMatrix, font, textComponent));
jobs.push_back(modelJob);
}
}
bool RenderSystem::OnInputCommand(const Events::InputCommand& e)
{
return false;
@@ -119,11 +171,12 @@ void RenderSystem::Update(double dt)
{
m_EventBroker->Process<RenderSystem>();
if (m_CurrentCamera) {
ComponentWrapper cameraTransform = m_CurrentCamera["Transform"];
m_Camera->SetPosition(cameraTransform["Position"]);
m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"]));
// Update the current camera used for rendering
if (m_CurrentCamera.Valid()) {
m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera));
m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera));
}
//Only supports opaque geometry atm
RenderScene scene;
@@ -132,6 +185,7 @@ void RenderSystem::Update(double dt)
fillModels(scene.ForwardJobs);
fillPointLights(scene.PointLightJobs, m_World);
fillDirectionalLights(scene.DirectionalLightJobs, m_World);
fillText(scene.TextJobs, m_World);
m_RenderFrame->Add(scene);
}
+33 -29
View File
@@ -9,6 +9,9 @@ void Renderer::Initialize()
glfwSwapInterval(m_VSYNC);
InitializeShaders();
InitializeTextures();
m_TextPass = new TextPass();
m_TextPass->Initialize();
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
@@ -60,12 +63,6 @@ void Renderer::InitializeWindow()
void Renderer::InitializeShaders()
{
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#m_BasicForwardProgram");
m_DrawScreenQuadProgram = ResourceManager::Load<ShaderProgram>("#DrawScreenQuadProgram");
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
m_DrawScreenQuadProgram->Compile();
m_DrawScreenQuadProgram->Link();
}
void Renderer::InputUpdate(double dt)
@@ -77,15 +74,22 @@ void Renderer::Update(double dt)
{
m_EventBroker->Process<Renderer>();
InputUpdate(dt);
m_TextPass->Update();
m_ImGuiRenderPass->Update(dt);
}
void Renderer::Draw(RenderFrame& frame)
{
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f);
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking");
//clear buffer 0
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Clear other buffers
m_PickingPass->ClearPicking();
m_DrawFinalPass->ClearBuffer();
m_DrawBloomPass->ClearBuffer();
for (auto scene : frame.RenderScenes){
SortRenderJobsByDepth(*scene);
@@ -94,9 +98,27 @@ void Renderer::Draw(RenderFrame& frame)
m_LightCullingPass->FillLightList(*scene);
m_LightCullingPass->CullLights(*scene);
m_DrawFinalPass->Draw(*scene);
//m_DrawScenePass->Draw(rq);
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
m_TextPass->Draw(*scene, *m_DrawFinalPass->FinalPassFrameBuffer());
}
m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture());
if(m_DebugTextureToDraw == 0) {
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture());
}
if (m_DebugTextureToDraw == 1) {
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture());
}
if (m_DebugTextureToDraw == 2) {
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTexture());
}
if (m_DebugTextureToDraw == 3) {
m_DrawScreenQuadPass->Draw(m_DrawBloomPass->GaussianTexture());
}
if (m_DebugTextureToDraw == 4) {
m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture());
}
m_ImGuiRenderPass->Draw();
@@ -108,27 +130,6 @@ PickData Renderer::Pick(glm::vec2 screenCoord)
return m_PickingPass->Pick(screenCoord);
}
void Renderer::DrawScreenQuad(GLuint textureToDraw)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
m_DrawScreenQuadProgram->Bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureToDraw);
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
}
void Renderer::InitializeTextures()
{
m_ErrorTexture = ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
@@ -159,4 +160,7 @@ void Renderer::InitializeRenderPasses()
m_PickingPass = new PickingPass(this, m_EventBroker);
m_LightCullingPass = new LightCullingPass(this);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass);
m_DrawScreenQuadPass = new DrawScreenQuadPass(this);
m_DrawBloomPass = new DrawBloomPass(this);
m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this);
}
+113
View File
@@ -0,0 +1,113 @@
#include "Rendering/TextPass.h"
TextPass::TextPass()
{
}
void TextPass::Initialize()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
m_TextProgram = ResourceManager::Load<ShaderProgram>("#TextProgram");
m_TextProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Text.vert.glsl")));
m_TextProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Text.frag.glsl")));
m_TextProgram->Compile();
m_TextProgram->BindFragDataLocation(0, "sceneColor");
m_TextProgram->BindFragDataLocation(1, "bloomColor");
m_TextProgram->Link();
}
void TextPass::Update()
{
}
void TextPass::Draw(RenderScene& scene, FrameBuffer& frameBuffer)
{
GLERROR("Derp1");
TextPassState* state = new TextPassState(frameBuffer.GetHandle());
for (auto &job : scene.TextJobs) {
auto textJob = std::dynamic_pointer_cast<TextJob>(job);
if (textJob) {
renderText(textJob->Content, textJob->Resource, textJob->Alignment, textJob->Color, textJob->Matrix, scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix());
}
}
GLERROR("Derp2");
delete state;
}
void TextPass::renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix)
{
GLfloat penX = 0;
GLfloat penY = 0;
GLfloat scale = 1.0/font->FontSize;
GLfloat stringWidth = 0.f;
for (std::string::const_iterator c = text.begin(); c != text.end(); c++) {
Font::Character ch = font->m_Characters[*c];
stringWidth += (ch.Advance >> 6) * scale;
}
if(alignment == TextJob::AlignmentEnum::Center) {
penX = -stringWidth/2.f;
} else if (alignment == TextJob::AlignmentEnum::Right) {
penX = -stringWidth;
} else {
penX = 0;
}
m_TextProgram->Bind();
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(color));
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
for (std::string::const_iterator c = text.begin(); c != text.end(); c++) {
Font::Character ch = font->m_Characters[*c];
GLfloat xpos = penX + ch.Bearing.x * scale;
GLfloat ypos = penY - (ch.Size.y - ch.Bearing.y) * scale;
GLfloat w = ch.Size.x * scale;
GLfloat h = ch.Size.y * scale;
GLfloat vertices[6][4] = {
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos, ypos, 0.0, 1.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos + w, ypos + h, 1.0, 0.0 }
};
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
penX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
GLERROR("Text rendering Error");
}
+16
View File
@@ -0,0 +1,16 @@
#include "Rendering/TextPassState.h"
TextPassState::TextPassState(GLuint frameBuffer)
{
BindFramebuffer(frameBuffer);
glEnable(GL_BLEND);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
TextPassState::~TextPassState()
{
}
@@ -0,0 +1,2 @@
#include "Rendering/Util/CommonFunctions.h"
+1
View File
@@ -20,6 +20,7 @@ Game::Game(int argc, char* argv[])
ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
ResourceManager::RegisterType<EntityFile>("EntityFile");
ResourceManager::RegisterType<Font>("FontFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
ResourceManager::UseThreading = m_Config->Get<bool>("Multithreading.ResourceLoading", true);
+6
View File
@@ -66,6 +66,9 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
nextPossibleCapturePoint["Blue"] = -1;
for (size_t i = 0; i < m_NumberOfCapturePoints; i++)
{
if (!m_World->HasComponent(m_CapturePointNumberToEntityIDMap[i], "Team")) {
continue;
}
ComponentWrapper& capturePointOwnedBy = m_World->GetComponent(m_CapturePointNumberToEntityIDMap[i], "Team");
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) {
nextPossibleCapturePoint["Red"] = i + 1;
@@ -76,6 +79,9 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
}
for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--)
{
if (!m_World->HasComponent(m_CapturePointNumberToEntityIDMap[i], "Team")) {
continue;
}
ComponentWrapper& capturePointOwnedBy = m_World->GetComponent(m_CapturePointNumberToEntityIDMap[i], "Team");
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) {
nextPossibleCapturePoint["Red"] = i - 1;
+28 -34
View File
@@ -1,24 +1,14 @@
#include "Systems/InterpolationSystem.h"
//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt)
//{
// if (m_InterpolationPoints[transform.EntityID].size() > 0) {
// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front();
// sTransform.interpolationTime += dt;
// if (sTransform.interpolationTime > 0.05) {
// double time = std::fmod(sTransform.interpolationTime, 0.05f);
// m_InterpolationPoints[transform.EntityID].pop();
// if (m_InterpolationPoints[transform.EntityID].size() <= 0) {
// return;
// }
// sTransform = m_InterpolationPoints[transform.EntityID].front();
// sTransform.interpolationTime = time;
// }
// glm::vec3 nextPosition = sTransform.Position;
// glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime);
// }
//}
InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Transform")
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_SnapshotInterval = config->Get<float>("Networking.SnapshotInterval", 0.05);
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned);
}
void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt)
{
@@ -26,10 +16,10 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
m_NextTransform[transform.EntityID].interpolationTime += dt;
Transform sTransform = m_NextTransform[transform.EntityID];
double time = sTransform.interpolationTime;
if (time > SNAPSHOTINTERVAL) {
if (time > m_SnapshotInterval) {
if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) {
m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID];
m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL;
m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval;
sTransform = m_NextTransform[transform.EntityID];
m_LastReceivedTransform.erase(transform.EntityID);
} else {
@@ -37,14 +27,22 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
}
}
if (transform.Info.Name == "Transform") {
bool isLocalPlayer = entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer);
// Position
glm::vec3 nextPosition = sTransform.Position;
glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
// HACK: Hardcoded tolerance value for player position desync = 1
if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) {
return;
}
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
// Orientation
glm::quat nextOrientation = sTransform.Orientation;
glm::quat currentOrientation = glm::quat(static_cast<glm::vec3>(transform["Orientation"]));
(glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp<float>(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL));
// Don't force orientation for players
if (!isLocalPlayer) {
glm::quat nextOrientation = sTransform.Orientation;
glm::quat currentOrientation = glm::quat(static_cast<glm::vec3>(transform["Orientation"]));
(glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp<float>(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval));
}
// Scale
glm::vec3 nextScale = sTransform.Scale;
glm::vec3 currentScale = static_cast<glm::vec3>(transform["Scale"]);
@@ -53,6 +51,12 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
}
}
bool InterpolationSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
{
m_LocalPlayer = e.Player;
return true;
}
bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
{
Transform transform;
@@ -72,15 +76,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
} else { // Did not
m_NextTransform[e.Entity] = transform;
}
// Check if queue already exists
//if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue
// m_InterpolationPoints[e.Entity].push(transform);
//}
//else { // Did not exist, create queue
// std::queue<Transform> transformQueue;
// transformQueue.push(transform);
// m_InterpolationPoints[e.Entity] = transformQueue;
//}
return false;
}
+116 -2
View File
@@ -1,18 +1,132 @@
#include "Systems/PlayerMovementSystem.h"
PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Player")
{
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
}
PlayerMovementSystem::~PlayerMovementSystem()
{
for (auto& kv : m_PlayerInputControllers) {
delete kv.second;
}
}
void PlayerMovementSystem::Update(double dt)
{
for (auto& kv : m_PlayerInputControllers) {
EntityWrapper player = kv.first;
auto& controller = kv.second;
if (!player.Valid()) {
continue;
}
EntityWrapper cameraEntity = player.FirstChildByName("Camera");
if (cameraEntity.Valid()) {
glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"];
cameraOrientation.x += controller->Rotation().x;
// Limit camera pitch so we don't break our necks
cameraOrientation.x = glm::clamp(cameraOrientation.x, -glm::half_pi<float>(), glm::half_pi<float>());
}
ComponentWrapper& cTransform = player["Transform"];
glm::vec3& ori = cTransform["Orientation"];
ori.y += controller->Rotation().y;
if (player.HasComponent("Physics")) {
ComponentWrapper cPhysics = player["Physics"];
glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
float wishSpeed;
if (controller->Crouching()) {
wishSpeed = player["Player"]["CrouchSpeed"];
} else {
wishSpeed = player["Player"]["MovementSpeed"];
}
glm::vec3& velocity = cPhysics["Velocity"];
ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z);
glm::vec3 groundVelocity(0.f, 0.f, 0.f);
groundVelocity.x = glm::dot(velocity, glm::vec3(1.f, 0.f, 0.f));
groundVelocity.z = glm::dot(velocity, glm::vec3(0.f, 0.f, 1.f));
ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(wishDirection));
ImGui::Text("wishDirection: (%f, %f, %f) |%f|", wishDirection.x, wishDirection.y, wishDirection.z, glm::length(wishDirection));
float currentSpeedProj = glm::dot(groundVelocity, wishDirection);
float addSpeed = wishSpeed - currentSpeedProj;
ImGui::Text("currentSpeedProj: %f", currentSpeedProj);
ImGui::Text("wishSpeed: %f", wishSpeed);
ImGui::Text("addSpeed: %f", addSpeed);
if (addSpeed > 0) {
static float accel = 15.f;
ImGui::InputFloat("accel", &accel);
static float airAccel = 0.5f;
ImGui::InputFloat("airAccel", &airAccel);
float actualAccel = (velocity.y != 0) ? airAccel : accel;
static float surfaceFriction = 5.f;
ImGui::InputFloat("surfaceFriction", &surfaceFriction);
float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction;
accelerationSpeed = glm::min(accelerationSpeed, addSpeed);
velocity += accelerationSpeed * wishDirection;
ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity));
}
if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) {
velocity.y += 4.f;
}
//if (player.HasComponent("AABB")) {
// glm::vec3& size = player["AABB"]["Size"];
// if (controller->Crouching()) {
// size = glm::vec3(1.f, 1.f, 1.f);
// } else {
// size = glm::vec3(1.f, 1.6f, 1.f);
// }
//}
}
controller->Reset();
}
}
void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
{
ComponentWrapper& cTransform = entity["Transform"];
if (!entity.HasComponent("Physics")) {
return;
}
ComponentWrapper& cPhysics = entity["Physics"];
ComponentWrapper& cPhysics = entity["Physics"];
glm::vec3& velocity = cPhysics["Velocity"];
// Ground friction
float speed = glm::length(velocity);
static float groundFriction = 7.f;
ImGui::InputFloat("groundFriction", &groundFriction);
static float airFriction = 0.f;
ImGui::InputFloat("airFriction", &airFriction);
float friction = (velocity.y != 0) ? airFriction : groundFriction;
if (speed > 0) {
float drop = speed * friction * (float)dt;
float multiplier = glm::max(speed - drop, 0.f) / speed;
velocity.x *= multiplier;
velocity.z *= multiplier;
}
if (cPhysics["Gravity"]) {
velocity.y -= 9.82 * dt;
velocity.y -= 9.82f * (float)dt;
}
glm::vec3& position = cTransform["Position"];
position += velocity * (float)dt;
}
bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
{
// When a player spawns, create an input controller for them
m_PlayerInputControllers[e.Player] = new FirstPersonInputController<PlayerMovementSystem>(m_EventBroker, e.PlayerID);
return true;
}
+64 -4
View File
@@ -4,6 +4,8 @@ PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker)
: System(m_World, eventBroker)
{
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned);
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
}
void PlayerSpawnSystem::Update(double dt)
@@ -13,7 +15,7 @@ void PlayerSpawnSystem::Update(double dt)
return;
}
for (auto& team : m_SpawnRequests) {
for (auto& req : m_SpawnRequests) {
for (auto& cPlayerSpawn : *playerSpawns) {
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
if (!spawner.HasComponent("Spawner")) {
@@ -22,7 +24,7 @@ void PlayerSpawnSystem::Update(double dt)
// If the spawner has a team affiliation, check it
if (spawner.HasComponent("Team")) {
if ((int)spawner["Team"]["Team"] != team) {
if ((int)spawner["Team"]["Team"] != req.Team) {
continue;
}
}
@@ -30,7 +32,15 @@ void PlayerSpawnSystem::Update(double dt)
// Spawn the player!
EntityWrapper player = SpawnerSystem::Spawn(spawner);
// Set the player team affiliation
player["Team"]["Team"] = team;
player["Team"]["Team"] = req.Team;
// Publish a PlayerSpawned event
Events::PlayerSpawned e;
e.PlayerID = req.PlayerID;
e.Player = player;
e.Spawner = spawner;
m_EventBroker->Publish(e);
}
}
m_SpawnRequests.clear();
@@ -42,10 +52,60 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
return false;
}
// Team picks should be processed ONLY server-side!
// Don't make a spawn request if PlayerID is -1, i.e. we're the client.
if (e.PlayerID == -1 && m_NetworkEnabled) {
return false;
}
if (e.Value != 0) {
m_SpawnRequests.push_back((int)e.Value);
SpawnRequest req;
req.PlayerID = e.PlayerID;
req.Team = (ComponentInfo::EnumType)e.Value;
m_SpawnRequests.push_back(req);
}
return true;
}
bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
{
// When a player is actually spawned (since the actual spawning is handled on the server)
// Check if a player already exists
if (m_PlayerEntities.count(e.PlayerID) != 0) {
// TODO: Disallow infinite respawning here
m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID);
}
// Store the player for future reference
m_PlayerEntities[e.PlayerID] = e.Player;
// Set the camera to the correct entity
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
if (cameraEntity.Valid()) {
Events::SetCamera e;
e.CameraEntity = cameraEntity;
m_EventBroker->Publish(e);
}
// HACK: Set the player model color to team color
EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel");
if (playerModel.Valid() && e.Player.HasComponent("Team")) {
ComponentWrapper cTeam = e.Player["Team"];
ComponentWrapper cModel = playerModel["Model"];
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) {
cModel["Color"] = glm::vec3(1.f, 0.f, 0.f);
} else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) {
cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f);
}
}
// TODO: Set the player name to whatever
//EntityWrapper playerName = e.Player.FirstChildByName("PlayerName");
//if (playerName.Valid()) {
// playerName["Text"]["Content"] = ???;
//}
return true;
}