Compare commits

..

76 Commits

Author SHA1 Message Date
Jace 73064c7257 Broken undo 2016-02-26 13:12:49 +01:00
Jace fa78991795 World::MemoryUsage returns approximate value of component pool memory usage 2016-02-26 12:53:33 +01:00
Jace 0c60b637c3 Who's merging without compiling? 2016-02-26 12:52:10 +01:00
William Moberg d411de894f Merge pull request #140 from teamfisk/FixNetworkBugs
Death explosion should always get triggered now.
2016-02-26 12:01:19 +01:00
Jocke 18450ff4f3 Death explosion should always get triggered now. (I hope) 2016-02-26 11:08:05 +01:00
William Moberg 22b473a0b6 Merge pull request #139 from teamfisk/EditorCopyPaste
Editor copy paste
2016-02-26 11:01:18 +01:00
Jace f161fce719 Merge pull request #138 from teamfisk/PlayerAtOriginFix
Teleporting to origin on spawn fixed.
2016-02-25 17:55:03 +01:00
Jace 0343683678 Fixed cubemaps being generated over and over again each frame. 2016-02-25 17:51:40 +01:00
Jace 9e6c67596d Basic editor copy and paste. Doesn't actually copy the entity until you paste it. 2016-02-25 17:51:28 +01:00
William Moberg 89d0d5753f Fix for player teleporting to (0,0,0). Saves player previous position in CollisionSystem instead of Physics component so it won't be saved when editing Players. 2016-02-25 16:16:24 +01:00
Adam Byléhn 748a178801 Merge pull request #136 from teamfisk/FixNetworkBugs
Fix network bugs
2016-02-25 16:09:08 +01:00
Jocke eac9a9daf6 Pull request #136 Merge remote-tracking branch 'origin/master' into FixNetworkBugs
# Conflicts:
#	src/Engine/Network/Client.cpp
2016-02-25 16:07:06 +01:00
Jocke 059fe5c6c0 Fixed typo m_EPDoubleJump to m_EDoubleJump. 2016-02-25 16:04:27 +01:00
Joachim Pettersson fb465ede81 Merge pull request #134 from teamfisk/HUDDesync
Good job! 👍
2016-02-25 15:53:07 +01:00
Jocke f66fa7a183 Merge remote-tracking branch 'origin/master' into FixNetworkBugs
# Conflicts:
#	include/Engine/Network/Client.h
#	include/Engine/Network/MessageType.h
#	include/Engine/Network/Server.h
#	include/Engine/Network/TCPServer.h
#	src/Engine/Network/Client.cpp
#	src/Engine/Network/TCPServer.cpp
2016-02-25 15:13:11 +01:00
Jocke 508d8a6f00 Fixed memory leak in TCPServer::AcceptNewConnections caused by acceptor->async_accept().
Fixed some formating and comments.
2016-02-25 14:24:38 +01:00
stiffly 8ce6308649 In snapshot: now sends player information and also CP information. Now it is no longer true that they will arrive in pre order. Appropriate actions were therefor implemented. 2016-02-25 11:56:40 +01:00
stiffly f10958c268 Capturepoint logic is now purely done on the serverside. 2016-02-25 11:50:29 +01:00
William Moberg da1c7b3093 Merge pull request #133 from teamfisk/AndersTest
Ammo,HealthPickup now takes in account for possible parenting/childin…
2016-02-25 09:58:14 +01:00
verysecrethero ef87102d1f Ammo,HealthPickup now takes in account for possible parenting/childing of the pickup. Also saved the xml files with the new scaling 2016-02-24 17:53:37 +01:00
Jace 9a41bda4cf Merge pull request #132 from teamfisk/CubeMap
Cube map
2016-02-24 16:03:49 +01:00
Tleety fc18932068 Merge remote-tracking branch 'origin/master' into CubeMap
# Conflicts:
#	src/Engine/Rendering/Renderer.cpp
2016-02-24 15:45:30 +01:00
Tobias Dahl b874ea8641 Merge pull request #131 from teamfisk/ResizeWindowFixFromSSAOMerge
Have fix the resizing errors
2016-02-24 15:22:12 +01:00
Tobias Dahl 2609a0253d Merge pull request #129 from teamfisk/HUDDesync
Networking improvements
2016-02-24 15:22:01 +01:00
William Moberg de309d3b9d Merge pull request #130 from teamfisk/AndersTest
CapturePointSystem fix, DamageIndicatorSystem fix
2016-02-24 15:17:36 +01:00
Tobias Dahl f7ef6707a7 Merge pull request #116 from teamfisk/SeeTeamMates
See team mates
2016-02-24 15:05:19 +01:00
Tleety feeff5b164 Debug tool for different CubeMap
changed cubemap influence.
2016-02-24 14:47:47 +01:00
stiffly 7394436e7a Removed unnecessary comment. 2016-02-24 14:23:54 +01:00
Tleety f41e0b29be assets 2016-02-24 14:21:48 +01:00
Tleety 607e83134d Cubemaps working 2016-02-24 14:16:49 +01:00
verysecrethero 5af4f9d8e7 Removed a comment originating from HUDDesynch branch 2016-02-24 14:06:41 +01:00
verysecrethero af68236e71 now using a define INDICATOR_TEST to activate the DamageIndicatorSystem test. 2016-02-24 13:58:05 +01:00
Tleety 6f9ce8a0c1 WIP 2016-02-24 13:57:54 +01:00
Teejoon 6465fe6ed6 Have fix the resizing errors 2016-02-24 13:22:41 +01:00
Jocke fa13c1d065 Double jump is now working. 2016-02-23 18:24:46 +01:00
verysecrethero e2831c5593 CapturePointSystem fix, DamageIndicatorSystem fix 2016-02-23 17:29:33 +01:00
Tleety 8d23c531af Cubemaps kinda functioning, still somthing wierd with the vectors. 2016-02-23 17:17:50 +01:00
Tleety 91b0ac5fbd Some groundwork for cubemaps. 2016-02-23 16:00:43 +01:00
stiffly d77119bb2d Fixed print for serverlist. 2016-02-23 11:47:44 +01:00
stiffly 27669b7383 Merge remote-tracking branch 'origin/master' into HUDDesync 2016-02-23 11:09:44 +01:00
stiffly fc7d62a5ad Various clean ups. 2016-02-23 11:07:56 +01:00
stiffly c42e1e0967 SoundSystem Fix. Now subscribes to an event that was thought to be listened to. 2016-02-23 11:07:41 +01:00
stiffly fe9dbf0b0f Serverlist fix. 2016-02-23 10:33:20 +01:00
Tleety 4ffb03fdd5 Merge remote-tracking branch 'origin/master' into SmallFixes-Tobias
# Conflicts:
#	src/Engine/Rendering/DrawFinalPass.cpp
2016-02-23 10:02:53 +01:00
Teejoon fe3e0bac5b Changed SpritIndicator values on player 2016-02-22 18:45:02 +01:00
Teejoon fa4f007604 Changed name from Indicator to SpriteIndicator. Can now be an indicator for a single team or every one 2016-02-22 18:35:00 +01:00
stiffly e5ff88d3c9 SoundSystem bug fix 2016-02-22 17:41:14 +01:00
stiffly 845a30ed0f Merge remote-tracking branch 'origin/DynamicPacketBuffer' into HUDDesync
# Conflicts:
#	include/Engine/Network/TCPServer.h
#	src/Engine/Network/TCPServer.cpp
2016-02-22 17:39:48 +01:00
stiffly 833006744a WIP 2016-02-22 17:00:25 +01:00
Teejoon 6fab971734 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into SeeTeamMates
Conflicts:
	include/Engine/Rendering/SpriteJob.h
	resources/Schema/Components.xsd
	resources/Schema/Entities/Player.xml
	resources/Schema/Entities/PlayerRed.xml
2016-02-22 16:43:18 +01:00
Viktor Ljung 2c18068059 Merge pull request #126 from teamfisk/SSAO
SSAO
2016-02-22 16:40:11 +01:00
Teejoon 09aec08d0e Pull request fixes 2016-02-22 16:38:20 +01:00
Teejoon 4cf8c3d8d7 Fixed PerformanceTimer start and stop in Renderer.cpp since I have changed a little code there 2016-02-22 15:02:20 +01:00
Teejoon 37414ce124 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into SSAO
Conflicts:
	include/Engine/Rendering/Renderer.h
	src/Engine/Rendering/Renderer.cpp
2016-02-22 14:51:42 +01:00
Teejoon adceccf402 SSAO now working. Changed in DrawFinalePass so that th AOTexture is on texture position 0 and only get binded once.
Changed so that the picking pass get drawn once in the beginning so that the AO shatde could calculate AO from the depthbuffer generated during pthe pickingpass.

In the ImGUI debugg window there is now sliders to change the behavior of the AO shader. Only the minimum ambient lightning is HardCoded in to the frowardPlus fragmentshaders with a define in the begining.
2016-02-22 14:48:20 +01:00
stiffly 4c1a284636 Server now does Capture point logic too. 2016-02-22 11:30:31 +01:00
stiffly 23dc8e07b2 Will this do the trick? Now tells the server to send HUD entities too. 2016-02-22 10:41:37 +01:00
stiffly c7d31cac2d Merge remote-tracking branch 'origin/master' into FriendlyHost/Join
# Conflicts:
#	src/Engine/Network/Client.cpp
2016-02-22 10:19:48 +01:00
stiffly a1e932d261 Merge remote-tracking branch 'origin/master' into FriendlyHost/Join 2016-02-22 10:06:51 +01:00
stiffly 070f1bd394 Merge remote-tracking branch 'origin/FriendlyHost/Join' into FriendlyHost/Join
# Conflicts:
#	src/Engine/Network/Client.cpp
2016-02-22 10:06:25 +01:00
stiffly 993d804cef Added an event to search for servers.
Client now broadcasts a serverlistrequest.
An active server will then answer the request and send info about the server.
The client saves this data to a list and presents it to the user.
2016-02-22 10:05:47 +01:00
Teejoon 201480b17f SSAO is working, but is kinda crappy. You can change shade variables in the debug window. 2016-02-19 16:50:04 +01:00
stiffly 2f259c3773 Added an event to search for servers.
Client now broadcasts a serverlistrequest.
An active server will then answer the request and send info about the server.
The client saves this data to a list and presents it to the user.
2016-02-19 15:38:09 +01:00
Tleety 97fcdb342d Bloom should now show behind transparent objects. 2016-02-19 14:23:40 +01:00
Tleety 949ee76f55 Fallow and name fix 2016-02-19 13:52:16 +01:00
Teejoon c4d3c515e4 Marge with Master 2016-02-17 18:04:49 +01:00
Teejoon 7cc58dc94c Merge branch 'master' of https://github.com/teamfisk/TacticalZ into SeeTeamMates 2016-02-17 18:00:30 +01:00
Teejoon 5e3af7ac5d Player Indicator now working OK. Scaling depending on how far away you are makes the Indicator to hide players head behind it. Shields are making indicators to disappear. 2016-02-17 17:58:01 +01:00
stiffly 46987beefb Updated the serverlist, now prints adress and port of the server. 2016-02-17 17:05:10 +01:00
Teejoon 4fd0108443 Working billbording 2016-02-17 16:50:24 +01:00
stiffly 950ecba1c0 Merge remote-tracking branch 'origin/master' into FriendlyHost/Join 2016-02-17 15:52:58 +01:00
stiffly fdc8f753cb Implemented primitive server "heartbeat" logic, which sends server info from server to client without being connected. 2016-02-17 15:51:26 +01:00
Jocke 4432891437 Fixed crash in Client::parsePlayerDamage. 2016-02-17 10:21:50 +01:00
Jocke a006db9e63 WIP Fix dsync 2016-02-16 16:06:17 +01:00
Teejoon 17da9a8036 WIP 2016-02-16 15:56:58 +01:00
Jocke 717af2c4a4 Fixed bug in Client::parsePlayerDamage() 2016-02-16 10:22:15 +00:00
82 changed files with 1676 additions and 489 deletions
+1 -1
Submodule assets updated: 1e7adc749e...10a611659d
@@ -24,6 +24,7 @@ public:
private:
Octree<EntityAABB>* m_Octree;
std::vector<EntityAABB> m_OctreeResult;
std::unordered_map<EntityWrapper, glm::vec3> m_PrevPositions;
};
#endif
+2
View File
@@ -65,6 +65,8 @@ public:
iterator end() const;
size_t size() const;
std::size_t MemoryUsage() const;
//Dumps information about what the pool memory looks like right now
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
//Interpret the data in the memory as InterpretType.
+3
View File
@@ -27,8 +27,10 @@ struct EntityWrapper
bool HasComponent(const std::string& componentType);
void AttachComponent(const char* componentName);
EntityWrapper Parent();
EntityWrapper BaseParent();
EntityWrapper FirstChildByName(const std::string& name);
EntityWrapper FirstParentWithComponent(const std::string& componentType);
EntityWrapper Clone(EntityWrapper parent = EntityWrapper::Invalid);
bool IsChildOf(EntityWrapper potentialParent);
bool Valid() const;
@@ -39,6 +41,7 @@ struct EntityWrapper
private:
EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent);
EntityWrapper cloneRecursive(EntityWrapper entity, EntityWrapper parent);
};
namespace std
+5
View File
@@ -194,6 +194,11 @@ public:
return m_ExtraMemory.size();
}
std::size_t MemoryUsage() const
{
return size() * m_Stride;
}
//Dumps information about what the pool memory looks like right now
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
//Interpret the data in the memory as InterpretType.
+5 -2
View File
@@ -18,7 +18,7 @@ public:
World(const World& other);
// Create empty entity
EntityID CreateEntity(EntityID parent = 0);
EntityID CreateEntity(EntityID parent = EntityID_Invalid);
// Delete entity and all components within
void DeleteEntity(EntityID entity);
// Check if an entity exists
@@ -40,7 +40,7 @@ public:
// Change the parent of an entity
void SetParent(EntityID entity, EntityID parent);
// Get children of an entity
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetChildren(EntityID entity);
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetDirectChildren(EntityID entity);
// Get all component pools
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map
@@ -50,6 +50,9 @@ public:
// Get the textual name of an entity
std::string GetName(EntityID entity) const;
// Get an approximate number for component pool memory usage
std::size_t MemoryUsage() const;
private:
EventBroker* m_EventBroker = nullptr;
EntityID m_CurrentEntityID = 0;
+17 -1
View File
@@ -73,6 +73,12 @@ public:
// Called when the user means to rename an entity.
typedef std::function<void(EntityWrapper, const std::string&)> OnEntityChangeName_t;
void SetEntityChangeNameCallback(OnEntityChangeName_t f) { m_OnEntityChangeName = f; }
// Called when the user pastes an entity previously "copied"
// @param EntityWrapper The entity to copy
// @param EntityWrapper The entity to parent the new copy to
// @return The new copy of the entity
typedef std::function<EntityWrapper(EntityWrapper, EntityWrapper)> OnEntityPaste_t;
void SetEntityPasteCallback(OnEntityPaste_t f) { m_OnEntityPaste = f; }
// Called when the user means to attach a new component to an entity.
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentAttach_t;
void SetComponentAttachCallback(OnComponentAttach_t f) { m_OnComponentAttach = f; }
@@ -85,7 +91,13 @@ public:
// Called when the user selects a widget space.
typedef std::function<void(WidgetSpace)> OnWidgetSpace_t;
void SetWidgetSpaceCallback(OnWidgetSpace_t f) { m_OnWidgetSpace = f; }
// Called when anything is modified making the world dirty
// @param EntityWrapper The entity that was changed and marked as dirty
typedef std::function<void(EntityWrapper)> OnDirty_t;
void SetDirtyCallback(OnDirty_t f) { m_OnDirty = f; }
// Called when the user wishes to undo
typedef std::function<void()> OnUndo_t;
void SetUndoCallback(OnUndo_t f) { m_OnUndo = f; }
private:
World* m_World;
EventBroker* m_EventBroker;
@@ -111,6 +123,7 @@ private:
std::string m_DroppedFile = "";
bool m_Paused = false;
bool m_MouseLocked = false;
EntityWrapper m_CopyTarget = EntityWrapper::Invalid;
// Callbacks
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
@@ -124,6 +137,9 @@ private:
OnComponentDelete_t m_OnComponentDelete = nullptr;
OnWidgetMode_t m_OnWidgetMode = nullptr;
OnWidgetSpace_t m_OnWidgetSpace = nullptr;
OnEntityPaste_t m_OnEntityPaste = nullptr;
OnDirty_t m_OnDirty = nullptr;
OnUndo_t m_OnUndo = nullptr;
// Events
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
+5
View File
@@ -36,6 +36,7 @@ private:
EditorCameraInputController<EditorSystem>* m_EditorCameraInputController;
EditorGUI* m_EditorGUI;
EditorStats* m_EditorStats;
std::vector<World> m_UndoLevels;
// State
double m_LastTime = 0.f;
@@ -44,6 +45,7 @@ private:
EditorGUI::WidgetSpace m_WidgetSpace = EditorGUI::WidgetSpace::Global;
EntityWrapper m_Widget = EntityWrapper::Invalid;
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
bool m_SaveUndoLevel = false; // Only save undo state once per update
// Utility functions
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
@@ -56,9 +58,12 @@ private:
void OnEntityDelete(EntityWrapper entity);
void OnEntityChangeParent(EntityWrapper entity, EntityWrapper parent);
void OnEntityChangeName(EntityWrapper entity, const std::string& name);
EntityWrapper OnEntityPaste(EntityWrapper entityToCopy, EntityWrapper parent);
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace);
void OnDirty(EntityWrapper entity);
void OnUndo();
// Events
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
+31 -5
View File
@@ -19,11 +19,26 @@
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Core/ConfigFile.h"
#include "Core/EPlayerDeath.h"
#include "Input/EInputCommand.h"
#include "Core/EPlayerDamage.h"
#include "../Game/Events/EDoubleJump.h"
#include "Network/EInterpolate.h"
#include "Network/SnapshotFilter.h"
#include "Core/EPlayerSpawned.h"
#include "Network/ESearchForServers.h"
struct ServerInfo
{
ServerInfo(std::string a, int b, std::string c, int d)
{
Address = a; Port = b; Name = c; PlayersConnected = d;
}
std::string Address = "";
int Port = 0;
std::string Name = "";
int PlayersConnected = 0;
};
class Client : public Network
{
@@ -34,7 +49,9 @@ public:
void Connect(std::string address, int port);
void Update() override;
private:
UDPClient m_Unreliable;
TCPClient m_Reliable;
std::vector<Events::PlayerSpawned> m_PlayerSpawnEvents;
void parseSpawnEvents();
// Save for children
@@ -82,10 +99,13 @@ public:
void parseTCPConnect(Packet& packet);
void parsePlayerConnected(Packet& packet);
void parsePing();
void parseServerlist(Packet& packet);
void parseKick();
void parsePlayersSpawned(Packet& packet);
void parseEntityDeletion(Packet& packet);
void parsePlayerDamage(Packet& packet);
void parseComponentDeletion(Packet& packet);
void parseDoubleJump(Packet& packet);
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
void parseSnapshot(Packet& packet);
void identifyPacketLoss();
@@ -94,6 +114,7 @@ public:
void sendInputCommands();
void sendLocalPlayerTransform();
void becomePlayer();
void displayServerlist();
// Mapping Logic
// Returns if local EntityID exist in map
bool clientServerMapsHasEntity(EntityID clientEntityID);
@@ -109,10 +130,15 @@ public:
bool OnPlayerDamage(const Events::PlayerDamage& e);
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
void parsePlayerDamage(Packet& packet);
private:
UDPClient m_Unreliable;
TCPClient m_Reliable;
EventRelay< Client, Events::SearchForServers> m_ESearchForServers;
EventRelay<Client, Events::DoubleJump> m_EDoubleJump;
bool OnDoubleJump(Events::DoubleJump & e);
bool OnSearchForServers(const Events::SearchForServers& e);
UDPClient m_ServerlistRequest;
std::vector<ServerInfo> m_Serverlist;
bool m_SearchingForServers = false;
std::clock_t m_StartSearchTime;
double m_SearchingTime = 2000; // Config I guess
};
#endif
@@ -0,0 +1,12 @@
#ifndef Events_SearchForServers_h__
#define Events_SearchForServers_h__
#include "Core/Event.h"
namespace Events
{
struct SearchForServers : public Event { };
}
#endif
-13
View File
@@ -1,13 +0,0 @@
#ifndef HybridClient_h__
#define HybridClient_h__
class HybridClient
{
public:
HybridClient();
~HybridClient();
private:
};
#endif
-12
View File
@@ -1,12 +0,0 @@
#ifndef HybridServer_h__
#define HybridServer_h__
class HybridServer
{
public:
HybridServer();
~HybridServer();
private:
};
#endif
+2
View File
@@ -19,6 +19,8 @@ enum class MessageType
EntityDeleted,
ComponentDeleted,
PlayerTransform,
OnDoubleJump,
ServerlistRequest,
Invalid
};
+6 -2
View File
@@ -17,6 +17,7 @@
#include "Core/EPlayerDamage.h"
#include "Network/EPlayerDisconnected.h"
#include "Core/EPlayerSpawned.h"
#include "../Game/Events/EDoubleJump.h"
#include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h"
@@ -32,6 +33,7 @@ private:
// Network channels
TCPServer m_Reliable;
UDPServer m_Unreliable;
UDPServer m_ServerlistRequest;
// dont forget to set these in the childrens receive logic
boost::asio::ip::address m_Address;
int m_Port = 27666;
@@ -79,9 +81,11 @@ private:
void parseOnInputCommand(Packet& packet);
void parseClientPing();
void parsePing();
void parseUDPConnect(Packet & packet);
void parseTCPConnect(Packet & packet);
bool parseDoubleJump(Packet& packet);
void parseUDPConnect(Packet& packet);
void parseTCPConnect(Packet& packet);
void parseDisconnect();
void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint);
bool shouldSendToClient(EntityWrapper childEntity);
// Debug event
+9 -3
View File
@@ -16,16 +16,22 @@ public:
void Send(Packet & packet, PlayerDefinition & playerDefinition);
void Send(Packet & packet);
void Disconnect();
int Port() { return m_Port; }
std::string Address() { return m_Address; }
private:
// TCP logic
boost::asio::io_service m_IOService;
std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;
boost::shared_ptr<boost::asio::ip::tcp::socket> lastReceivedSocket;
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket,
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
const boost::system::error_code& error);
int readBuffer(PlayerDefinition& playerDefinition);
PlayerID getPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
boost::asio::ip::address address, unsigned short port);
int GetPort();
std::string GetAddress();
int m_Port = 0;
std::string m_Address = "";
};
#endif
+1
View File
@@ -14,6 +14,7 @@ public:
void Disconnect();
void Receive(Packet& packet);
void Send(Packet & packet);
void Broadcast(Packet& packet, int port);
bool IsSocketAvailable();
private:
// Assio UDP logic
+4 -1
View File
@@ -8,11 +8,14 @@ class UDPServer : public NetworkServer
{
public:
UDPServer();
UDPServer(int port);
~UDPServer();
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
void Send(Packet & packet, PlayerDefinition & playerDefinition);
void Send(Packet & packet);
void Send(Packet & packet);
void Send(Packet & packet, boost::asio::ip::udp::endpoint endpoint);
void Broadcast(Packet & packet, int port);
bool IsSocketAvailable();
private:
// UDP logic
+27
View File
@@ -0,0 +1,27 @@
#ifndef CubeMapPass_h__
#define CubeMapPass_h__
#include "IRenderer.h"
#include "ShaderProgram.h"
class CubeMapPass
{
public:
CubeMapPass(IRenderer* renderer);
~CubeMapPass() { }
void LoadTextures(std::string input);
void FillCubeMap(glm::vec3 originPosition);
void GenerateCubeMapTexture();
//GLuint CubeMapTexture() const { return m_CubeMapTexture; }
GLuint m_CubeMapTexture = -1;
private:
IRenderer* m_Renderer;
std::string m_PreviusCubeMapTexture;
std::vector<Texture*> m_CubeMapTextures;
};
#endif
+6 -3
View File
@@ -4,6 +4,7 @@
#include "IRenderer.h"
#include "DrawFinalPassState.h"
#include "LightCullingPass.h"
#include "CubeMapPass.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
@@ -13,12 +14,12 @@
class DrawFinalPass
{
public:
DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass);
DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass);
~DrawFinalPass() { }
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
void Draw(RenderScene& scene, GLuint SSAOTexture);
void ClearBuffer();
void OnWindowResize();
@@ -37,7 +38,7 @@ private:
void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const;
void DrawSprites(std::list<std::shared_ptr<RenderJob>>&jobs, RenderScene& scene);
void DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene);
void DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene, GLuint SSAOTexture);
void DrawShieldToStencilBuffer(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene);
void DrawShieldedModelRenderQueue(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene);
void DrawToDepthBuffer(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene);
@@ -62,12 +63,14 @@ private:
GLuint m_SceneTextureLowRes;
GLuint m_DepthBuffer;
GLuint m_DepthBufferLowRes;
GLuint m_CubeMapTexture;
//maqke this component based i guess?
GLuint m_ShieldPixelRate = 16;
const IRenderer* m_Renderer;
const LightCullingPass* m_LightCullingPass;
const CubeMapPass* m_CubeMapPass;
ShaderProgram* m_ForwardPlusProgram;
ShaderProgram* m_ExplosionEffectProgram;
+1 -1
View File
@@ -184,7 +184,7 @@ struct ModelJob : RenderJob
void CalculateHash() override
{
Hash = TextureID + ModelID << 10 + ShaderID << 20;
Hash = ShaderID << 20 + ModelID << 10 + TextureID;
}
};
+11
View File
@@ -16,6 +16,8 @@
#include "DrawScreenQuadPass.h"
#include "DrawBloomPass.h"
#include "DrawColorCorrectionPass.h"
#include "SSAOPass.h"
#include "CubeMapPass.h"
#include "../Core/EventBroker.h"
#include "ImGuiRenderPass.h"
#include "Camera.h"
@@ -57,7 +59,14 @@ private:
Model* m_UnitSphere;
int m_DebugTextureToDraw = 0;
int m_CubeMapTexture = 0;
bool m_ResizeWindow = false;
float m_SSAO_Radius = 1.0f;
float m_SSAO_Bias = 0.05f;
float m_SSAO_Contrast = 1.5f;
float m_SSAO_IntensityScale = 1.0f;
int m_SSAO_NumOfSamples = 24;
int m_SSAO_NumOfTurns = 7;
PickingPass* m_PickingPass;
LightCullingPass* m_LightCullingPass;
@@ -66,6 +75,8 @@ private:
DrawScreenQuadPass* m_DrawScreenQuadPass;
DrawBloomPass* m_DrawBloomPass;
DrawColorCorrectionPass* m_DrawColorCorrectionPass;
SSAOPass* m_SSAOPass;
CubeMapPass* m_CubeMapPass;
//----------------------Functions----------------------//
void InitializeWindow();
+63
View File
@@ -0,0 +1,63 @@
#ifndef SSAOPass_h__
#define SSAOPass_h__
#include "IRenderer.h"
#include "SSAOPassState.h"
//#include "LightCullingPass.h" Finalpass om den skall skickas in
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "DrawBloomPass.h"
//#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class SSAOPass
{
public:
SSAOPass(IRenderer* rendere);
~SSAOPass() {
delete m_DrawBloomPass;
};
void Draw(GLuint depthBuffer, Camera* camera);
void Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns);
void ClearBuffer();
void OnWindowResize();
//Return the SSAO of the texture sent to Draw
GLuint SSAOTexture() const { return m_DrawBloomPass->GaussianTexture(); }
private:
void InitializeTexture();
void InitializeFrameBuffer();
void InitializeShaderProgram();
void InitializeBuffer();
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
//void blurHorizontal(GLuint depthBuffer);
//void blurVertical(GLuint depthBuffer);
Model* m_ScreenQuad;
const IRenderer* m_Renderer;
float m_Radius;
float m_Bias;
float m_Contrast;
float m_IntensityScale;
int m_NumOfSamples;
int m_NumOfTurns;
GLuint m_SSAOTexture;
FrameBuffer m_SSAOFramBuffer;
GLuint m_SSAOViewSpaceZTexture;
FrameBuffer m_SSAOViewSpaceZFramBuffer;
ShaderProgram* m_SSAOProgram;
ShaderProgram* m_SSAOViewSpaceZProgram;
DrawBloomPass* m_DrawBloomPass;
};
#endif
+15
View File
@@ -0,0 +1,15 @@
#ifndef SSAOPassState_h__
#define SSAOPassState_h__
#include "Rendering/RenderState.h"
class SSAOPassState : public RenderState
{
public:
SSAOPassState();
~SSAOPassState();
private:
};
#endif
+6 -3
View File
@@ -17,7 +17,7 @@
struct SpriteJob : RenderJob
{
SpriteJob(ComponentWrapper cSprite, Camera* camera, glm::mat4 matrix, World* world, glm::vec4 fillColor, float fillPercentage, bool depthSorted)
SpriteJob(ComponentWrapper cSprite, Camera* camera, glm::mat4 matrix, World* world, glm::vec4 fillColor, float fillPercentage, bool depthSorted, bool isIndicator)
: RenderJob()
{
Model = ResourceManager::Load<::Model>("Models/Core/UnitQuad.mesh");
@@ -30,7 +30,7 @@ struct SpriteJob : RenderJob
StartIndex = matProp.material->StartIndex;
EndIndex = matProp.material->EndIndex;
Matrix = matrix;
Matrix = matrix;
Color = cSprite["Color"];
Entity = cSprite.EntityID;
Position = Transform::AbsolutePosition(world, cSprite.EntityID);
@@ -41,7 +41,8 @@ struct SpriteJob : RenderJob
}
World = world;
Pickable = world->HasComponent(cSprite.EntityID, "Button");
IsIndicator = isIndicator;
FillColor = fillColor;
FillPercentage = fillPercentage;
};
@@ -61,7 +62,9 @@ struct SpriteJob : RenderJob
unsigned int StartIndex = 0;
unsigned int EndIndex = 0;
World* World;
bool Pickable;
bool IsIndicator = false;
glm::vec4 FillColor = glm::vec4(0);
float FillPercentage = 0.0;
+1
View File
@@ -18,6 +18,7 @@ public:
void Bind(GLenum textureUnit = GL_TEXTURE0);
GLuint m_Texture = 0;
unsigned char* Data = nullptr;
};
+1 -1
View File
@@ -8,7 +8,7 @@ namespace Events
struct DoubleJump : public Event
{
EntityID entityID;
};
}
+1
View File
@@ -26,6 +26,7 @@ private:
double AmmoGain;
double RespawnTimer;
double DecreaseThisRespawnTimer;
EntityID parentID;
};
std::vector<NewAmmoPickup> m_ETriggerTouchVector;
};
+17 -1
View File
@@ -14,11 +14,13 @@
#include <glm/gtx/vector_angle.hpp>
#include "Rendering/Util/CommonFunctions.h"
//#define INDICATOR_TEST
class DamageIndicatorSystem : public System
class DamageIndicatorSystem : public ImpureSystem
{
public:
DamageIndicatorSystem(SystemParams params);
virtual void Update(double dt) override;
private:
EventRelay<DamageIndicatorSystem, Events::PlayerDamage> m_EPlayerDamage;
@@ -28,6 +30,20 @@ private:
bool OnSetCamera(const Events::SetCamera& e);
EntityID m_CurrentCamera = -1;
struct DamageIndicatorStruct {
EntityWrapper spriteEntity;
glm::vec3 enemyPosition;
DamageIndicatorStruct(EntityWrapper sprite, glm::vec3 pos)
: spriteEntity(sprite)
, enemyPosition(pos) {}
};
std::vector<DamageIndicatorStruct> updateDamageIndicatorVector;
float CalculateAngle(EntityWrapper player, glm::vec3 enemyPos);
//for tests
#ifdef INDICATOR_TEST
glm::vec3 DamageIndicatorTest(EntityWrapper player);
int m_TestVar = 0;
#endif
};
#endif
+1
View File
@@ -27,6 +27,7 @@ private:
double HealthGain;
double RespawnTimer;
double DecreaseThisRespawnTimer;
EntityID parentID;
};
std::vector<NewHealthPickup> m_ETriggerTouchVector;
};
+5 -1
View File
@@ -34,10 +34,14 @@ private:
glm::vec3 m_LastPosition = glm::vec3();
// The logic for making the sound play when player is moving
void playerStep(double dt);
// Spawn a hexagon at origin of an Entity
void spawnHexagon(EntityWrapper target);
EventRelay<PlayerMovementSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
EventRelay<PlayerMovementSystem, Events::DoubleJump> m_EDoubleJump;
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e);
void updateMovementControllers(double dt);
void updateVelocity(double dt);
void updateVelocity(EntityWrapper player, double dt);
};
+1
View File
@@ -44,5 +44,6 @@
<xs:include schemaLocation="Components/Menu.xsd"/>
<xs:include schemaLocation="Components/KillFeed.xsd"/>
<xs:include schemaLocation="Components/Page.xsd"/>
<xs:include schemaLocation="Components/SpriteIndicator.xsd"/>
<xs:include schemaLocation="Components/Button.xsd"/>
</xs:schema>
-1
View File
@@ -2,7 +2,6 @@
<Physics xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Physics.xsd">
<Velocity X="0" Y="0" Z="0"/>
<Gravity>true</Gravity>
<PrevOrigin X="-9876.5" Y="-9876.5" Z="-9876.5"/>
<IsOnGround>false</IsOnGround>
<VerticalStepHeight>0.33</VerticalStepHeight>
</Physics>
-1
View File
@@ -13,7 +13,6 @@
<xs:annotation><xs:documentation>m/s^2</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Gravity" type="t:bool" minOccurs="0"/>
<xs:element name="PrevOrigin" type="t:Vector" minOccurs="0"/>
<xs:element name="IsOnGround" type="t:bool" minOccurs="0"/>
<xs:element name="VerticalStepHeight" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>The largest height of a "stair-step" that can be walked over</xs:documentation></xs:annotation>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<SpriteIndicator xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SpriteIndicator.xsd">
<MinScale>10</MinScale>
<VisibleForSingleTeamOnly>false</VisibleForSingleTeamOnly>
</SpriteIndicator>
@@ -0,0 +1,19 @@
<?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:element name="SpriteIndicator">
<xs:annotation>
<xs:documentation>Billbord a Sprite around global Y axis</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="MinScale" type="t:double" minOccurs="0"/>
<xs:element name="VisibleForSingleTeamOnly" type="t:bool" minOccurs="0">
<xs:annotation><xs:documentation>Add a Team component to this Entity or Parent to make it visible only for that team</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+5 -5
View File
@@ -2,18 +2,18 @@
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:AABB/>
<c:AmmoPickup/>
<c:Model>
<Resource>Models/Props/PickUps/AmmoPickUp.mesh</Resource>
</c:Model>
<c:RaptorCopter>
<Speed>0.1</Speed>
<Axis X="0" Y="1" Z="0"/>
<Speed>8</Speed>
<Axis X="0" Y="0.100000001" Z="0"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="1" Z="0"/>
<Scale X="0.3" Y="0.3" Z="0.3"/>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="18717.9453" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
+15 -1
View File
@@ -5,6 +5,20 @@
<c:Transform/>
</Components>
<Children/>
<Children>
<Entity>
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+5 -5
View File
@@ -2,18 +2,18 @@
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:AABB/>
<c:HealthPickup/>
<c:Model>
<Resource>Models/Props/PickUps/HealthPickUp.mesh</Resource>
</c:Model>
<c:RaptorCopter>
<Speed>0.1</Speed>
<Axis X="0" Y="1" Z="0"/>
<Speed>8</Speed>
<Axis X="0" Y="0.100000001" Z="0"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="1" Z="0"/>
<Scale X="0.3" Y="0.3" Z="0.3"/>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="18767.0273" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
+47 -10
View File
@@ -60,6 +60,7 @@
<c:Sprite>
<DiffuseTexture>Textures/Weapons/Crosshair/SmallThickHoleDot.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.200000003"/>
@@ -110,6 +111,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/HealthHUD3.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0" G="0" R="0"/>
</c:Sprite>
<c:HealthHUD/>
@@ -135,6 +137,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
@@ -152,6 +155,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -167,6 +171,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
@@ -185,6 +190,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -200,6 +206,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Sprite>
<c:Transform>
@@ -217,6 +224,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -232,6 +240,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
@@ -249,6 +258,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -264,6 +274,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="0" G="0.200000003" R="1"/>
</c:Sprite>
<c:Transform>
@@ -279,6 +290,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -291,8 +303,7 @@
</Children>
</Entity>
</Children>
</Entity>
<Entity name="KillFeed">
</Entity> <Entity name="KillFeed">
<Components>
<c:KillFeed/>
<c:Transform>
@@ -304,6 +315,7 @@
<Entity name="KillFeed1">
<Components>
<c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>
<Right/>
@@ -316,6 +328,7 @@
<Entity name="KillFeed2">
<Components>
<c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>
<Right/>
@@ -330,6 +343,7 @@
<Entity name="KillFeed3">
<Components>
<c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>
<Right/>
@@ -349,13 +363,14 @@
<Components>
<c:Animation>
<AnimationName1>Idle</AnimationName1>
<Time1>1.6050530664521858</Time1>
<Time1>0.97725610639912475</Time1>
<Speed1>1</Speed1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:Model>
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
<Color A="1" B="1" G="0.309803933" R="0"/>
<Transparent>true</Transparent>
</c:Model>
<c:Transform/>
</Components>
@@ -367,11 +382,10 @@
</c:BoneAttachment>
<c:Model>
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
<Transparent>true</Transparent>
</c:Model>
<c:Transform>
<Position X="0.12043035" Y="-0.234149337" Z="-0.181454644"/>
<Orientation X="0.0104045281" Y="-0.00268131681" Z="0.0428438708"/>
<Position X="0.12043038" Y="-0.244988307" Z="-0.181454808"/>
<Orientation X="0.010404544" Y="-0.00268173823" Z="0.0428441577"/>
</c:Transform>
</Components>
<Children>
@@ -408,6 +422,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0" G="0" R="0"/>
</c:Sprite>
<c:Transform>
@@ -477,8 +492,10 @@
<Components>
<c:Animation>
<AnimationName1>Idle</AnimationName1>
<Time1>1.620305457513453</Time1>
<Time1>0.87583812735846323</Time1>
<Speed1>1</Speed1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:AnimationOffset>
<AnimationName>AimRifle</AnimationName>
@@ -501,8 +518,8 @@
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0.160351232" Y="1.02591991" Z="-0.215102971"/>
<Orientation X="-0.0627480298" Y="-0.0432248674" Z="0.119431816"/>
<Position X="0.163429111" Y="1.0235405" Z="-0.215489209"/>
<Orientation X="-0.0631071255" Y="-0.0576644838" Z="0.118255548"/>
</c:Transform>
</Components>
<Children>
@@ -572,6 +589,26 @@
</Components>
<Children/>
</Entity>
<Entity name="Indicator">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Icons/Arrow.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
<Color A="1" B="1" G="0.309803933" R="0"/>
</c:Sprite>
<c:HiddenForLocalPlayer/>
<c:SpriteIndicator>
<MinScale>50</MinScale>
<VisibleForSingleTeamOnly>true</VisibleForSingleTeamOnly>
</c:SpriteIndicator>
<c:Transform>
<Position X="0" Y="1.84019077" Z="0"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+46 -8
View File
@@ -60,6 +60,7 @@
<c:Sprite>
<DiffuseTexture>Textures/Weapons/Crosshair/SmallThickHoleDot.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.200000003"/>
@@ -110,6 +111,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/HealthHUD3.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0" G="0" R="0"/>
</c:Sprite>
<c:HealthHUD/>
@@ -135,6 +137,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
@@ -152,6 +155,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -167,6 +171,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
@@ -185,6 +190,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -200,6 +206,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Sprite>
<c:Transform>
@@ -217,6 +224,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -232,6 +240,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
@@ -249,6 +258,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -264,6 +274,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="0" G="0.200000003" R="1"/>
</c:Sprite>
<c:Transform>
@@ -279,6 +290,7 @@
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
@@ -304,6 +316,7 @@
<Entity name="KillFeed1">
<Components>
<c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>
<Right/>
@@ -316,6 +329,7 @@
<Entity name="KillFeed2">
<Components>
<c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>
<Right/>
@@ -330,6 +344,7 @@
<Entity name="KillFeed3">
<Components>
<c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>
<Right/>
@@ -349,13 +364,14 @@
<Components>
<c:Animation>
<AnimationName1>Idle</AnimationName1>
<Time1>1.6050530664521858</Time1>
<Time1>1.2667383999985162</Time1>
<Speed1>1</Speed1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:Model>
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
<Color A="1" B="0" G="0" R="1"/>
<Transparent>true</Transparent>
</c:Model>
<c:Transform/>
</Components>
@@ -367,11 +383,10 @@
</c:BoneAttachment>
<c:Model>
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
<Transparent>true</Transparent>
</c:Model>
<c:Transform>
<Position X="0.12043035" Y="-0.234149337" Z="-0.181454644"/>
<Orientation X="0.0104045281" Y="-0.00268131681" Z="0.0428438708"/>
<Position X="0.120430425" Y="-0.242105931" Z="-0.181454822"/>
<Orientation X="0.010404665" Y="-0.00268179877" Z="0.0428443067"/>
</c:Transform>
</Components>
<Children>
@@ -408,6 +423,7 @@
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0" G="0" R="0"/>
</c:Sprite>
<c:Transform>
@@ -477,8 +493,10 @@
<Components>
<c:Animation>
<AnimationName1>Idle</AnimationName1>
<Time1>1.620305457513453</Time1>
<Time1>0.26532318661337229</Time1>
<Speed1>1</Speed1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:AnimationOffset>
<AnimationName>AimRifle</AnimationName>
@@ -501,8 +519,8 @@
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0.160351232" Y="1.02591991" Z="-0.215102971"/>
<Orientation X="-0.0627480298" Y="-0.0432248674" Z="0.119431816"/>
<Position X="0.159282878" Y="1.0300566" Z="-0.216084003"/>
<Orientation X="-0.0626799241" Y="-0.0390551724" Z="0.119761385"/>
</c:Transform>
</Components>
<Children>
@@ -572,6 +590,26 @@
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Icons/Arrow.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
<Color A="1" B="0" G="0" R="1"/>
</c:Sprite>
<c:HiddenForLocalPlayer/>
<c:SpriteIndicator>
<MinScale>50</MinScale>
<VisibleForSingleTeamOnly>true</VisibleForSingleTeamOnly>
</c:SpriteIndicator>
<c:Transform>
<Position X="0" Y="1.84000003" Z="0"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
@@ -19,6 +19,8 @@ void main()
vec4 bloomColor = texture(BloomTexture, Input.TextureCoordinate);
vec4 hdrColorLowRes = texture(SceneTextureLowRes, Input.TextureCoordinate);
vec4 bloomColorLowRes = texture(BloomTextureLowRes, Input.TextureCoordinate);
//hdrColor = hdrColor * SSAO;
hdrColor += bloomColor;
hdrColorLowRes;
@@ -33,7 +35,6 @@ void main()
//gamme correction
result = pow(result, vec3(1.0 / Gamma));
fragmentColor = vec4(result, 1.0);
//fragmentColor = hdrColor;
//fragmentColor = bloomColor;
+24 -10
View File
@@ -1,5 +1,7 @@
#version 430
#define MIN_AMBIENT_LIGHT 0.3
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
@@ -10,15 +12,18 @@ uniform vec4 FillColor;
uniform vec4 AmbientColor;
uniform float FillPercentage;
uniform float GlowIntensity = 10;
uniform vec3 CameraPosition;
uniform vec2 DiffuseUVRepeat;
uniform vec2 NormalUVRepeat;
uniform vec2 SpecularUVRepeat;
uniform vec2 GlowUVRepeat;
layout (binding = 0) uniform sampler2D DiffuseTexture;
layout (binding = 1) uniform sampler2D NormalMapTexture;
layout (binding = 2) uniform sampler2D SpecularMapTexture;
layout (binding = 3) uniform sampler2D GlowMapTexture;
layout (binding = 0) uniform sampler2D AOTexture;
layout (binding = 1) uniform sampler2D DiffuseTexture;
layout (binding = 2) uniform sampler2D NormalMapTexture;
layout (binding = 3) uniform sampler2D SpecularMapTexture;
layout (binding = 4) uniform sampler2D GlowMapTexture;
layout (binding = 5) uniform samplerCube CubeMap;
#define TILE_SIZE 16
@@ -73,7 +78,7 @@ struct LightResult {
};
float CalcAttenuation(float radius, float dist, float falloff) {
return 1.0 - smoothstep(radius * 0.3, radius, dist);
return 1.0 - smoothstep(radius * falloff, radius, dist);
}
vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) {
@@ -120,6 +125,8 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu
void main()
{
float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy), 0).r;
ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT);
vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate * DiffuseUVRepeat);
vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate * GlowUVRepeat);
vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate * SpecularUVRepeat);
@@ -127,14 +134,18 @@ void main()
vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate * NormalUVRepeat, NormalMapTexture);
normal = normalize(normal);
//vec4 normal = normalize(V * vec4(Input.Normal, 0.0));
vec4 viewVec = normalize(-position);
vec4 viewVec = normalize(-position);
vec3 I = normalize(vec3(M * vec4(Input.Position, 1.0)) - CameraPosition);
vec3 R = reflect(-I, Input.Normal);
//R = vec3(P * vec4(R, 1.0));
vec4 reflectionColor = texture(CubeMap, R);
vec2 tilePos;
tilePos.x = int(gl_FragCoord.x/TILE_SIZE);
tilePos.y = int(gl_FragCoord.y/TILE_SIZE);
LightResult totalLighting;
totalLighting.Diffuse = vec4(AmbientColor.rgb, 1.0);
totalLighting.Diffuse = vec4(AmbientColor.rgb * ao, 1.0);
int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE)));
int start = int(LightGrids.Data[currentTile].Start);
@@ -152,12 +163,14 @@ void main()
} else if (light.Type == 2) { //Directional
light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
}
totalLighting.Diffuse += light_result.Diffuse;
totalLighting.Specular += light_result.Specular;
totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a);
totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a);
}
vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed);
color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel));
float specularResult = (specularTexel.r + specularTexel.g + specularTexel.b)/3.0;
color_result = color_result * clamp(1/specularTexel, 0, 1)*2 + reflectionColor * clamp(specularTexel, 0, 1)/2;
//vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color;
@@ -167,9 +180,10 @@ void main()
color_result += FillColor;
}
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
//sceneColor = vec4(reflectionColor.xyz, 1);
color_result += glowTexel*GlowIntensity;
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0);
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), clamp(color_result.a, 0, 1));
//Tiled Debug Code
/*
+4 -4
View File
@@ -23,12 +23,12 @@ out VertexData{
void main()
{
gl_Position = P*V*M * vec4(Position, 1.0);
mat4 TIM = transpose(inverse(M));
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.Normal = vec3(TIM * vec4(Normal, 0.0));
Output.Tangent = vec3(TIM * vec4(Tangent, 0.0));
Output.BiTangent = vec3(TIM * vec4(BiTangent, 0.0));
Output.ExplosionColor = vec4(1.0);
Output.ExplosionPercentageElapsed = 0.0;
}
@@ -1,5 +1,7 @@
#version 430
#define MIN_AMBIENT_LIGHT 0.3
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
@@ -23,19 +25,20 @@ uniform vec2 SpecularUVRepeat3;
uniform vec2 GlowUVRepeat1;
uniform vec2 GlowUVRepeat2;
uniform vec2 GlowUVRepeat3;
layout (binding = 0) uniform sampler2D SplatMapTexture;
layout (binding = 1) uniform sampler2D DiffuseTexture1;
layout (binding = 2) uniform sampler2D DiffuseTexture2;
layout (binding = 3) uniform sampler2D DiffuseTexture3;
layout (binding = 4) uniform sampler2D NormalMapTexture1;
layout (binding = 5) uniform sampler2D NormalMapTexture2;
layout (binding = 6) uniform sampler2D NormalMapTexture3;
layout (binding = 7) uniform sampler2D SpecularMapTexture1;
layout (binding = 8) uniform sampler2D SpecularMapTexture2;
layout (binding = 9) uniform sampler2D SpecularMapTexture3;
layout (binding = 10) uniform sampler2D GlowMapTexture1;
layout (binding = 11) uniform sampler2D GlowMapTexture2;
layout (binding = 12) uniform sampler2D GlowMapTexture3;
layout (binding = 0) uniform sampler2D AOTexture;
layout (binding = 1) uniform sampler2D SplatMapTexture;
layout (binding = 2) uniform sampler2D DiffuseTexture1;
layout (binding = 3) uniform sampler2D DiffuseTexture2;
layout (binding = 4) uniform sampler2D DiffuseTexture3;
layout (binding = 5) uniform sampler2D NormalMapTexture1;
layout (binding = 6) uniform sampler2D NormalMapTexture2;
layout (binding = 7) uniform sampler2D NormalMapTexture3;
layout (binding = 8) uniform sampler2D SpecularMapTexture1;
layout (binding = 9) uniform sampler2D SpecularMapTexture2;
layout (binding = 10) uniform sampler2D SpecularMapTexture3;
layout (binding = 11) uniform sampler2D GlowMapTexture1;
layout (binding = 12) uniform sampler2D GlowMapTexture2;
layout (binding = 13) uniform sampler2D GlowMapTexture3;
#define TILE_SIZE 16
@@ -174,6 +177,9 @@ vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B,
void main()
{
float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy), 0).r;
ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT);
vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate);
vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3,
@@ -195,7 +201,7 @@ void main()
tilePos.y = int(gl_FragCoord.y/TILE_SIZE);
LightResult totalLighting;
totalLighting.Diffuse = vec4(AmbientColor.rgb, 1.0);
totalLighting.Diffuse = vec4(AmbientColor.rgb * ao, 1.0);
int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE)));
int start = int(LightGrids.Data[currentTile].Start);
@@ -213,8 +219,8 @@ void main()
} else if (light.Type == 2) { //Directional
light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
}
totalLighting.Diffuse += light_result.Diffuse;
totalLighting.Specular += light_result.Specular;
totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a);
totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a);
}
vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed);
+114
View File
@@ -0,0 +1,114 @@
#version 430
//Number of samples per pixel
uniform int uNumOfSamples;
//#define NUM_SAMPLES (11)
//Number of turns around the cirle
uniform int uNumOfTurns;
//#define NUM_TURNS (7)
layout (binding = 0) uniform sampler2D ViewSpaceZ;
uniform vec4 uProjInfo;
uniform float uProjScale;
//#define ProjScale 500
uniform float uRadius;
//#define Radius 1.0f
uniform float uBias;
//#define Bias 0.012f
uniform float uContrast;
//#define IntensityDivR6 1
uniform float uIntensityScale;
out float AO;
vec3 getVSPosition(ivec2 ScreenSpaceCoord) {
float z = texelFetch(ViewSpaceZ, ScreenSpaceCoord, 0).r;
//Get the xy view space coordinates and add the z value from ViewSpaceZ buffer.
return vec3((uProjInfo[0] + (ScreenSpaceCoord.x * uProjInfo[1])) * z, (uProjInfo[2] + (ScreenSpaceCoord.y * uProjInfo[3])) * z, z);
}
vec3 getVSFaceNormal(vec3 ViewSpacePosition) {
// Get tangets vector for the plane and ViewSpacePositin... don't ask how this functions works. It's pure magic.
// They do this and it just works... I would guess that they approximate the function of a plane from pixels close to the pixel were on now.
return normalize(cross(dFdx(ViewSpacePosition), dFdy(ViewSpacePosition)));
}
vec3 getSampleViewSpacePos(ivec2 ScreenSpaceCoord, int SampleIndex, float RotationAngle, float ScreenSpaceSampleRadius){
// Pure Magic...
float alpha = float(SampleIndex) * (1.0 / uNumOfSamples);
// Angle to where to sample
float angle = alpha * (uNumOfTurns * 6.28) + RotationAngle;
//Lenght to were to sample
ScreenSpaceSampleRadius = ScreenSpaceSampleRadius * alpha;
vec2 screenSpaceSampleOffsetVecor = vec2(cos(angle), sin(angle));
// Get texel coordinate on where to sample by going screenSpaceSampleOffsetVecor direction in ScreenSpaceSampleRadius units from ScreenSpaceCoord (the point being shaded);
ivec2 screenSpaceSampleTexel = ivec2(ScreenSpaceSampleRadius * screenSpaceSampleOffsetVecor) + ScreenSpaceCoord;
return getVSPosition(screenSpaceSampleTexel);
}
float sampleAO(ivec2 ScreenSpaceCoord, vec3 Origin, vec3 OriginNormal, float ScreenSpaceSampleRadius, int SampleIndex, float RotationAngle, float Radius) {
float radius2 = Radius * Radius;
vec3 sampleViewSpacePosition = getSampleViewSpacePos(ScreenSpaceCoord, SampleIndex, RotationAngle, ScreenSpaceSampleRadius);
vec3 sampleVector = Origin - sampleViewSpacePosition;
// vv = sampleVectorLenght ^ 2
float vv = dot(sampleVector, sampleVector);
// vn = angle between sampleVector and Normal
float vn = dot(sampleVector, OriginNormal);
const float epsilon = 0.0001f;
// vv < radius2 if the vector is shorter then the radius;
// vn - bias, offset the angle to reduse self occlusion.
// epsilon is here to make divison by 0 impossible.
return float(vv < radius2) * max((vn - uBias) / (epsilon + vv), 0.0);
//float f = max(radius2 - vv, 0.0);
//return f * f * f * max((vn - uBias) / (epsilon + vv), 0.0);
}
void main() {
ivec2 originScreenCoord = ivec2(gl_FragCoord.xy);
vec3 origin = getVSPosition(originScreenCoord);
float radius;
if(origin.z < uRadius){
radius = origin.z;
} else {
radius = uRadius;
}
vec3 originNormal = getVSFaceNormal(origin);
float screenSpaceSampleRadius = -uProjScale * radius / origin.z;
float rotationAngleOffset = 30 * originScreenCoord.x ^ originScreenCoord.y + 10 * originScreenCoord.x * originScreenCoord.y;
float sum = 0.0;
for (int i = 0; i < uNumOfSamples; i++) {
sum += sampleAO(originScreenCoord, origin, originNormal, screenSpaceSampleRadius, i, rotationAngleOffset, radius);
}
//float A = max(0.0, 1.0 - sum * (2.0f / uNumOfSamples));
float A = 1.0 - sum * (2.0f * uIntensityScale / float(uNumOfSamples));
AO = clamp(pow(A, uContrast), 0.0f, 1.0f);
//AO = vec4(originNormal, 1.0f);
}
+8
View File
@@ -0,0 +1,8 @@
#version 430
layout (location = 0) in vec3 Position;
void main()
{
gl_Position = vec4(Position, 1.0);
}
@@ -0,0 +1,14 @@
#version 430
layout (binding = 0) uniform sampler2D DepthBuffer;
uniform vec3 ClipInfo;
out float depthLinear;
//Just for Debug, should be depthLinear
//out vec4 fragmentColor;
void main() {
float depthSample = texelFetch(DepthBuffer, ivec2(gl_FragCoord.xy), 0).r;
depthLinear = ClipInfo[0] / (ClipInfo[1] * depthSample + ClipInfo[2]);
//float depthLinear = (NearClip) / ( -depthSample + 1.0f);
//fragmentColor = vec4(depthLinear, depthLinear, depthLinear, 1.0f);
}
+2 -2
View File
@@ -7,8 +7,8 @@ uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
layout (binding = 0) uniform sampler2D DiffuseTexture;
layout (binding = 1) uniform sampler2D GlowMapTexture;
layout (binding = 1) uniform sampler2D DiffuseTexture;
layout (binding = 2) uniform sampler2D GlowMapTexture;
in VertexData{
+45 -43
View File
@@ -16,51 +16,51 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
EntityAABB& boxA = *boundingBox;
bool everHitTheGround = false;
glm::vec3 size = boxA.Size();
float diameter = std::min(size.x, size.z);
glm::vec3 prevOrigin = (glm::vec3)cPhysics["PrevOrigin"];
glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin;
float rayLength = glm::length(toCurrentPos) + 0.5f*diameter;
//If the entity has moved farther than the size of its box, we need to handle it specially.
bool traceCollision = rayLength > diameter;
//hack solution: If prevOrigin is less than -9000 in all dimensions,
//then it means it is not set, i.e. this is the first collision check for the entity.
if (traceCollision && glm::any(glm::greaterThan((glm::vec3)cPhysics["PrevOrigin"], glm::vec3(-9000.f)))) {
Ray ray(prevOrigin, toCurrentPos);
m_OctreeResult.clear();
m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult);
for (auto& boxB : m_OctreeResult) {
if (boxA.Entity == boxB.Entity) {
continue;
}
bool hit;
float dist;
if (boxB.Entity.HasComponent("Model")) {
RawModel* model;
std::string res = (std::string)boxB.Entity["Model"]["Resource"];
try {
model = ResourceManager::Load<RawModel, true>(res);
} catch (const std::exception&) {
auto prevPosIt = m_PrevPositions.find(entity);
if (prevPosIt != m_PrevPositions.end()) {
glm::vec3 size = boxA.Size();
float diameter = std::min(size.x, size.z);
glm::vec3 prevOrigin = prevPosIt->second;
glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin;
float rayLength = glm::length(toCurrentPos) + 0.5f*diameter;
//If the entity has moved farther than the size of its box, we need to handle it specially.
if (rayLength > diameter) {
Ray ray(prevOrigin, toCurrentPos);
m_OctreeResult.clear();
m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult);
for (auto& boxB : m_OctreeResult) {
if (boxA.Entity == boxB.Entity) {
continue;
}
float u, v;
hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v);
} else {
hit = Collision::RayVsAABB(ray, boxB, dist);
}
if (hit && dist < rayLength) {
//Set the entity to where it was colliding, minus the maximum box size.
//TODO: Perhaps this should be done slightly more properly.
glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction();
glm::vec3 resolve = newOriginPos - boxA.Origin();
(glm::vec3&)cTransform["Position"] += resolve;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolve.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
bool hit;
float dist;
if (boxB.Entity.HasComponent("Model")) {
RawModel* model;
std::string res = (std::string)boxB.Entity["Model"]["Resource"];
try {
model = ResourceManager::Load<RawModel, true>(res);
} catch (const std::exception&) {
continue;
}
float u, v;
hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v);
} else {
hit = Collision::RayVsAABB(ray, boxB, dist);
}
if (hit && dist < rayLength) {
//Set the entity to where it was colliding, minus the maximum box size.
//TODO: Perhaps this should be done slightly more properly.
glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction();
glm::vec3 resolve = newOriginPos - boxA.Origin();
(glm::vec3&)cTransform["Position"] += resolve;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolve.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
}
break;
}
break;
}
}
}
@@ -90,6 +90,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
(glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
cPhysics["Velocity"] = inOutVelocity;
if (isOnGround) {
everHitTheGround = true;
@@ -99,6 +100,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
} else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
//Enter here if boxB has no Model.
(glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolutionVector.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
@@ -112,5 +114,5 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
(bool)cPhysics["IsOnGround"] = false;
}
(glm::vec3&)cPhysics["PrevOrigin"] = boxA.Origin();
m_PrevPositions[entity] = boxA.Origin();
}
+5
View File
@@ -112,6 +112,11 @@ size_t ComponentPool::size() const
return m_Pool.size();
}
std::size_t ComponentPool::MemoryUsage() const
{
return m_Pool.MemoryUsage();
}
template <typename InterpretType /*= char*/>
void ComponentPool::Dump() const
{
+45 -1
View File
@@ -34,6 +34,15 @@ EntityWrapper EntityWrapper::Parent()
}
}
EntityWrapper EntityWrapper::BaseParent()
{
EntityWrapper baseParent = Parent();
while (baseParent.Parent().Valid()) {
baseParent = baseParent.Parent();
}
return baseParent;
}
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
{
return firstChildByNameRecursive(name, this->ID);
@@ -51,6 +60,17 @@ EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& compone
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::Clone(EntityWrapper parent /*= Invalid*/)
{
if (!Valid()) {
return EntityWrapper::Invalid;
}
EntityWrapper clone = cloneRecursive(*this, EntityWrapper::Invalid);
this->World->SetParent(clone.ID, parent.ID);
return clone;
}
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
{
EntityWrapper entity = *this;
@@ -111,7 +131,7 @@ EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name,
return EntityWrapper::Invalid;
}
auto itPair = this->World->GetChildren(parent);
auto itPair = this->World->GetDirectChildren(parent);
if (itPair.first == itPair.second) {
return EntityWrapper::Invalid;
}
@@ -131,3 +151,27 @@ EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name,
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::cloneRecursive(EntityWrapper entity, EntityWrapper parent)
{
EntityWrapper clone = EntityWrapper(entity.World, entity.World->CreateEntity(parent.ID));
entity.World->SetName(clone.ID, entity.Name());
// Clone components
for (auto& kv : entity.World->GetComponentPools()) {
if (kv.second->KnowsEntity(entity.ID)) {
ComponentWrapper c1 = kv.second->GetByEntity(entity.ID);
ComponentWrapper c2 = entity.World->AttachComponent(clone.ID, kv.first);
c1.Copy(c2);
}
}
// Clone children
auto children = entity.World->GetDirectChildren(entity.ID);
for (auto it = children.first; it != children.second; ++it) {
EntityWrapper child(entity.World, it->second);
cloneRecursive(child, clone);
}
return clone;
}
+12 -1
View File
@@ -127,7 +127,7 @@ void World::SetParent(EntityID entity, EntityID parent)
m_EntityChildren.insert(std::make_pair(parent, entity));
}
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetChildren(EntityID entity)
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetDirectChildren(EntityID entity)
{
return m_EntityChildren.equal_range(entity);
}
@@ -151,6 +151,17 @@ std::string World::GetName(EntityID entity) const
}
}
std::size_t World::MemoryUsage() const
{
std::size_t mem = 0;
for (auto& kv : m_ComponentPools) {
mem += kv.second->MemoryUsage();
}
return mem;
}
EntityID World::generateEntityID()
{
// TODO: Make EntityID generation smarter
+29 -6
View File
@@ -598,6 +598,28 @@ bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
entityImport(m_World);
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_C) {
m_CopyTarget = m_CurrentSelection;
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_Z) {
if (m_OnUndo != nullptr) {
m_OnUndo();
if (!m_CurrentSelection.Valid()) {
SelectEntity(EntityWrapper::Invalid);
}
}
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_V) {
if (m_OnEntityPaste != nullptr) {
EntityWrapper copy = m_OnEntityPaste(m_CopyTarget, m_CurrentSelection);
if (copy != EntityWrapper::Invalid) {
SelectEntity(copy);
}
}
}
if (e.KeyCode == GLFW_KEY_DELETE) {
if (m_CurrentSelection.Valid()) {
entityDelete(m_CurrentSelection);
@@ -761,13 +783,13 @@ bool EditorGUI::compareCharArray(const char* c1, const char* c2)
void EditorGUI::SetDirty(EntityWrapper entity)
{
EntityWrapper baseParent = entity;
while (baseParent.Parent().Valid()) {
baseParent = baseParent.Parent();
}
EntityWrapper baseParent = entity.BaseParent();
if (m_EntityFiles.find(baseParent) != m_EntityFiles.end()) {
m_EntityFiles.at(baseParent).Dirty = true;
}
if (m_OnDirty != nullptr) {
m_OnDirty(entity);
}
}
void EditorGUI::entityImport(World* world)
@@ -817,6 +839,7 @@ void EditorGUI::entityCreate(World* world, EntityWrapper parent)
parent.World = world;
}
EntityWrapper newEntity = m_OnEntityCreate(parent);
SetDirty(newEntity);
SelectEntity(newEntity);
}
}
@@ -832,9 +855,9 @@ void EditorGUI::entityDelete(EntityWrapper entity)
if (boost::any_cast<EntityWrapper>(m_ModalData[modalName]) == entity) {
EntityWrapper parent = entity.Parent();
if (m_OnEntityDelete != nullptr) {
SetDirty(entity);
m_OnEntityDelete(entity);
m_EntityFiles.erase(entity);
SetDirty(parent);
}
if (!m_CurrentSelection.Valid()) {
SelectEntity(parent);
@@ -851,8 +874,8 @@ void EditorGUI::entityChangeParent(EntityWrapper entity, EntityWrapper parent)
}
if (m_OnEntityChangeParent != nullptr) {
SetDirty(entity);
m_OnEntityChangeParent(entity, parent);
SetDirty(entity);
LOG_DEBUG("Changed parent of %i to %i", entity.ID, parent.ID);
}
}
+26
View File
@@ -28,10 +28,13 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame
m_EditorGUI->SetEntityDeleteCallback(std::bind(&EditorSystem::OnEntityDelete, this, std::placeholders::_1));
m_EditorGUI->SetEntityChangeParentCallback(std::bind(&EditorSystem::OnEntityChangeParent, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetEntityPasteCallback(std::bind(&EditorSystem::OnEntityPaste, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
m_EditorGUI->SetWidgetSpaceCallback(std::bind(&EditorSystem::OnWidgetSpace, this, std::placeholders::_1));
m_EditorGUI->SetDirtyCallback(std::bind(&EditorSystem::OnDirty, this, std::placeholders::_1));
m_EditorGUI->SetUndoCallback(std::bind(&EditorSystem::OnUndo, this));
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
@@ -86,6 +89,11 @@ void EditorSystem::Update(double dt)
glm::vec3& pos = cameraTransform["Position"];
pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta;
}
if (m_SaveUndoLevel) {
m_UndoLevels.push_back(*m_World);
m_SaveUndoLevel = false;
}
}
void EditorSystem::Enable()
@@ -160,6 +168,11 @@ void EditorSystem::OnEntityChangeName(EntityWrapper entity, const std::string& n
}
}
EntityWrapper EditorSystem::OnEntityPaste(EntityWrapper entityToCopy, EntityWrapper parent)
{
return entityToCopy.Clone(parent);
}
void EditorSystem::OnComponentAttach(EntityWrapper entity, const std::string& componentType)
{
if (entity.Valid()) {
@@ -179,6 +192,19 @@ void EditorSystem::OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace)
m_WidgetSpace = widgetSpace;
}
void EditorSystem::OnDirty(EntityWrapper entity)
{
m_SaveUndoLevel = true;
}
void EditorSystem::OnUndo()
{
// The last "undo level" is always the most recent change
if (m_UndoLevels.size() >= 2) {
*m_World = m_UndoLevels.at(m_UndoLevels.size() - 2);
}
}
bool EditorSystem::OnMousePress(const Events::MousePress& e)
{
ImGuiIO& io = ImGui::GetIO();
+121 -13
View File
@@ -1,7 +1,7 @@
#include "Network/Client.h"
using namespace boost::asio::ip;
Client::Client(World* world, EventBroker* eventBroker)
Client::Client(World* world, EventBroker* eventBroker)
: Network(world, eventBroker)
{
// Asumes root node is EntityID_Invalid
@@ -13,6 +13,8 @@ Client::Client(World* world, EventBroker* eventBroker)
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
LOG_INFO("Client initialized");
m_ServerlistRequest.Connect(m_PlayerName, "192.168.1.255", 32554);
}
Client::Client(World* world, EventBroker* eventBroker, std::unique_ptr<SnapshotFilter> snapshotFilter)
@@ -30,6 +32,8 @@ void Client::Connect(std::string address, int port)
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers);
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Address = address;
if (address.empty()) {
@@ -66,6 +70,21 @@ void Client::Update()
}
while (m_ServerlistRequest.IsSocketAvailable()) {
Packet packet(MessageType::Invalid);
m_ServerlistRequest.Receive(packet);
if (packet.GetMessageType() == MessageType::ServerlistRequest) {
parseServerlist(packet);
}
}
if (m_SearchingForServers) {
if (m_SearchingTime < (1000* (std::clock() - m_StartSearchTime) / (double)CLOCKS_PER_SEC)) {
m_SearchingForServers = false;
displayServerlist();
}
}
if (m_IsConnected) {
// Don't send 1 input in 1 packet, bunch em up.
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
@@ -122,6 +141,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::OnPlayerDamage:
parsePlayerDamage(packet);
break;
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
break;
default:
break;
}
@@ -173,6 +195,22 @@ void Client::parsePing()
m_Reliable.Send(packet);
}
void Client::parseServerlist(Packet& packet)
{
// Pop size, message type, and ID
packet.ReadPrimitive<int>();
packet.ReadPrimitive<int>();
packet.ReadPrimitive<int>();
std::string address = packet.ReadString();
int port = packet.ReadPrimitive<int>();
std::string serverName = packet.ReadString();
int playersConnected = packet.ReadPrimitive<int>();
//TODO: This should not happen when a client is connected to a server
m_Serverlist.push_back({ address, port, serverName, playersConnected });
}
void Client::parseKick()
{
LOG_WARNING("You have been kicked from the server.");
@@ -190,12 +228,12 @@ void Client::parseSpawnEvents()
}
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Player.ID));
//e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID));
e.PlayerID = -1;
e.PlayerID = -1;
e.PlayerName = m_PlayerSpawnEvents.at(i).PlayerName;
m_EventBroker->Publish(e);
}
m_PlayerSpawnEvents = tempSpawn;
// m_PlayerSpawnEvents.clear();
// m_PlayerSpawnEvents.clear();
}
void Client::parsePlayersSpawned(Packet& packet)
@@ -223,8 +261,14 @@ void Client::parseEntityDeletion(Packet & packet)
if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) {
EntityID localEntity = m_ServerIDToClientID.at(entityToDelete);
if (m_World->ValidEntity(localEntity)) {
m_World->DeleteEntity(localEntity);
deleteFromServerClientMaps(entityToDelete, localEntity);
if (m_World->HasComponent(localEntity,"Player")) {
Events::PlayerDeath e;
e.Player = EntityWrapper(m_World, localEntity);
m_EventBroker->Publish(e);
} else {
m_World->DeleteEntity(localEntity);
deleteFromServerClientMaps(entityToDelete, localEntity);
}
}
}
}
@@ -238,6 +282,20 @@ void Client::parseComponentDeletion(Packet & packet)
}
}
void Client::parseDoubleJump(Packet & packet)
{
EntityID serverID = packet.ReadPrimitive<EntityID>();
if (!serverClientMapsHasEntity(serverID)) {
return;
}
Events::DoubleJump e;
e.entityID = m_ServerIDToClientID.at(serverID);
// If player is local player do not publish to prevent infinite feedback loop
if (e.entityID != m_LocalPlayer.ID) {
m_EventBroker->Publish(e);
}
}
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID)
{
for (auto field : componentInfo.FieldsInOrder) {
@@ -312,19 +370,20 @@ void Client::parseSnapshot(Packet& packet)
if (serverClientMapsHasEntity(serverEntityID)) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
EntityWrapper localEntity(m_World, localEntityID);
// Update entity
if (m_World->HasComponent(localEntityID, componentType)) {
// TODO Fix memory leak here
SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo);
bool shouldApply = true;
// Apply potential filter function
if (m_SnapshotFilter != nullptr) {
shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent);
}
if (shouldApply) {
if (shouldApply) {
ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType);
memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride);
}
//if (localEntity != m_LocalPlayer && !localEntity.IsChildOf(m_LocalPlayer)) {
// updateFields(packet, componentInfo, localEntityID);
//} else {
@@ -341,7 +400,11 @@ void Client::parseSnapshot(Packet& packet)
if (serverParentID == EntityID_Invalid) {
newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
} else {
newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID));
if (serverClientMapsHasEntity(serverParentID)) {
newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID));
} else {
newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
}
}
m_World->SetName(newLocalEntityID, serverEntityName);
insertIntoServerClientMaps(serverEntityID, newLocalEntityID);
@@ -351,9 +414,11 @@ void Client::parseSnapshot(Packet& packet)
}
// Parent logic
// This should be enough beacause we know that the entities arives in pre-order (there will always be a parent)
if (serverParentID != EntityID_Invalid) {
if (serverParentID != EntityID_Invalid && serverClientMapsHasEntity(serverParentID)) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
if (m_World->GetParent(localEntityID) != m_ServerIDToClientID.at(serverParentID)) {
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
}
}
}
parseSpawnEvents();
@@ -371,6 +436,12 @@ void Client::disconnect()
bool Client::OnInputCommand(const Events::InputCommand & e)
{
// TEMP
if (e.Command == "SearchForServers" && e.Value > 0) {
Events::SearchForServers e;
m_EventBroker->Publish(e);
}
if (e.PlayerID != -1) {
return false;
}
@@ -415,6 +486,11 @@ bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
if (e.Inflictor != m_LocalPlayer) {
return false;
}
// Could this happen?
//if (!clientServerMapsHasEntity(e.Inflictor.ID)
// || !clientServerMapsHasEntity(e.Victim.ID)) {
// return;
//}
Packet packet(MessageType::OnPlayerDamage, m_SendPacketID);
packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID));
@@ -433,12 +509,23 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
return true;
}
bool Client::OnSearchForServers(const Events::SearchForServers& e)
{
m_SearchingForServers = true;
m_StartSearchTime = std::clock();
m_Serverlist.clear();
LOG_INFO("Searching for LAN servers...\n");
Packet packet(MessageType::ServerlistRequest);
m_ServerlistRequest.Broadcast(packet, 13); // TODO: Config
return true;
}
void Client::parsePlayerDamage(Packet& packet)
{
Events::PlayerDamage e;
PlayerID victimID = packet.ReadPrimitive<EntityID>();
PlayerID inflictorID = packet.ReadPrimitive<EntityID>();
if(!serverClientMapsHasEntity(victimID) || !serverClientMapsHasEntity(inflictorID)){
if (!serverClientMapsHasEntity(victimID) || !serverClientMapsHasEntity(inflictorID)) {
return;
}
e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(victimID));
@@ -450,6 +537,17 @@ void Client::parsePlayerDamage(Packet& packet)
}
}
bool Client::OnDoubleJump(Events::DoubleJump & e)
{
if (!clientServerMapsHasEntity(e.entityID) || e.entityID != m_LocalPlayer.ID) {
return false;
}
Packet packet(MessageType::OnDoubleJump);
packet.WritePrimitive(m_ClientIDToServerID.at(e.entityID));
m_Reliable.Send(packet);
return true;
}
void Client::sendLocalPlayerTransform()
{
if (!m_LocalPlayer.Valid()) {
@@ -467,7 +565,7 @@ void Client::sendLocalPlayerTransform()
packet.WritePrimitive(orientation.x);
packet.WritePrimitive(orientation.y);
packet.WritePrimitive(orientation.z);
bool hasAssaultWeapon = m_LocalPlayer.HasComponent("AssaultWeapon");
packet.WritePrimitive(hasAssaultWeapon);
if (hasAssaultWeapon) {
@@ -475,7 +573,7 @@ void Client::sendLocalPlayerTransform()
packet.WritePrimitive((int)cAssaultWeapon["MagazineAmmo"]);
packet.WritePrimitive((int)cAssaultWeapon["Ammo"]);
}
m_Unreliable.Send(packet);
}
@@ -528,6 +626,16 @@ void Client::becomePlayer()
m_Reliable.Send(packet);
}
void Client::displayServerlist()
{
LOG_INFO("This is a serverlist:\n");
for (int i = 0; i < m_Serverlist.size(); i++) {
ServerInfo si = m_Serverlist[i];
LOG_INFO("%s:%i\t%s\t%i\n", si.Address.c_str(), si.Port, si.Name.c_str(), si.PlayersConnected);
}
}
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
{
if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
-10
View File
@@ -1,10 +0,0 @@
#include "Network/HybridClient.h"
HybridClient::HybridClient()
{
}
HybridClient::~HybridClient()
{
}
-9
View File
@@ -1,9 +0,0 @@
#include "Network/HybridServer.h"
HybridServer::HybridServer()
{
}
HybridServer::~HybridServer()
{
}
+89 -42
View File
@@ -1,7 +1,8 @@
#include "Network/Server.h"
Server::Server(World* world, EventBroker* eventBroker, int port)
Server::Server(World* world, EventBroker* eventBroker, int port)
: Network(world, eventBroker)
, m_ServerlistRequest(13)
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
@@ -13,7 +14,7 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage);
// Bind
// BindWW
if (port == 0) {
port = config->Get<float>("Networking.Port", 27666);
}
@@ -28,9 +29,8 @@ Server::~Server()
void Server::Update()
{
PlayerDefinition pd;
m_Reliable.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers);
for (auto& kv : m_ConnectedPlayers) {
while (kv.second.TCPSocket->available()) {
// Packet will get real data in receive
@@ -46,6 +46,7 @@ void Server::Update()
}
}
PlayerDefinition pd;
while (m_Unreliable.IsSocketAvailable()) {
// Packet will get real data in receive
Packet packet(MessageType::Invalid);
@@ -58,6 +59,22 @@ void Server::Update()
parseMessageType(packet);
}
}
while (m_ServerlistRequest.IsSocketAvailable()) {
Packet packet(MessageType::Invalid);
PlayerDefinition localArea;
localArea.Endpoint = boost::asio::ip::udp::endpoint();
m_ServerlistRequest.Receive(packet, localArea);
if (packet.GetMessageType() == MessageType::ServerlistRequest) {
packet.ReadPrimitive<int>(); // Pop size
packet.ReadPrimitive<int>(); // Pop MsgType
packet.ReadPrimitive<int>(); // Pop packet ID
int port = packet.ReadPrimitive<int>();
std::string address = localArea.Endpoint.address().to_string();
parseServerlistRequest(boost::asio::ip::udp::endpoint(boost::asio::ip::address().from_string(address), port));
}
}
// Check if players have disconnected
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
disconnect(m_PlayersToDisconnect.at(i));
@@ -75,6 +92,7 @@ void Server::Update()
sendPing();
previousePingMessage = currentTime;
}
// Time out logic
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
checkForTimeOuts();
@@ -120,6 +138,9 @@ void Server::parseMessageType(Packet& packet)
case MessageType::PlayerTransform:
parsePlayerTransform(packet);
break;
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
break;
default:
break;
}
@@ -165,56 +186,55 @@ void Server::addInputCommandsToPacket(Packet& packet)
void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
auto itPair = m_World->GetDirectChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
EntityID childEntityID = it->second;
// HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself
// HACK: Also checked CapturePointHUD for now. (this would get out of sync);
EntityWrapper childEntity(m_World, childEntityID);
if (!shouldSendToClient(childEntity)) {
continue;
}
// Write EntityID and parentsID and Entity name
packet.WritePrimitive(childEntityID);
packet.WritePrimitive(entityID);
packet.WriteString(m_World->GetName(childEntityID));
// Write components to child
int numberOfComponents = 0;
for (auto& i : worldComponentPools) {
if (i.second->KnowsEntity(childEntityID)) {
numberOfComponents++;
if (shouldSendToClient(childEntity)) {
// Write EntityID and parentsID and Entity name
packet.WritePrimitive(childEntityID);
packet.WritePrimitive(entityID);
packet.WriteString(m_World->GetName(childEntityID));
// Write components to child
int numberOfComponents = 0;
for (auto& i : worldComponentPools) {
if (i.second->KnowsEntity(childEntityID)) {
numberOfComponents++;
}
}
}
// Write how many components should be read
packet.WritePrimitive(numberOfComponents);
for (auto& i : worldComponentPools) {
// If the entity exist in the pool
if (i.second->KnowsEntity(childEntityID)) {
ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID);
// ComponentType
packet.WriteString(componentWrapper.Info.Name);
// Loop through fields
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField);
if (fieldInfo.Type == "string") {
std::string& value = componentWrapper[componentField];
packet.WriteString(value);
} else {
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
// Write how many components should be read
packet.WritePrimitive(numberOfComponents);
for (auto& i : worldComponentPools) {
// If the entity exist in the pool
if (i.second->KnowsEntity(childEntityID)) {
ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID);
// ComponentType
packet.WriteString(componentWrapper.Info.Name);
// Loop through fields
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField);
if (fieldInfo.Type == "string") {
std::string& value = componentWrapper[componentField];
packet.WriteString(value);
} else {
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
}
}
}
}
}
// Go to to your children
addChildrenToPacket(packet, childEntityID);
addPlayersToPacket(packet, childEntityID);
}
}
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
auto itPair = m_World->GetDirectChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
@@ -273,6 +293,8 @@ void Server::sendPing()
reliableBroadcast(packet);
}
void Server::checkForTimeOuts()
{
double startPing = 1000 * m_StartPingTime
@@ -322,7 +344,7 @@ void Server::parseTCPConnect(Packet & packet)
// Read packet ID
m_PreviousPacketID = m_PacketID; // Set previous packet id
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
LOG_INFO("Parsing connections");
// Check if player is already connected
// Ska vara till lagd i TCPServer receive
@@ -370,6 +392,17 @@ void Server::parseDisconnect()
}
}
void Server::parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint)
{
Packet packet(MessageType::ServerlistRequest);
packet.WriteString(m_Reliable.Address());
packet.WritePrimitive<int>(m_Reliable.Port());
packet.WriteString("SERVERNAME");
packet.WritePrimitive<int>(m_ConnectedPlayers.size());
m_ServerlistRequest.Send(packet);
}
void Server::disconnect(PlayerID playerID)
{
//broadcast("A player disconnected");
@@ -394,6 +427,7 @@ void Server::parseOnPlayerDamage(Packet & packet)
e.Victim = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
e.Damage = packet.ReadPrimitive<double>();
m_EventBroker->Publish(e);
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
}
@@ -422,8 +456,7 @@ bool Server::OnInputCommand(const Events::InputCommand & e)
}
isReadingData = !isReadingData;
m_SaveDataTimer = std::clock();
}
if (e.Command == "KickPlayer" && e.Value > 0) {
} else if (e.Command == "KickPlayer" && e.Value > 0) {
kick(0);
}
@@ -474,7 +507,7 @@ bool Server::OnPlayerDamage(const Events::PlayerDamage& e)
packet.WritePrimitive(e.Damage);
reliableBroadcast(packet);
return false;
return true;
}
void Server::parseClientPing()
@@ -503,6 +536,12 @@ void Server::parsePing()
}
}
bool Server::parseDoubleJump(Packet & packet)
{
reliableBroadcast(packet);
return true;
}
void Server::parseOnInputCommand(Packet& packet)
{
PlayerID player = -1;
@@ -562,7 +601,15 @@ void Server::parsePlayerTransform(Packet& packet)
bool Server::shouldSendToClient(EntityWrapper childEntity)
{
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid();
auto children = m_World->GetDirectChildren(childEntity.ID);
for (auto it = children.first; it != children.second; it++) {
EntityWrapper child(m_World, it->second);
if(child.HasComponent("CapturePoint")) {
return true;
}
}
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid()
|| childEntity.HasComponent("CapturePoint");
}
PlayerID Server::GetPlayerIDFromEndpoint()
-20
View File
@@ -64,26 +64,6 @@ void TCPClient::Receive(Packet& packet)
size_t TCPClient::readBuffer()
{
//if (!m_Socket) {
// return 0;
//}
//boost::system::error_code error;
//// Read size of packet
//size_t bytesReceived = m_Socket->read_some(boost
// ::asio::buffer((void*)data, sizeof(int)),
// error);
//int sizeOfPacket = 0;
//memcpy(&sizeOfPacket, data, sizeof(int));
//// Read the rest of the message
//bytesReceived += m_Socket->read_some(boost
// ::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
// error);
//if (error) {
// //LOG_ERROR("receive: %s", error.message().c_str());
//}
//return bytesReceived;
if (!m_Socket) {
return 0;
}
+33 -56
View File
@@ -1,9 +1,13 @@
#include "Network/TCPServer.h"
using namespace boost::asio::ip;
TCPServer::TCPServer()
TCPServer::TCPServer()
{
acceptor = std::unique_ptr<tcp::acceptor>(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666)));
// Make the acceptor non-blocking so we wont get stuck in AcceptNewConnections().
acceptor->non_blocking(true);
m_Port = GetPort();
m_Address = GetAddress();
}
TCPServer::~TCPServer()
@@ -11,14 +15,24 @@ TCPServer::~TCPServer()
void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
{
boost::system::error_code error;
boost::shared_ptr<tcp::socket> newSocket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService));
m_IOService.poll();
acceptor->async_accept(*newSocket,
boost::bind(&TCPServer::handle_accept, this, newSocket, boost::ref(nextPlayerID), boost::ref(connectedPlayers),
boost::asio::placeholders::error));
acceptor->accept(*newSocket, error);
// If no error occured add new tcp connection
if (!error) {
// Add tcp socket to connections
boost::asio::ip::tcp::no_delay option(true);
newSocket->set_option(option);
PlayerDefinition pd;
pd.StopTime = std::clock();
pd.TCPSocket = newSocket;
pd.TCPAddress = newSocket.get()->remote_endpoint().address();
pd.TCPPort = newSocket.get()->remote_endpoint().port();
connectedPlayers[nextPlayerID++] = pd;
}
}
PlayerID GetPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
PlayerID TCPServer::getPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
boost::asio::ip::address address, unsigned short port)
{
for (auto& kv : connectedPlayers) {
@@ -30,24 +44,6 @@ PlayerID GetPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& con
return -1;
}
void TCPServer::handle_accept(boost::shared_ptr<tcp::socket> socket,
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
const boost::system::error_code& error)
{
if (!error && GetPlayerIDFromEndpoint(connectedPlayers, socket->remote_endpoint().address(),
socket->remote_endpoint().port()) == -1) {
// Add tcp socket to connections
boost::asio::ip::tcp::no_delay option(true);
socket->set_option(option);
PlayerDefinition pd;
pd.StopTime = std::clock();
pd.TCPSocket = socket;
pd.TCPAddress = socket.get()->remote_endpoint().address();
pd.TCPPort = socket.get()->remote_endpoint().port();
connectedPlayers[nextPlayerID++] = pd;
}
}
void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition)
{
packet.UpdateSize();
@@ -73,40 +69,21 @@ void TCPServer::Send(Packet & packet)
void TCPServer::Disconnect()
{
}
//void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
//{
// int bytesRead = readBuffer(m_ReadBuffer, playerDefinition);
// if (bytesRead > 0) {
// packet.ReconstructFromData(m_ReadBuffer, bytesRead);
// }
// lastReceivedSocket = playerDefinition.TCPSocket;
//}
//
//int TCPServer::readBuffer(char* data, PlayerDefinition & playerDefinition)
//{
// if (!playerDefinition.TCPSocket) {
// return 0;
// }
// boost::system::error_code error;
// // Read size of packet
// size_t bytesReceived = playerDefinition.TCPSocket->read_some(boost
// ::asio::buffer((void*)data, sizeof(int)),
// error);
// int sizeOfPacket = 0;
// memcpy(&sizeOfPacket, data, sizeof(int));
//
// // Read the rest of the message
// bytesReceived += playerDefinition.TCPSocket->read_some(boost
// ::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
// error);
// if (error) {
// //LOG_ERROR("receive: %s", error.message().c_str());
// }
// return bytesReceived;
//}
int TCPServer::GetPort()
{
return acceptor->local_endpoint().port();
}
std::string TCPServer::GetAddress()
{
boost::asio::ip::tcp::resolver resolver(m_IOService);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), boost::asio::ip::host_name(), "");
boost::asio::ip::tcp::resolver::iterator it = resolver.resolve(query);
boost::asio::ip::tcp::endpoint endpoint = *it;
return endpoint.address().to_string().c_str();
}
void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
{
+14 -14
View File
@@ -15,9 +15,9 @@ void UDPClient::Connect(std::string playerName, std::string address, int port)
if (m_Socket) {
return;
}
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address().from_string(address), port);
m_Socket = boost::shared_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService));
m_Socket->connect(m_ReceiverEndpoint);
m_Socket->open(boost::asio::ip::udp::v4());
}
void UDPClient::Disconnect()
@@ -35,18 +35,6 @@ void UDPClient::Receive(Packet& packet)
int UDPClient::readBuffer()
{
//if (!m_Socket) {
// return 0;
//}
//boost::system::error_code error;
//int bytesReceived = m_Socket->receive_from(boost
// ::asio::buffer((void*)data, BUFFERSIZE),
// m_ReceiverEndpoint,
// 0, error);
//if (error) {
// //LOG_ERROR("receive: %s", error.message().c_str());
//}
//return bytesReceived;
if (!m_Socket) {
return 0;
}
@@ -87,6 +75,18 @@ void UDPClient::Send(Packet& packet)
packet.Data(),
packet.Size()),
m_ReceiverEndpoint, 0);
}
void UDPClient::Broadcast(Packet& packet, int port)
{
packet.UpdateSize();
m_Socket->set_option(boost::asio::socket_base::broadcast(true));
m_Socket->send_to(boost::asio::buffer(
packet.Data(),
packet.Size()),
udp::endpoint(boost::asio::ip::address_v4().broadcast(), port)
, 0);
m_Socket->set_option(boost::asio::socket_base::broadcast(false));
}
bool UDPClient::IsSocketAvailable()
+32 -9
View File
@@ -5,6 +5,11 @@ UDPServer::UDPServer()
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)));
}
UDPServer::UDPServer(int port)
{
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)));
}
UDPServer::~UDPServer()
{ }
@@ -33,6 +38,32 @@ void UDPServer::Send(Packet & packet)
0);
}
// Broadcasting respond specific logic
void UDPServer::Send(Packet & packet, boost::asio::ip::udp::endpoint endpoint)
{
packet.UpdateSize();
m_Socket->send_to(
boost::asio::buffer(
packet.Data(),
packet.Size()),
endpoint,
0);
}
// Broadcasting
void UDPServer::Broadcast(Packet & packet, int port)
{
packet.UpdateSize();
m_Socket->set_option(boost::asio::socket_base::broadcast(true));
m_Socket->send_to(
boost::asio::buffer(
packet.Data(),
packet.Size()),
boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4().broadcast(),port),
0);
m_Socket->set_option(boost::asio::socket_base::broadcast(false));
}
void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
{
int bytesRead = readBuffer();
@@ -49,18 +80,10 @@ bool UDPServer::IsSocketAvailable()
int UDPServer::readBuffer()
{
//boost::system::error_code error = boost::asio::error::host_not_found;
//unsigned int length = m_Socket->receive_from(
// boost::asio::buffer((void*)data
// , BUFFERSIZE)
// , m_ReceiverEndpoint, 0, error);
//if (error) {
// LOG_WARNING(error.message().c_str());
//}
//return length;
if (!m_Socket) {
return 0;
}
int addasdasd = m_Socket->available();
boost::system::error_code error;
// Read size of packet
m_Socket->receive_from(boost
+41
View File
@@ -0,0 +1,41 @@
#include "Rendering/CubeMapPass.h"
CubeMapPass::CubeMapPass(IRenderer* renderer)
:m_Renderer(renderer)
{
LoadTextures("Nevada");
}
void CubeMapPass::LoadTextures(std::string input)
{
if (m_PreviusCubeMapTexture != input) {
m_CubeMapTextures.clear();
for (int i = 0; i < 6; i++) {
std::string str;
str = "Textures/Test/CubeMap/" + input + "/CubeMapTest0" + std::to_string(i) + ".png";
Texture* img = ResourceManager::Load<Texture>(str);
m_CubeMapTextures.push_back(img);
}
GenerateCubeMapTexture();
m_PreviusCubeMapTexture = input;
}
}
void CubeMapPass::GenerateCubeMapTexture()
{
if (m_CubeMapTexture == -1) {
glGenTextures(1, &m_CubeMapTexture);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapTexture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA32F, m_CubeMapTextures[0]->Width, m_CubeMapTextures[0]->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_CubeMapTextures[i]->Data);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
GLERROR("Generate Cubemap");
}
+15 -14
View File
@@ -19,16 +19,20 @@ void DrawBloomPass::InitializeTextures()
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();
if (m_GaussianProgram_horiz->GetHandle() == 0) {
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();
m_GaussianProgram_vert = ResourceManager::Load<ShaderProgram>("##GaussianProgramVert");
if (m_GaussianProgram_vert->GetHandle() == 0) {
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();
}
}
@@ -48,6 +52,7 @@ void DrawBloomPass::InitializeBuffers()
void DrawBloomPass::ClearBuffer()
{
GLERROR("PRE");
m_GaussianFrameBuffer_horiz.Bind();
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -56,6 +61,7 @@ void DrawBloomPass::ClearBuffer()
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GaussianFrameBuffer_vert.Unbind();
GLERROR("END");
}
void DrawBloomPass::Draw(GLuint texture)
@@ -71,15 +77,12 @@ void DrawBloomPass::Draw(GLuint texture)
//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].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
//Iterate some times to make it more gaussian.
for (int i = 1; i < m_iterations; i++) {
//Vertical pass
@@ -92,7 +95,6 @@ void DrawBloomPass::Draw(GLuint texture)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
//horizontal pass
m_GaussianFrameBuffer_horiz.Bind();
@@ -112,7 +114,6 @@ void DrawBloomPass::Draw(GLuint texture)
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].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
+69 -29
View File
@@ -1,10 +1,11 @@
#include "Rendering/DrawFinalPass.h"
DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass)
DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass)
: m_Renderer(renderer)
, m_LightCullingPass(lightCullingPass)
, m_CubeMapPass(cubeMapPass)
{
//TODO: Make sure that uniforms are not sent into shader if not needed.
m_Renderer = renderer;
m_LightCullingPass = lightCullingPass;
m_ShieldPixelRate = 8;
InitializeTextures();
InitializeShaderPrograms();
@@ -27,6 +28,7 @@ void DrawFinalPass::InitializeFrameBuffers()
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
GLERROR("RenderBuffer generation");
GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
//GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
@@ -173,26 +175,28 @@ void DrawFinalPass::InitializeShaderPrograms()
GLERROR("Creating DepthFill program");
}
void DrawFinalPass::Draw(RenderScene& scene)
void DrawFinalPass::Draw(RenderScene& scene, GLuint SSAOTexture)
{
GLERROR("Pre");
DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle());
if (scene.ClearDepth) {
glClear(GL_DEPTH_BUFFER_BIT);
//glClear(GL_DEPTH_BUFFER_BIT);
state->Disable(GL_DEPTH_TEST);
state->DepthMask(GL_FALSE);
}
//TODO: Do we need check for this or will it be per scene always?
glClearStencil(0x00);
glClear(GL_STENCIL_BUFFER_BIT);
//Fill depth buffer
state->StencilMask(0x00);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene, SSAOTexture);
GLERROR("OpaqueObjects");
DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene);
state->BlendFunc(GL_ONE, GL_ONE);
DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene, SSAOTexture);
GLERROR("TransparentObjects");
state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawSprites(scene.Jobs.SpriteJob, scene);
GLERROR("SpriteJobs");
@@ -206,11 +210,11 @@ void DrawFinalPass::Draw(RenderScene& scene)
//Draw Opaque shielded objects
state->StencilFunc(GL_NOTEQUAL, 1, 0xFF);
state->StencilMask(0x00);
DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene); //might need changing
DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene, SSAOTexture); //might need changing
GLERROR("Shielded Opaque object");
//Draw Transparen Shielded objects
DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene); //might need changing
DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene, SSAOTexture); //might need changing
GLERROR("Shielded Transparent objects");
GLERROR("END");
@@ -241,14 +245,14 @@ void DrawFinalPass::Draw(RenderScene& scene)
DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene);
GLERROR("StencilPass");
glClear(GL_DEPTH_BUFFER_BIT);
//glClear(GL_DEPTH_BUFFER_BIT);
stateLowRes->Enable(GL_DEPTH_TEST);
stateLowRes->StencilFunc(GL_LEQUAL, 1, 0xFF);
stateLowRes->StencilMask(0x00);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene, SSAOTexture);
GLERROR("OpaqueObjects");
DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene);
DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene, SSAOTexture);
GLERROR("TransparentObjects");
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
@@ -258,20 +262,35 @@ void DrawFinalPass::Draw(RenderScene& scene)
void DrawFinalPass::ClearBuffer()
{
GLERROR("PRE");
m_FinalPassFrameBufferLowRes.Bind();
GLERROR("Bind LowRes");
glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate);
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
GLERROR("ViewPort,Scissor LowRes");
glClearColor(0.f, 0.f, 0.f, 0.f);
GLERROR("1");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLERROR("2");
glDisable(GL_SCISSOR_TEST);
GLERROR("3");
m_FinalPassFrameBufferLowRes.Unbind();
GLERROR("prebind HighRes");
m_FinalPassFrameBuffer.Bind();
GLERROR("Bind HighRes");
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
GLERROR("ViewPort,Scissor LowRes");
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_FinalPassFrameBuffer.Unbind();
GLERROR("END");
}
@@ -321,7 +340,7 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm:
GLERROR("MipMap Texture initialization failed");
}
void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene)
void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene, GLuint SSAOTexture)
{
GLuint forwardHandle = m_ForwardPlusProgram->GetHandle();
GLERROR("forwardHandle");
@@ -344,6 +363,9 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, SSAOTexture);
for (auto &job : jobs) {
auto explosionEffectJob = std::dynamic_pointer_cast<ExplosionEffectJob>(job);
if (explosionEffectJob) {
@@ -352,12 +374,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
case RawModel::MaterialType::SingleTextures:
{
if (explosionEffectJob->Model->IsSkinned()) {
m_ExplosionEffectSkinnedProgram->Bind();
GLERROR("Bind ExplosionEffectSkinned program");
//bind uniforms
BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene);
//bind textures
BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture);
glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position()));
std::vector<glm::mat4> frameBones;
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
@@ -372,6 +399,10 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
BindExplosionUniforms(explosionHandle, explosionEffectJob, scene);
//bind textures
BindExplosionTextures(explosionHandle, explosionEffectJob);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture);
glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position()));
}
break;
}
@@ -430,6 +461,10 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
BindModelUniforms(forwardSkinnedHandle, modelJob, scene);
//bind textures
BindModelTextures(forwardSkinnedHandle, modelJob);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture);
glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position()));
std::vector<glm::mat4> frameBones;
if (modelJob->AnimationOffset.animation != nullptr) {
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
@@ -445,6 +480,9 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
BindModelUniforms(forwardHandle, modelJob, scene);
//bind textures
BindModelTextures(forwardHandle, modelJob);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture);
glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position()));
}
break;
}
@@ -690,14 +728,14 @@ void DrawFinalPass::DrawSprites(std::list<std::shared_ptr<RenderJob>>&jobs, Rend
glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(spriteJob->FillColor));
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), spriteJob->FillPercentage);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
if (spriteJob->DiffuseTexture != nullptr) {
glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture->m_Texture);
} else {
glBindTexture(GL_TEXTURE_2D, m_ErrorTexture->m_Texture);
}
glActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE2);
if (spriteJob->IncandescenceTexture != nullptr) {
glBindTexture(GL_TEXTURE_2D, spriteJob->IncandescenceTexture->m_Texture);
} else {
@@ -803,11 +841,13 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr<Model
void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptr<ExplosionEffectJob>& job)
{
switch (job->Type) {
case RawModel::MaterialType::SingleTextures:
case RawModel::MaterialType::Basic:
{
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(job->DiffuseTexture[0]->UVRepeat));
@@ -817,7 +857,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptr<E
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
glActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE2);
if (job->NormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(job->NormalTexture[0]->UVRepeat));
@@ -827,7 +867,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptr<E
glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
glActiveTexture(GL_TEXTURE2);
glActiveTexture(GL_TEXTURE3);
if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(job->SpecularTexture[0]->UVRepeat));
@@ -837,7 +877,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptr<E
glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
glActiveTexture(GL_TEXTURE3);
glActiveTexture(GL_TEXTURE4);
if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(job->IncandescenceTexture[0]->UVRepeat));
@@ -850,7 +890,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptr<E
}
case RawModel::MaterialType::SplatMapping:
{
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, job->SplatMap->Texture->m_Texture);
int texturePosition = GL_TEXTURE1;
@@ -925,7 +965,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr<Model
case RawModel::MaterialType::SingleTextures:
case RawModel::MaterialType::Basic:
{
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(job->DiffuseTexture[0]->UVRepeat));
@@ -935,7 +975,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr<Model
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
glActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE2);
if (job->NormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(job->NormalTexture[0]->UVRepeat));
@@ -945,7 +985,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr<Model
glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
glActiveTexture(GL_TEXTURE2);
glActiveTexture(GL_TEXTURE3);
if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(job->SpecularTexture[0]->UVRepeat));
@@ -955,7 +995,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr<Model
glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
glActiveTexture(GL_TEXTURE3);
glActiveTexture(GL_TEXTURE4);
if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(job->IncandescenceTexture[0]->UVRepeat));
@@ -968,10 +1008,10 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr<Model
}
case RawModel::MaterialType::SplatMapping:
{
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, job->SplatMap->Texture->m_Texture);
int texturePosition = GL_TEXTURE1;
int texturePosition = GL_TEXTURE2;
//Bind 5 diffuse textures
std::string UniformName = "DiffuseUVRepeat";
+10 -8
View File
@@ -21,15 +21,14 @@ void PickingPass::InitializeTextures()
{
GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR,
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST,
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
}
void PickingPass::InitializeFrameBuffers()
{
glGenRenderbuffers(1, &m_DepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
m_PickingBuffer.Generate();
}
@@ -55,6 +54,7 @@ void PickingPass::InitializeShaderPrograms()
void PickingPass::Draw(RenderScene& scene)
{
GLERROR("PRE");
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
//TODO: Render: Add code for more jobs than modeljobs.
@@ -63,7 +63,9 @@ void PickingPass::Draw(RenderScene& scene)
m_PickingProgram->Bind();
if (scene.ClearDepth) {
glClear(GL_DEPTH_BUFFER_BIT);
//glClear(GL_DEPTH_BUFFER_BIT);
state->Disable(GL_DEPTH_TEST);
state->DepthMask(GL_FALSE);
}
m_Camera = scene.Camera;
@@ -356,6 +358,7 @@ void PickingPass::Draw(RenderScene& scene)
void PickingPass::ClearPicking()
{
GLERROR("PRE");
m_PickingColorsToEntity.clear();
m_EntityColors.clear();
m_ColorCounter[0] = 0;
@@ -365,14 +368,13 @@ void PickingPass::ClearPicking()
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_PickingBuffer.Unbind();
GLERROR("END");
}
void PickingPass::OnWindowResize()
{
InitializeTextures();
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
m_PickingBuffer.Generate();
}
+3 -2
View File
@@ -3,9 +3,9 @@
PickingPassState::PickingPassState(GLuint frameBuffer)
{
GLERROR("---2");
GLERROR("PRE");
BindFramebuffer(frameBuffer);
GLERROR("---3");
GLERROR("Bind Framebuffer");
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
Disable(GL_BLEND);
@@ -13,6 +13,7 @@ PickingPassState::PickingPassState(GLuint frameBuffer)
glm::vec4 clearColor = glm::vec4(0.f);
//ClearColor(clearColor);
//Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLERROR("END");
}
PickingPassState::~PickingPassState()
+96 -6
View File
@@ -52,6 +52,101 @@ void RenderSystem::fillSprites(std::list<std::shared_ptr<RenderJob>>& jobs, Worl
continue;
}
glm::mat4 modelMatrix;
// See a sprite is an SpriteIndicator
bool isIndicator = false;
if (world->HasComponent(entity.ID, "SpriteIndicator"))
{
auto indicator = entity["SpriteIndicator"];
float minScale = (float)(double)indicator["MinScale"];
bool hasTeam = indicator["VisibleForSingleTeamOnly"];
isIndicator = true;
glm::vec3 pos = Transform::AbsolutePosition(entity);
EntityWrapper entityTeam;
if (hasTeam && (entity.HasComponent("Team") || entity.FirstParentWithComponent("Team").Valid()) && m_LocalPlayer.World != nullptr) {
if (!entity.HasComponent("Team")) {
entityTeam = entity.FirstParentWithComponent("Team");
}
else {
entityTeam = entity;
}
ComponentWrapper& entityTeamComponent = entityTeam["Team"];
ComponentWrapper& localComponent = m_LocalPlayer["Team"];
int entityTeamInt = entityTeamComponent["Team"];
int localComponentInt = localComponent["Team"];
int SpectatorInt = localComponent["Team"].Enum("Spectator");
if (entityTeamInt != localComponentInt && localComponentInt != SpectatorInt) {
continue;
}
}
// Code for check if sprite is inside or outside of screen
//glm::vec4 projectedPos = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * glm::vec4(pos, 1.0f);
//projectedPos /= projectedPos.w;
//// Check if inside of outside of screen.
//if (projectedPos.x < -1.0f || projectedPos.x > 1.0f || projectedPos.y < -1.0f || projectedPos.y > 1.0f) {
// // is outside of screen
//} else {
// // is inside of screen
//}
glm::vec3 zAxis = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 normal = pos - m_Camera->Position();
//float distance = glm::length(normal);
//if (distance < minDistance) {
// pos = pos - glm::normalize(normal) * (distance - minDistance);
//} else if (distance > maxDistance) {
// pos = pos - glm::normalize(normal) * (distance - maxDistance);
//}
normal.y = 0;
normal = glm::normalize(normal);
glm::vec3 right = glm::cross(normal, zAxis);
glm::vec3 up = glm::cross(right, normal);
modelMatrix[0][0] = right.x;
modelMatrix[0][1] = right.y;
modelMatrix[0][2] = right.z;
modelMatrix[0][3] = 0.0f;
modelMatrix[1][0] = zAxis.x;
modelMatrix[1][1] = zAxis.y;
modelMatrix[1][2] = zAxis.z;
modelMatrix[1][3] = 0.0f;
modelMatrix[2][0] = normal.x;
modelMatrix[2][1] = normal.y;
modelMatrix[2][2] = normal.z;
modelMatrix[2][3] = 0.0f;
modelMatrix[3][0] = pos.x;
modelMatrix[3][1] = pos.y;
modelMatrix[3][2] = pos.z;
modelMatrix[3][3] = 1.0f;
glm::mat4 tranformationMatrix = modelMatrix * glm::scale(Transform::AbsoluteScale(entity));
glm::vec4 tmp = tranformationMatrix * glm::vec4(glm::vec3(0.5, 0.5, 0), 1.0f);
glm::vec2 projectedTopRight = m_Camera->WorldToScreen(glm::vec3(tmp), m_Renderer->GetViewportSize());
tmp = tranformationMatrix * glm::vec4(glm::vec3(-0.5, -0.5, 0), 1.0f);
glm::vec2 projectedBottomLeft = m_Camera->WorldToScreen(glm::vec3(tmp), m_Renderer->GetViewportSize());
float diag = glm::length(projectedBottomLeft - projectedTopRight);
if (diag < minScale) {
tranformationMatrix = tranformationMatrix * glm::scale(glm::vec3(minScale / diag, minScale / diag, minScale / diag));
}
modelMatrix = tranformationMatrix;
}
else {
modelMatrix = Transform::ModelMatrix(entity.ID, world);
}
std::string diffuseResource = cSprite["DiffuseTexture"];
std::string glowResource = cSprite["GlowMap"];
bool depthSorted = cSprite["DepthSort"];
@@ -67,11 +162,7 @@ void RenderSystem::fillSprites(std::list<std::shared_ptr<RenderJob>>& jobs, Worl
fillColor = (glm::vec4)fillComponent["Color"];
}
glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, world);
//modelMatrix *= m_Camera->BillboardMatrix();
std::shared_ptr<SpriteJob> spriteJob = std::shared_ptr<SpriteJob>(new SpriteJob(cSprite, m_Camera, modelMatrix, world, fillColor, fillPercentage, depthSorted));
std::shared_ptr<SpriteJob> spriteJob = std::shared_ptr<SpriteJob>(new SpriteJob(cSprite, m_Camera, modelMatrix, world, fillColor, fillPercentage, depthSorted, isIndicator));
jobs.push_back(spriteJob);
}
@@ -93,7 +184,6 @@ bool RenderSystem::isEntityVisible(EntityWrapper& entity)
) {
return false;
}
return true;
}
+42 -12
View File
@@ -30,6 +30,7 @@ void Renderer::glfwFrameBufferCallback(GLFWwindow* window, int width, int height
currentRenderer->m_LightCullingPass->OnWindowResize();
currentRenderer->m_PickingPass->OnWindowResize();
currentRenderer->m_DrawBloomPass->OnWindowResize();
currentRenderer->m_SSAOPass->OnWindowResize();
}
void Renderer::InitializeWindow()
@@ -88,9 +89,6 @@ void Renderer::InitializeShaders()
//m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/ExplosionEffect.frag.glsl")));
//m_ExplosionEffectProgram->Compile();
//m_ExplosionEffectProgram->Link();
}
void Renderer::InputUpdate(double dt)
@@ -108,7 +106,23 @@ void Renderer::Update(double dt)
void Renderer::Draw(RenderFrame& frame)
{
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking");
GLERROR("PRE");
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking\0Ambient Occlusion");
ImGui::Combo("CubeMap", &m_CubeMapTexture, "Nevada(512)\0Sky(1024)");
if(m_CubeMapTexture == 0) {
m_CubeMapPass->LoadTextures("Nevada");
} else if (m_CubeMapTexture == 1) {
m_CubeMapPass->LoadTextures("Sky");
}
ImGui::SliderFloat("SSAO sample radius", &m_SSAO_Radius, 0.01f, 5.0f);
ImGui::SliderFloat("SSAO bias", &m_SSAO_Bias, 0.0f, 0.1f);
ImGui::SliderFloat("SSAO contrast", &m_SSAO_Contrast, 0.0f, 10.0f);
ImGui::SliderFloat("SSAO IntensityScale", &m_SSAO_IntensityScale, 0.0f, 10.0f);
ImGui::SliderInt("SSAO Number of Samples", &m_SSAO_NumOfSamples, 2, 100);
ImGui::SliderInt("SSAO Number of Turns", &m_SSAO_NumOfTurns, 0, 50);
m_SSAOPass->Setting(m_SSAO_Radius, m_SSAO_Bias, m_SSAO_Contrast, m_SSAO_IntensityScale, m_SSAO_NumOfSamples, m_SSAO_NumOfTurns);
GLERROR("SSAO Settings");
//clear buffer 0
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -118,16 +132,24 @@ void Renderer::Draw(RenderFrame& frame)
m_PickingPass->ClearPicking();
m_DrawFinalPass->ClearBuffer();
m_DrawBloomPass->ClearBuffer();
m_SSAOPass->ClearBuffer();
PerformanceTimer::StopTimer("Renderer-ClearBuffers");
GLERROR("ClearBuffers");
for (auto scene : frame.RenderScenes) {
PerformanceTimer::StartTimer("Renderer-Depth");
m_PickingPass->Draw(*scene);
GLERROR("Drawing pickingpass");
PerformanceTimer::StopTimer("Renderer-Depth");
}
PerformanceTimer::StartTimer("AO generation");
m_SSAOPass->Draw(m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera);
GLuint ao = m_SSAOPass->SSAOTexture();
PerformanceTimer::StopTimer("AO generation");
for (auto scene : frame.RenderScenes){
PerformanceTimer::StartTimer("Renderer-Depth");
PerformanceTimer::StartTimer("Renderer-Drawing PickingPass");
SortRenderJobsByDepth(*scene);
GLERROR("SortByDepth");
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Drawing PickingPass");
m_PickingPass->Draw(*scene);
GLERROR("Drawing pickingpass");
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums");
m_LightCullingPass->GenerateNewFrustum(*scene);
GLERROR("Generate frustums");
@@ -137,8 +159,8 @@ void Renderer::Draw(RenderFrame& frame)
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Light Culling");
m_LightCullingPass->CullLights(*scene);
GLERROR("LightCulling");
m_DrawFinalPass->Draw(*scene, ao);
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light");
m_DrawFinalPass->Draw(*scene);
GLERROR("Draw Geometry+Light");
//m_DrawScenePass->Draw(*scene);
@@ -147,14 +169,17 @@ void Renderer::Draw(RenderFrame& frame)
GLERROR("Draw Text");
PerformanceTimer::StopTimer("Renderer-Draw Text");
}
PerformanceTimer::StartTimer("Renderer-Draw Bloom");
m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture());
PerformanceTimer::StopTimer("Renderer-Draw Bloom");
if (m_DebugTextureToDraw == 0) {
PerformanceTimer::StartTimer("Renderer-Color Correction Pass");
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure);
PerformanceTimer::StopTimer("Renderer-Color Correction Pass");
}
PerformanceTimer::StartTimer("Renderer-Misc Debug Draws");
if (m_DebugTextureToDraw == 1) {
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture());
@@ -174,7 +199,10 @@ void Renderer::Draw(RenderFrame& frame)
if (m_DebugTextureToDraw == 6) {
m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture());
}
PerformanceTimer::StopTimer("Renderer-Misc Debug Draws");
if (m_DebugTextureToDraw == 7) {
m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture());
}
PerformanceTimer::StopTimer("Renderer-Misc Debug Draws");
PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass");
m_ImGuiRenderPass->Draw();
@@ -219,8 +247,10 @@ void Renderer::InitializeRenderPasses()
{
m_PickingPass = new PickingPass(this, m_EventBroker);
m_LightCullingPass = new LightCullingPass(this);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass);
m_CubeMapPass = new CubeMapPass(this);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass);
m_DrawScreenQuadPass = new DrawScreenQuadPass(this);
m_DrawBloomPass = new DrawBloomPass(this);
m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this);
m_SSAOPass = new SSAOPass(this);
}
+145
View File
@@ -0,0 +1,145 @@
#include "Rendering/SSAOPass.h"
SSAOPass::SSAOPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
InitializeTexture();
InitializeBuffer();
InitializeShaderProgram();
Setting(0.1f, 0.012f, 1.0f, 1.0f, 13, 7);
m_DrawBloomPass = new DrawBloomPass(renderer);
}
void SSAOPass::InitializeShaderProgram()
{
m_SSAOProgram = ResourceManager::Load<ShaderProgram>("##SSAOProgram");
m_SSAOProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/SSAO.vert.glsl")));
m_SSAOProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/SSAO.frag.glsl")));
m_SSAOProgram->Compile();
m_SSAOProgram->Link();
m_SSAOViewSpaceZProgram = ResourceManager::Load<ShaderProgram>("##SSAOViewSpaceZProgram");
m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/SSAO.vert.glsl")));
m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/SSAOViewSpaceZ.frag.glsl")));
m_SSAOViewSpaceZProgram->Compile();
m_SSAOViewSpaceZProgram->Link();
}
void SSAOPass::InitializeTexture() {
GenerateTexture(&m_SSAOTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_R8, GL_RED, GL_FLOAT);
GenerateTexture(&m_SSAOViewSpaceZTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_R32F, GL_RED, GL_FLOAT);
}
void SSAOPass::InitializeBuffer()
{
m_SSAOFramBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SSAOTexture, GL_COLOR_ATTACHMENT0)));
m_SSAOFramBuffer.Generate();
m_SSAOViewSpaceZFramBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SSAOViewSpaceZTexture, GL_COLOR_ATTACHMENT0)));
m_SSAOViewSpaceZFramBuffer.Generate();
}
void SSAOPass::ClearBuffer()
{
m_SSAOFramBuffer.Bind();
glClearColor(1.f, 1.f, 1.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_SSAOFramBuffer.Unbind();
m_SSAOViewSpaceZFramBuffer.Bind();
glClearColor(1.f, 1.f, 1.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_SSAOViewSpaceZFramBuffer.Unbind();
}
void SSAOPass::Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns) {
m_Radius = radius;
m_Bias = bias;
m_Contrast = contrast;
m_IntensityScale = intensityScale;
m_NumOfSamples = numOfSamples;
m_NumOfTurns = NumOfTurns;
}
void SSAOPass::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);
GLERROR("Texture initialization failed");
}
void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
{
SSAOPassState state;
GLuint viewSpaceZPShaderHandle = m_SSAOViewSpaceZProgram->GetHandle();
GLuint SSAOShaderHandle = m_SSAOProgram->GetHandle();
m_SSAOViewSpaceZFramBuffer.Bind();
m_SSAOViewSpaceZProgram->Bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthBuffer);
glm::vec3 clipInfo = glm::vec3(
(camera->NearClip() * camera->FarClip()),
(camera->NearClip() - camera->FarClip()),
(camera->FarClip())
);
/*glm::vec3 clipInfo = glm::vec3(
(camera->NearClip()),
(-1.0f),
(+1.0f)
);*/
glUniform3fv(glGetUniformLocation(viewSpaceZPShaderHandle, "ClipInfo"), 1, glm::value_ptr(clipInfo));
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
glm::vec4 projInfo = glm::vec4(
((1.0 - camera->ProjectionMatrix()[0][2]) / camera->ProjectionMatrix()[0][0]),
(-2.0 / (m_Renderer->GetViewportSize().Width * camera->ProjectionMatrix()[0][0])),
((1.0 + camera->ProjectionMatrix()[1][2]) / camera->ProjectionMatrix()[1][1]),
(-2.0 / (m_Renderer->GetViewportSize().Height * camera->ProjectionMatrix()[1][1]))
);
m_SSAOFramBuffer.Bind();
m_SSAOProgram->Bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_SSAOViewSpaceZTexture);
// How many pixel there are in a 1m long object 1m away from the camera
glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uProjScale"), m_Renderer->GetViewportSize().Height / (-2.0f * glm::tan(camera->FOV() * 0.5f)));
glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uRadius"), m_Radius);
glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uBias"), m_Bias);
glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uContrast"), m_Contrast);
glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uIntensityScale"), m_IntensityScale);
glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfSamples"), m_NumOfSamples);
glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfTurns"), m_NumOfTurns);;
glUniform4fv(glGetUniformLocation(SSAOShaderHandle, "uProjInfo"), 1, glm::value_ptr(projInfo));
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
m_DrawBloomPass->ClearBuffer();
m_DrawBloomPass->Draw(m_SSAOTexture);
}
void SSAOPass::OnWindowResize() {
m_DrawBloomPass->OnWindowResize();
InitializeTexture();
m_SSAOFramBuffer.Generate();
m_SSAOViewSpaceZFramBuffer.Generate();
}
+16
View File
@@ -0,0 +1,16 @@
#include "Rendering/SSAOPassState.h"
SSAOPassState::SSAOPassState()
{
//BindFramebuffer(0);
Disable(GL_BLEND);
Disable(GL_DEPTH_TEST);
Disable(GL_CULL_FACE);
}
SSAOPassState::~SSAOPassState()
{
}
+1 -2
View File
@@ -98,8 +98,7 @@ void ShaderProgram::AddShader(std::shared_ptr<Shader> shader)
void ShaderProgram::Compile()
{
if (m_ShaderProgramHandle == 0)
{
if (m_ShaderProgramHandle == 0) {
m_ShaderProgramHandle = glCreateProgram();
}
+2
View File
@@ -18,6 +18,7 @@ Texture::Texture(std::string path)
this->Width = img->Width;
this->Height = img->Height;
this->Data = img->Data;
GLint format;
switch (img->Format) {
@@ -28,6 +29,7 @@ Texture::Texture(std::string path)
format = GL_RGBA;
break;
}
// Construct the OpenGL texture
glGenTextures(1, &m_Texture);
+3 -2
View File
@@ -29,6 +29,7 @@ void AmmoPickupSystem::Update(double dt)
newAmmoPickupEntity["Transform"]["Position"] = ammoPickupPosition.Pos;
newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = ammoPickupPosition.AmmoGain;
newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = ammoPickupPosition.RespawnTimer;
m_World->SetParent(newAmmoPickupEntity.ID, ammoPickupPosition.parentID);
//erase the current element (AmmoPickupPosition)
m_ETriggerTouchVector.erase(it);
@@ -69,8 +70,8 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
//copy position, ammogain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object)
//we need to copy all values since each value can be different for each ammoPickup
m_ETriggerTouchVector.push_back({ (glm::vec3)e.Trigger["Transform"]["Position"] ,e.Trigger["AmmoPickup"]["AmmoGain"],
e.Trigger["AmmoPickup"]["RespawnTimer"],e.Trigger["AmmoPickup"]["RespawnTimer"] });
m_ETriggerTouchVector.push_back({ e.Trigger["Transform"]["Position"], e.Trigger["AmmoPickup"]["AmmoGain"],
e.Trigger["AmmoPickup"]["RespawnTimer"], e.Trigger["AmmoPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) });
//delete the ammopickup
m_World->DeleteEntity(e.Trigger.ID);
+21 -22
View File
@@ -1,32 +1,39 @@
#include "Systems/CapturePointSystem.h"
#include <algorithm>
CapturePointSystem::CapturePointSystem(SystemParams params)
CapturePointSystem::CapturePointSystem(SystemParams params)
: System(params)
, PureSystem("CapturePoint")
{
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
if (IsClient) {
if (!IsClient) {
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
}
}
//here all capturepoints will update their component
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
{
if (!IsClient) {
if (IsClient) {
return;
}
if (m_WinnerWasFound) {
return;
}
const int capturePointNumber = cCapturePoint["CapturePointNumber"];
const bool hasTeamComponent = capturePointEntity.HasComponent("Team");
if (m_NumberOfCapturePoints != 0) {
if (!m_CapturePointNumberToEntityMap[0].HasComponent("CapturePoint")) {
//if map has changed, the capturepoints has changed, now have to redo them
m_NumberOfCapturePoints = 0;
m_CapturePointNumberToEntityMap.clear();
}
}
//if point doesnt have a teamComponent yet, add one. since:
//what if capture point has no team -> we cant get/use the team enum from it...
if (!hasTeamComponent) {
@@ -71,8 +78,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
std::map<std::string, int> nextPossibleCapturePoint;
nextPossibleCapturePoint["Red"] = -1;
nextPossibleCapturePoint["Blue"] = -1;
for (int i = 0; i < m_NumberOfCapturePoints; i++)
{
for (int i = 0; i < m_NumberOfCapturePoints; i++) {
if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) {
continue;
}
@@ -84,8 +90,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
nextPossibleCapturePoint["Blue"] = i + 1;
}
}
for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--)
{
for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--) {
if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) {
continue;
}
@@ -100,8 +105,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
//reset timers and reset the bool that triggers this
if (m_ResetTimers) {
for (int i = 0; i < m_NumberOfCapturePoints; i++)
{
for (int i = 0; i < m_NumberOfCapturePoints; i++) {
ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"];
if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] &&
(int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) {
@@ -116,8 +120,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
}
//check how many players are standing inside and are healthy
for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--)
{
for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--) {
auto triggerTouched = m_ETriggerTouchVector[i - 1];
if (std::get<1>(triggerTouched) == capturePointEntity) {
//some player has touched this - lets figure out: what team, health
@@ -176,8 +179,8 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange;
}
//if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0
if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < 0.0) ||
(ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > 0.0)) {
if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < captureTimeToTakeOver) ||
(ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > -captureTimeToTakeOver)) {
cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange;
}
//check if captureTimer > captureTimeToTakeOver and if so change owner and publish the eCaptured event
@@ -195,17 +198,14 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
//check for possible winCondition = check if the homebase is owned by the other team
bool checkForWinner = false;
if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam)
{
if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam) {
checkForWinner = true;
}
if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam)
{
if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam) {
checkForWinner = true;
}
if (checkForWinner && !m_WinnerWasFound)
{
if (checkForWinner && !m_WinnerWasFound) {
//publish Win event
Events::Win e;
e.TeamThatWon = ownedBy;
@@ -224,8 +224,7 @@ bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e)
bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e)
{
for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++)
{
for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++) {
auto triggerTouched = m_ETriggerTouchVector[i];
if (std::get<0>(triggerTouched) == e.Entity && std::get<1>(triggerTouched) == e.Trigger) {
m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i);
+104 -31
View File
@@ -12,51 +12,41 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params)
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DamageIndicator.xml");
}
void DamageIndicatorSystem::Update(double dt) {
if (!IsServer) {
for (auto& iter = updateDamageIndicatorVector.begin(); iter != updateDamageIndicatorVector.end(); iter++) {
if (!iter->spriteEntity.Valid()) {
updateDamageIndicatorVector.erase(iter);
break;
}
auto angleBetweenVectors = CalculateAngle(LocalPlayer, iter->enemyPosition);
//simply set the rotation z-wise to the angleBetweenVectors
iter->spriteEntity["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors);
}
}
}
bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
{
if (m_CurrentCamera == EntityID_Invalid) {
return false;
}
//if (e.Victim != LocalPlayer) {
// return false;
//}
if (e.Victim.Valid() && e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) {
return false;
}
if (!e.Inflictor.Valid() || !e.Victim.Valid()) {
return false;
return false;
}
//grab players direction
auto playerOrientation = glm::quat((glm::vec3)e.Victim["Transform"]["Orientation"]);
glm::vec3 inflictorPos = e.Inflictor["Transform"]["Position"];
//if testing
#ifdef INDICATOR_TEST
inflictorPos = DamageIndicatorTest(e.Victim);
#endif
//get the position vectors, but ignore the y-height
auto enemyPosition = (glm::vec3)e.Inflictor["Transform"]["Position"];
auto playerPosition = (glm::vec3)e.Victim["Transform"]["Position"];
enemyPosition.y = 0.0f;
playerPosition.y = 0.0f;
//calculate the enemy to player vector
auto enemyPlayerVector = glm::normalize(playerPosition - enemyPosition);
//get angle from players current rotation, this angle is how much you rotate around the y-axis
auto playerAngle = glm::angle(playerOrientation);
auto playerRotationVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle));
//dot product of players direction-vector and enemys-to-playervector will give the cos of the angle between the vectors
auto playerRotationDot = glm::dot(playerRotationVector, enemyPlayerVector);
//to get the angle between the vectors just do cos-inverse
auto angleBetweenVectors = glm::acos(playerRotationDot);
//rotate the direction-vector 90 degrees to get the players side-vector
auto playerSideVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle + 1.57f));
//dot of sidevector positive = enemy is on the right side, dot sidevector negative = left side
auto playerSideVectorDot = glm::dot(playerSideVector, enemyPlayerVector);
if (playerSideVectorDot < 0) {
angleBetweenVectors = -angleBetweenVectors;
}
float angleBetweenVectors = CalculateAngle(e.Victim, inflictorPos);
//load & set the "2d" sprite
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DamageIndicator.xml");
@@ -67,6 +57,10 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
//simply set the rotation z-wise to the angleBetweenVectors
spriteWrapper["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors);
if (!IsServer) {
updateDamageIndicatorVector.emplace_back(spriteWrapper, inflictorPos);
}
return true;
}
@@ -74,3 +68,82 @@ bool DamageIndicatorSystem::OnSetCamera(const Events::SetCamera& e) {
m_CurrentCamera = e.CameraEntity.ID;
return true;
}
float DamageIndicatorSystem::CalculateAngle(EntityWrapper player, glm::vec3 enemyPos) {
//grab players direction
auto playerOrientation = glm::quat((glm::vec3)player["Transform"]["Orientation"]);
//get the position vectors, but ignore the y-height
auto enemyPosition = enemyPos;
auto playerPosition = (glm::vec3)player["Transform"]["Position"];
enemyPosition.y = 0.0f;
playerPosition.y = 0.0f;
//calculate the enemy to player vector
auto enemyPlayerVector = glm::normalize(playerPosition - enemyPosition);
//get the rotationvector relative to the z-axis
auto rotationVectorVec3 = glm::vec3(glm::toMat4(Transform::AbsoluteOrientation(player))*glm::vec4(0, 0, 1, 0));
//rotate the direction-vector 90 degrees to get the players side-vector
auto playerSideVector = glm::vec3(glm::rotateY(rotationVectorVec3, 1.57f));
//dot product of players direction-vector and enemys-to-playervector will give the cos of the angle between the vectors
auto playerRotationDot = glm::dot(rotationVectorVec3, enemyPlayerVector);
//to get the angle between the vectors just do cos-inverse
auto angleBetweenVectors = glm::acos(playerRotationDot);
//dot of sidevector positive = enemy is on the right side, dot sidevector negative = left side
auto playerSideVectorDot = glm::dot(playerSideVector, enemyPlayerVector);
if (playerSideVectorDot < 0) {
angleBetweenVectors = -angleBetweenVectors;
}
return angleBetweenVectors;
}
#ifdef INDICATOR_TEST
glm::vec3 DamageIndicatorSystem::DamageIndicatorTest(EntityWrapper player) {
auto currentPos = (glm::vec3)player["Transform"]["Position"];
auto testVar = 1;
auto testVar2 = 1;
if (m_TestVar % 4 == 0) {
testVar = -1;
testVar2 = 1;
}
if (m_TestVar % 4 == 1) {
testVar = 1;
testVar2 = 1;
}
if (m_TestVar % 4 == 2) {
testVar *= -1;
testVar2 = -1;
}
if (m_TestVar % 4 == 3) {
testVar = 1;
testVar2 = -1;
}
m_TestVar++;
auto inflictorPos = glm::vec3(currentPos.x + testVar*6.0f, currentPos.y, currentPos.z + testVar2*6.0f);
//load the explosioneffect XML
auto deathEffect = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityFileParser parser(deathEffect);
EntityID deathEffectID = parser.MergeEntities(m_World);
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
//components that we need from player
auto playerModel = player.FirstChildByName("PlayerModel");
auto playerEntityModel = playerModel["Model"];
auto playerEntityAnimation = playerModel["Animation"];
//copy the data from player to explosioneffectmodel
playerEntityModel.Copy(deathEffectEW["Model"]);
playerEntityAnimation.Copy(deathEffectEW["Animation"]);
//copy the models position,orientation
deathEffectEW["Transform"]["Position"] = inflictorPos;
deathEffectEW["Transform"]["Orientation"] = (glm::vec3)player["Transform"]["Orientation"];
return inflictorPos;
}
#endif
+2 -1
View File
@@ -29,6 +29,7 @@ void PickupSpawnSystem::Update(double dt)
newHealthPickupEntity["Transform"]["Position"] = healthPickupPosition.Pos;
newHealthPickupEntity["HealthPickup"]["HealthGain"] = healthPickupPosition.HealthGain;
newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = healthPickupPosition.RespawnTimer;
m_World->SetParent(newHealthPickupEntity.ID, healthPickupPosition.parentID);
//erase the current element (healthPickupPosition)
m_ETriggerTouchVector.erase(it);
@@ -58,7 +59,7 @@ bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e)
//copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object)
//we need to copy all values since each value can be different for each healthPickup
m_ETriggerTouchVector.push_back({ (glm::vec3)e.Trigger["Transform"]["Position"] ,e.Trigger["HealthPickup"]["HealthGain"],
e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"] });
e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) });
//delete the healthpickup
m_World->DeleteEntity(e.Trigger.ID);
+2 -3
View File
@@ -33,9 +33,8 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
//components that we need from player
auto playerCamera = player.FirstChildByName("Camera");
auto playerModel = player.FirstChildByName("PlayerModel");
if (!playerCamera.Valid() || !playerModel.Valid()) {
if (!playerModel.Valid()) {
return;
}
if (!playerModel.HasComponent("Model") || !playerModel.HasComponent("Animation")) {
@@ -44,7 +43,7 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
auto playerEntityModel = playerModel["Model"];
auto playerEntityAnimation = playerModel["Animation"];
//copy the data from player to explisioneffectmodel
//copy the data from player to explosioneffectmodel
playerEntityModel.Copy(deathEffectEW["Model"]);
playerEntityAnimation.Copy(deathEffectEW["Animation"]);
//freeze the animation
+40 -14
View File
@@ -4,6 +4,7 @@ PlayerMovementSystem::PlayerMovementSystem(SystemParams params)
: System(params)
{
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump);
}
PlayerMovementSystem::~PlayerMovementSystem()
@@ -16,7 +17,15 @@ PlayerMovementSystem::~PlayerMovementSystem()
void PlayerMovementSystem::Update(double dt)
{
updateMovementControllers(dt);
updateVelocity(dt);
if (IsServer) {
for (auto& kv : m_PlayerInputControllers) {
updateVelocity(kv.first, dt);
}
} else {
if (LocalPlayer.Valid()) {
updateVelocity(LocalPlayer, dt);
}
}
}
void PlayerMovementSystem::updateMovementControllers(double dt)
@@ -28,7 +37,6 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
if (!player.Valid()) {
continue;
}
// Aim pitch
EntityWrapper cameraEntity = player.FirstChildByName("Camera");
if (cameraEntity.Valid()) {
@@ -114,15 +122,14 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
if (isOnGround) {
controller->SetDoubleJumping(false);
} else {
// If IsServer and network is off this will not work
if (IsClient) {
//put a hexagon at the players feet
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityFileParser parser(hexagonEffect);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
spawnHexagon(player);
controller->SetDoubleJumping(true);
// Publish event for client to listen to
Events::DoubleJump e;
e.entityID = player.ID;
m_EventBroker->Publish(e);
}
}
@@ -221,15 +228,11 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
}
void PlayerMovementSystem::updateVelocity(double dt)
void PlayerMovementSystem::updateVelocity(EntityWrapper player, double dt)
{
// Only apply velocity to local player
if (!LocalPlayer.Valid()) {
return;
}
ComponentWrapper& cTransform = LocalPlayer["Transform"];
ComponentWrapper& cPhysics = LocalPlayer["Physics"];
ComponentWrapper& cTransform = player["Transform"];
ComponentWrapper& cPhysics = player["Physics"];
glm::vec3& velocity = cPhysics["Velocity"];
bool isOnGround = (bool)cPhysics["IsOnGround"];
@@ -291,3 +294,26 @@ bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
}
return true;
}
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e)
{
// If entity does not exist, exit
if (!EntityWrapper(m_World, e.entityID).Valid()) {
return false;
}
// If entity IsLocalPlayer, exit
if (e.entityID == m_LocalPlayer.ID) {
return false;
}
spawnHexagon(EntityWrapper(m_World, e.entityID));
}
void PlayerMovementSystem::spawnHexagon(EntityWrapper target)
{
//put a hexagon at the entitys... feet?
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityFileParser parser(hexagonEffect);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
hexagonEW["Transform"]["Position"] = (glm::vec3)target["Transform"]["Position"];
}
+20 -3
View File
@@ -14,6 +14,7 @@ SoundSystem::SoundSystem(SystemParams params)
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDeath, &SoundSystem::OnPlayerDeath);
}
}
@@ -90,6 +91,9 @@ bool SoundSystem::drumTimer(double dt)
bool SoundSystem::OnCaptured(const Events::Captured & e)
{
if (!LocalPlayer.Valid()) {
return false;
}
int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"];
int team = (int)m_World->GetComponent(LocalPlayer.ID, "Team")["Team"];
Events::PlaySoundOnEntity ev;
@@ -108,7 +112,12 @@ bool SoundSystem::OnCaptured(const Events::Captured & e)
// Testing purposes atm...
bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e)
{
// Should check for only local players here...
if (!IsClient) { // Only play for clients
return false;
}
if (LocalPlayer.ID = e.Victim.ID) { // You're local player was the one who took dmg
return false;
}
std::uniform_int_distribution<int> dist(1, 12);
int rand = dist(generator);
std::vector<std::string> paths;
@@ -128,8 +137,16 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e)
bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e)
{
Events::PlaySoundOnEntity ev;
ev.EmitterID = LocalPlayer.ID;
if (e.Player.ID != LocalPlayer.ID) {
return false;
}
if (!IsClient) {
return false;
}
// The local player is dead. The local player might be invalid?
// Play the sound from the listener.
// TODO: We might want to hear other players die.
Events::PlayBackgroundMusic ev;
ev.FilePath = "Audio/die/die2.wav";
m_EventBroker->Publish(ev);
return false;
+1 -1
View File
@@ -36,7 +36,7 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
}
// Find any SpawnPoints existing as children of spawner
auto children = spawner.World->GetChildren(spawner.ID);
auto children = spawner.World->GetDirectChildren(spawner.ID);
std::vector<EntityWrapper> spawnPoints;
for (auto kv = children.first; kv != children.second; ++kv) {
const EntityID& child = kv->second;
-1
View File
@@ -6,7 +6,6 @@
#include "Core/EventBroker.h"
#include "Rendering/Renderer.h"
#include "Core/InputManager.h"
#include "GUI/Frame.h"
#include "Core/World.h"
#include "Input/InputProxy.h"
#include "Input/KeyboardInputHandler.h"