Merge remote-tracking branch 'origin/master' into Importer
Conflicts: resources/Schema/Entities/Player.xml src/Engine/Collision/CollisionSystem.cpp src/Engine/Rendering/DrawFinalPass.cpp
This commit is contained in:
@@ -12,55 +12,56 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
if (!boundingBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
ComponentWrapper& cTransform = entity["Transform"];
|
||||
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;
|
||||
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->CollisionVertices(), model->CollisionIndices(), 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;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,10 +87,13 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity);
|
||||
|
||||
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
|
||||
bool notMovingxz = glm::all(glm::lessThan(glm::abs(glm::vec2(inOutVelocity.x, inOutVelocity.z)), glm::vec2(0.01f))) && prevPosIt != m_PrevPositions.end();
|
||||
bool isOnGround = (bool)cPhysics["IsOnGround"];
|
||||
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
|
||||
if (Collision::AABBvsTriangles(boxA, model->CollisionVertices(), model->CollisionIndices(), modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
|
||||
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
||||
//Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector.
|
||||
(glm::vec3&)cTransform["Position"] += notMovingxz ? prevPosIt->second - boxA.Origin() : resolutionVector;
|
||||
boxA = *Collision::EntityAbsoluteAABB(entity);
|
||||
cPhysics["Velocity"] = inOutVelocity;
|
||||
if (isOnGround) {
|
||||
everHitTheGround = true;
|
||||
@@ -99,6 +103,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 +117,5 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
(bool)cPhysics["IsOnGround"] = false;
|
||||
}
|
||||
|
||||
(glm::vec3&)cPhysics["PrevOrigin"] = boxA.Origin();
|
||||
m_PrevPositions[entity] = boxA.Origin();
|
||||
}
|
||||
|
||||
@@ -51,6 +51,40 @@ 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;
|
||||
}
|
||||
|
||||
std::vector<EntityWrapper> EntityWrapper::ChildrenWithComponent(const std::string& componentType)
|
||||
{
|
||||
std::vector<EntityWrapper> childrenWithComponent;
|
||||
childrenWithComponentRecursive(componentType, *this, childrenWithComponent);
|
||||
return childrenWithComponent;
|
||||
}
|
||||
|
||||
void EntityWrapper::DeleteChildren()
|
||||
{
|
||||
auto itPair = this->World->GetDirectChildren(this->ID);
|
||||
if (itPair.first == itPair.second) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<EntityID> entitiesToDelete;
|
||||
for (auto it = itPair.first; it != itPair.second; it++) {
|
||||
entitiesToDelete.push_back(it->second);
|
||||
}
|
||||
for (auto& e : entitiesToDelete) {
|
||||
this->World->DeleteEntity(e);
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
|
||||
{
|
||||
EntityWrapper entity = *this;
|
||||
@@ -90,6 +124,11 @@ ComponentWrapper EntityWrapper::operator[](const char* componentName)
|
||||
}
|
||||
}
|
||||
|
||||
ComponentWrapper EntityWrapper::operator[](const std::string& componentName)
|
||||
{
|
||||
return this->operator[](componentName.c_str());
|
||||
}
|
||||
|
||||
bool EntityWrapper::operator==(const EntityWrapper& e) const
|
||||
{
|
||||
return (this->ID == e.ID) && (this->World == e.World);
|
||||
@@ -111,7 +150,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 +170,42 @@ 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;
|
||||
}
|
||||
|
||||
void EntityWrapper::childrenWithComponentRecursive(const std::string& componentType, EntityWrapper& entity, std::vector<EntityWrapper>& childrenWithComponent)
|
||||
{
|
||||
auto itPair = this->World->GetDirectChildren(entity.ID);
|
||||
if (itPair.first == itPair.second) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = itPair.first; it != itPair.second; ++it) {
|
||||
EntityWrapper child = EntityWrapper(entity.World, it->second);
|
||||
if (child.HasComponent(componentType)) {
|
||||
childrenWithComponent.push_back(child);
|
||||
}
|
||||
childrenWithComponentRecursive(componentType, child, childrenWithComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int
|
||||
va_end(args);
|
||||
|
||||
if (logLevel == LOG_LEVEL_ERROR) {
|
||||
std::cerr << file << ":" << line << " " << func << std::endl;
|
||||
std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
||||
//std::cerr << file << ":" << line << " " << func << std::endl;
|
||||
//std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
||||
} else {
|
||||
std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -580,6 +580,11 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode)
|
||||
|
||||
bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.WantCaptureKeyboard) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.ModCtrl && e.KeyCode == GLFW_KEY_S) {
|
||||
if (m_CurrentSelection.Valid()) {
|
||||
EntityWrapper baseParent = m_CurrentSelection;
|
||||
@@ -598,6 +603,19 @@ 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_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);
|
||||
|
||||
@@ -54,7 +54,7 @@ void EditorRenderSystem::Update(double dt)
|
||||
EntityWrapper entity(m_World, cModel.EntityID);
|
||||
glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World);
|
||||
for (auto matGroup : model->MaterialGroups()) {
|
||||
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f);
|
||||
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f, false);
|
||||
if (cModel["Transparent"]) {
|
||||
scene.Jobs.TransparentObjects.push_back(modelJob);
|
||||
} else {
|
||||
|
||||
@@ -28,6 +28,7 @@ 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));
|
||||
@@ -160,6 +161,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()) {
|
||||
|
||||
@@ -32,6 +32,7 @@ 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;
|
||||
@@ -100,8 +101,7 @@ void Client::Update()
|
||||
|
||||
void Client::parseMessageType(Packet& packet)
|
||||
{
|
||||
// Pop packetSize which is used by TCP Client to
|
||||
// create a packet of the correct size
|
||||
// Pop packetSize
|
||||
packet.ReadPrimitive<int>();
|
||||
int messageType = packet.ReadPrimitive<int>();
|
||||
if (messageType == -1)
|
||||
@@ -140,6 +140,12 @@ void Client::parseMessageType(Packet& packet)
|
||||
case MessageType::OnPlayerDamage:
|
||||
parsePlayerDamage(packet);
|
||||
break;
|
||||
case MessageType::OnDoubleJump:
|
||||
parseDoubleJump(packet);
|
||||
break;
|
||||
case MessageType::AmmoPickup:
|
||||
parseAmmoPickup(packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -229,7 +235,6 @@ void Client::parseSpawnEvents()
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
m_PlayerSpawnEvents = tempSpawn;
|
||||
// m_PlayerSpawnEvents.clear();
|
||||
}
|
||||
|
||||
void Client::parsePlayersSpawned(Packet& packet)
|
||||
@@ -257,8 +262,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,6 +283,28 @@ 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::parseAmmoPickup(Packet & packet)
|
||||
{
|
||||
Events::AmmoPickup e;
|
||||
e.AmmoGain = packet.ReadPrimitive<int>();
|
||||
e.Player = m_LocalPlayer;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID)
|
||||
{
|
||||
for (auto field : componentInfo.FieldsInOrder) {
|
||||
@@ -348,9 +381,7 @@ void Client::parseSnapshot(Packet& packet)
|
||||
EntityWrapper localEntity(m_World, localEntityID);
|
||||
// Update entity
|
||||
if (m_World->HasComponent(localEntityID, componentType)) {
|
||||
if (localEntity.Name() == "CapturePointHUD") {
|
||||
UpdateLocalCapturePointHUD(localEntity);
|
||||
}
|
||||
// TODO Fix memory leak here
|
||||
SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo);
|
||||
bool shouldApply = true;
|
||||
// Apply potential filter function
|
||||
@@ -361,6 +392,7 @@ void Client::parseSnapshot(Packet& packet)
|
||||
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 {
|
||||
@@ -377,7 +409,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);
|
||||
@@ -387,26 +423,16 @@ 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();
|
||||
}
|
||||
|
||||
|
||||
void Client::UpdateLocalCapturePointHUD(EntityWrapper capturePointHUD)
|
||||
{
|
||||
//auto children = m_World->GetChildren(capturePointHUD.ID);
|
||||
//for (auto it = children.first; it != children.second; it++) {
|
||||
// it->first
|
||||
//}
|
||||
//
|
||||
//EntityWrapper& localHUD = m_LocalPlayer.FirstChildByName("HUD").FirstChildByName("CapturePointHUD");
|
||||
//m_World->GetComponentPools()
|
||||
}
|
||||
|
||||
void Client::disconnect()
|
||||
{
|
||||
m_IsConnected = false;
|
||||
@@ -469,6 +495,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));
|
||||
@@ -503,7 +534,7 @@ 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));
|
||||
@@ -515,6 +546,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()) {
|
||||
|
||||
@@ -13,7 +13,7 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage);
|
||||
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EAmmoPickup, &Server::OnAmmoPickup);
|
||||
// BindWW
|
||||
if (port == 0) {
|
||||
port = config->Get<float>("Networking.Port", 27666);
|
||||
@@ -29,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
|
||||
@@ -47,6 +46,7 @@ void Server::Update()
|
||||
}
|
||||
}
|
||||
|
||||
PlayerDefinition pd;
|
||||
while (m_Unreliable.IsSocketAvailable()) {
|
||||
// Packet will get real data in receive
|
||||
Packet packet(MessageType::Invalid);
|
||||
@@ -65,7 +65,7 @@ void Server::Update()
|
||||
PlayerDefinition localArea;
|
||||
localArea.Endpoint = boost::asio::ip::udp::endpoint();
|
||||
m_ServerlistRequest.Receive(packet, localArea);
|
||||
if(packet.GetMessageType() == MessageType::ServerlistRequest) {
|
||||
if (packet.GetMessageType() == MessageType::ServerlistRequest) {
|
||||
packet.ReadPrimitive<int>(); // Pop size
|
||||
packet.ReadPrimitive<int>(); // Pop MsgType
|
||||
packet.ReadPrimitive<int>(); // Pop packet ID
|
||||
@@ -76,7 +76,7 @@ void Server::Update()
|
||||
}
|
||||
|
||||
// Check if players have disconnected
|
||||
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
|
||||
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
|
||||
disconnect(m_PlayersToDisconnect.at(i));
|
||||
}
|
||||
m_PlayersToDisconnect.clear();
|
||||
@@ -136,7 +136,10 @@ void Server::parseMessageType(Packet& packet)
|
||||
parseOnPlayerDamage(packet);
|
||||
break;
|
||||
case MessageType::PlayerTransform:
|
||||
parsePlayerTransform(packet);
|
||||
parsePlayerTransform(packet);
|
||||
break;
|
||||
case MessageType::OnDoubleJump:
|
||||
parseDoubleJump(packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -183,7 +186,7 @@ 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++) {
|
||||
@@ -191,49 +194,47 @@ void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
|
||||
// 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++) {
|
||||
@@ -343,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
|
||||
@@ -455,8 +456,7 @@ bool Server::OnInputCommand(const Events::InputCommand & e)
|
||||
}
|
||||
isReadingData = !isReadingData;
|
||||
m_SaveDataTimer = std::clock();
|
||||
}
|
||||
else if (e.Command == "KickPlayer" && e.Value > 0) {
|
||||
} else if (e.Command == "KickPlayer" && e.Value > 0) {
|
||||
kick(0);
|
||||
}
|
||||
|
||||
@@ -507,7 +507,20 @@ bool Server::OnPlayerDamage(const Events::PlayerDamage& e)
|
||||
packet.WritePrimitive(e.Damage);
|
||||
reliableBroadcast(packet);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Server::OnAmmoPickup(const Events::AmmoPickup & e)
|
||||
{
|
||||
for (auto& kv : m_ConnectedPlayers) {
|
||||
if (e.Player.ID == kv.second.EntityID) {
|
||||
Packet packet(MessageType::AmmoPickup);
|
||||
// We dont send playerID as it will be set at client to local
|
||||
packet.WritePrimitive(e.AmmoGain);
|
||||
m_Reliable.Send(packet, kv.second);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Server::parseClientPing()
|
||||
@@ -536,6 +549,12 @@ void Server::parsePing()
|
||||
}
|
||||
}
|
||||
|
||||
bool Server::parseDoubleJump(Packet & packet)
|
||||
{
|
||||
reliableBroadcast(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Server::parseOnInputCommand(Packet& packet)
|
||||
{
|
||||
PlayerID player = -1;
|
||||
@@ -595,8 +614,17 @@ void Server::parsePlayerTransform(Packet& packet)
|
||||
|
||||
bool Server::shouldSendToClient(EntityWrapper childEntity)
|
||||
{
|
||||
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") || child.HasComponent("HealthPickup")
|
||||
|| child.HasComponent("AmmoPickup")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid()
|
||||
|| childEntity.HasComponent("CapturePoint") || childEntity.FirstParentWithComponent("CapturePoint").Valid();
|
||||
|| childEntity.HasComponent("CapturePoint") || childEntity.HasComponent("HealthPickup")
|
||||
|| childEntity.HasComponent("AmmoPickup");
|
||||
}
|
||||
|
||||
PlayerID Server::GetPlayerIDFromEndpoint()
|
||||
|
||||
@@ -4,6 +4,8 @@ using namespace boost::asio::ip;
|
||||
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();
|
||||
}
|
||||
@@ -13,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) {
|
||||
@@ -32,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();
|
||||
|
||||
@@ -17,6 +17,7 @@ void CubeMapPass::LoadTextures(std::string input)
|
||||
m_CubeMapTextures.push_back(img);
|
||||
}
|
||||
GenerateCubeMapTexture();
|
||||
m_PreviusCubeMapTexture = input;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,41 @@
|
||||
#include "Rendering/DrawBloomPass.h"
|
||||
|
||||
DrawBloomPass::DrawBloomPass(IRenderer* renderer)
|
||||
DrawBloomPass::DrawBloomPass(IRenderer* renderer, ConfigFile* config)
|
||||
: m_Renderer(renderer)
|
||||
, m_Config(config)
|
||||
{
|
||||
m_Renderer = renderer;
|
||||
InitializeTextures();
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||
|
||||
InitializeTextures();
|
||||
InitializeBuffers();
|
||||
InitializeShaderPrograms();
|
||||
ChangeQuality(m_Config->Get<int>("GLOW.Quality", 2));
|
||||
}
|
||||
|
||||
void DrawBloomPass::InitializeTextures()
|
||||
{
|
||||
m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false);
|
||||
m_BlackTexture = CommonFunctions::LoadTexture("Textures/Core/Black.png", false);
|
||||
}
|
||||
|
||||
void DrawBloomPass::ChangeQuality(int quality)
|
||||
{
|
||||
if (m_Quality == quality) {
|
||||
return;
|
||||
}
|
||||
m_Quality = quality;
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||
|
||||
if (m_Quality == 0) {
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_horiz);
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_vert);
|
||||
m_GaussianTexture_horiz = 0;
|
||||
m_GaussianTexture_vert = 0;
|
||||
return;
|
||||
}
|
||||
InitializeTextures();
|
||||
|
||||
InitializeBuffers();
|
||||
InitializeShaderPrograms();
|
||||
std::string qStr = std::to_string(m_Quality);
|
||||
m_Iterations = m_Config->Get<float>("GLOW" + qStr + ".NumIterations", 0);
|
||||
}
|
||||
|
||||
void DrawBloomPass::InitializeShaderPrograms()
|
||||
@@ -35,37 +57,45 @@ void DrawBloomPass::InitializeShaderPrograms()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawBloomPass::InitializeBuffers()
|
||||
{
|
||||
GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
|
||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
if (m_GaussianFrameBuffer_horiz.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
|
||||
GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
|
||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
if (m_GaussianFrameBuffer_vert.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
}
|
||||
|
||||
|
||||
void DrawBloomPass::ClearBuffer()
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
GLERROR("PRE");
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
GLERROR("END");
|
||||
}
|
||||
|
||||
void DrawBloomPass::Draw(GLuint texture)
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
GLERROR("DrawBloomPass::Draw: Pre");
|
||||
|
||||
DrawBloomPassState state;
|
||||
@@ -84,11 +114,12 @@ void DrawBloomPass::Draw(GLuint texture)
|
||||
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++) {
|
||||
for (int i = 1; i < m_Iterations; i++) {
|
||||
//Vertical pass
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
@@ -96,16 +127,19 @@ void DrawBloomPass::Draw(GLuint texture)
|
||||
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_vert.Unbind();
|
||||
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
}
|
||||
|
||||
//final vertical gaussian after the iterations are done
|
||||
@@ -113,6 +147,7 @@ void DrawBloomPass::Draw(GLuint texture)
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
@@ -125,20 +160,11 @@ void DrawBloomPass::Draw(GLuint texture)
|
||||
|
||||
void DrawBloomPass::OnWindowResize()
|
||||
{
|
||||
GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
}
|
||||
|
||||
void DrawBloomPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
|
||||
{
|
||||
glGenTextures(1, texture);
|
||||
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution
|
||||
GLERROR("Texture initialization failed");
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ void DrawColorCorrectionPass::InitializeShaderPrograms()
|
||||
m_ColorCorrectionProgram->Link();
|
||||
}
|
||||
|
||||
void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLuint sceneTextureLowRes, GLuint bloomTextureLowRes, GLfloat gamma, GLfloat exposure)
|
||||
void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLfloat gamma, GLfloat exposure)
|
||||
{
|
||||
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
GLERROR("DrawScreenQuadPass::Draw: Pre");
|
||||
@@ -33,10 +33,6 @@ void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLu
|
||||
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, bloomTexture);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, sceneTextureLowRes);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, bloomTextureLowRes);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,11 +8,12 @@ DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer)
|
||||
Enable(GL_BLEND);
|
||||
BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
Enable(GL_DEPTH_TEST);
|
||||
DepthMask(GL_TRUE);
|
||||
Enable(GL_CULL_FACE);
|
||||
Enable(GL_STENCIL_TEST);
|
||||
StencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
StencilMask(0xFF);
|
||||
// Enable(GL_STENCIL_TEST);
|
||||
// StencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
// StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
// StencilMask(0xFF);
|
||||
ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));
|
||||
}
|
||||
|
||||
@@ -24,11 +25,9 @@ DrawFinalPassState::~DrawFinalPassState()
|
||||
DrawStencilState::DrawStencilState(GLuint frameBuffer)
|
||||
{
|
||||
BindFramebuffer(frameBuffer);
|
||||
Enable(GL_STENCIL_TEST);
|
||||
StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
StencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
StencilMask(0xFF);
|
||||
Enable(GL_DEPTH_TEST);
|
||||
DepthMask(GL_TRUE);
|
||||
Enable(GL_CULL_FACE);
|
||||
ClearColor(glm::vec4(0.f));
|
||||
}
|
||||
|
||||
|
||||
@@ -42,33 +42,33 @@ void FrameBuffer::Generate()
|
||||
GLERROR("PRE");
|
||||
|
||||
std::vector<GLenum> attachments;
|
||||
|
||||
glGenFramebuffers(1, &m_BufferHandle);
|
||||
if (m_BufferHandle == 0) {
|
||||
glGenFramebuffers(1, &m_BufferHandle);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle);
|
||||
GLERROR("1");
|
||||
|
||||
for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) {
|
||||
switch ((*it)->m_ResourceType) {
|
||||
case GL_TEXTURE_2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
|
||||
GLERROR("FrameBuffer generate: glFramebufferTexture2D");
|
||||
for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) {
|
||||
switch ((*it)->m_ResourceType) {
|
||||
case GL_TEXTURE_2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
|
||||
GLERROR("FrameBuffer generate: glFramebufferTexture2D");
|
||||
|
||||
break;
|
||||
case GL_RENDERBUFFER:
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
|
||||
GLERROR("FrameBuffer generate: glFramebufferRenderbuffer");
|
||||
break;
|
||||
}
|
||||
GLERROR("2");
|
||||
break;
|
||||
case GL_RENDERBUFFER:
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
|
||||
GLERROR("FrameBuffer generate: glFramebufferRenderbuffer");
|
||||
break;
|
||||
}
|
||||
GLERROR("2");
|
||||
|
||||
if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
attachments.push_back((*it)->m_Attachment);
|
||||
}
|
||||
GLERROR("Attachment");
|
||||
|
||||
}
|
||||
GLERROR("3");
|
||||
if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
attachments.push_back((*it)->m_Attachment);
|
||||
}
|
||||
GLERROR("Attachment");
|
||||
|
||||
}
|
||||
GLERROR("3");
|
||||
|
||||
GLenum* bufferTextures = &attachments[0];
|
||||
glDrawBuffers(attachments.size(), bufferTextures);
|
||||
|
||||
@@ -19,15 +19,16 @@ PickingPass::~PickingPass()
|
||||
|
||||
void PickingPass::InitializeTextures()
|
||||
{
|
||||
GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR,
|
||||
CommonFunctions::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);
|
||||
CommonFunctions::GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST,
|
||||
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
||||
}
|
||||
|
||||
void PickingPass::InitializeFrameBuffers()
|
||||
{
|
||||
|
||||
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();
|
||||
@@ -366,7 +367,7 @@ void PickingPass::ClearPicking()
|
||||
|
||||
m_PickingBuffer.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
m_PickingBuffer.Unbind();
|
||||
GLERROR("END");
|
||||
}
|
||||
@@ -407,16 +408,3 @@ PickData PickingPass::Pick(glm::vec2 screenCoord)
|
||||
pickData.World = pickInfo.World;
|
||||
return pickData;
|
||||
}
|
||||
|
||||
void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
|
||||
{
|
||||
//TODO: Renderer: Make this in a sparate class
|
||||
glGenTextures(1, texture);
|
||||
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution
|
||||
GLERROR("Texture initialization failed");
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ PickingPassState::PickingPassState(GLuint frameBuffer)
|
||||
Enable(GL_DEPTH_TEST);
|
||||
Enable(GL_CULL_FACE);
|
||||
Disable(GL_BLEND);
|
||||
|
||||
glm::vec4 clearColor = glm::vec4(0.f);
|
||||
//ClearColor(clearColor);
|
||||
//Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
GLERROR("END");
|
||||
|
||||
}
|
||||
|
||||
PickingPassState::~PickingPassState()
|
||||
|
||||
@@ -135,6 +135,26 @@ bool RenderState::DepthMask(GLboolean flag)
|
||||
return !GLERROR("DepthMask");
|
||||
}
|
||||
|
||||
bool RenderState::DepthFunc(GLenum func)
|
||||
{
|
||||
GLint original;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &original);
|
||||
m_ResetFunctions.push_back(std::bind(glDepthFunc, original));
|
||||
glDepthFunc(func);
|
||||
return !GLERROR("DepthFunc");
|
||||
}
|
||||
|
||||
bool RenderState::AlphaFunc(GLenum func, GLclampf thresholder)
|
||||
{
|
||||
GLint originalFunc;
|
||||
glGetIntegerv(GL_ALPHA_TEST_FUNC, &originalFunc);
|
||||
GLint originalRef;
|
||||
glGetIntegerv(GL_ALPHA_TEST_REF, &originalRef);
|
||||
m_ResetFunctions.push_back(std::bind(glAlphaFunc, originalFunc, originalRef));
|
||||
glAlphaFunc(func, thresholder);
|
||||
return !GLERROR("AlphaFunc");
|
||||
}
|
||||
|
||||
RenderState::~RenderState()
|
||||
{
|
||||
for (auto& f : boost::adaptors::reverse(m_ResetFunctions)) {
|
||||
|
||||
@@ -240,6 +240,8 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
fillColor = (glm::vec4)fillComponent["Color"];
|
||||
}
|
||||
|
||||
bool isShielded = m_World->HasComponent(cModel.EntityID, "Shielded") || m_World->HasComponent(cModel.EntityID, "Player");
|
||||
|
||||
glm::mat4 modelMatrix = Transform::ModelMatrix(cModel.EntityID, m_World);
|
||||
//Loop through all materialgroups of a model
|
||||
for (auto matGroup : model->MaterialGroups()) {
|
||||
@@ -255,20 +257,19 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
cModel,
|
||||
m_World,
|
||||
fillColor,
|
||||
fillPercentage
|
||||
fillPercentage,
|
||||
isShielded
|
||||
));
|
||||
if (m_World->HasComponent(cModel.EntityID, "Shield")){
|
||||
explosionEffectJob->CalculateHash();
|
||||
Jobs.ShieldObjects.push_back(explosionEffectJob);
|
||||
} else if (m_World->HasComponent(cModel.EntityID, "Shielded")
|
||||
|| m_World->HasComponent(cModel.EntityID, "Player")) {
|
||||
|
||||
} else if (isShielded) {
|
||||
if (explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) {
|
||||
cModel["Transparent"] = true;
|
||||
}
|
||||
|
||||
if (cModel["Transparent"]) {
|
||||
Jobs.TransparentShieldedObjects.push_back(explosionEffectJob);
|
||||
Jobs.TransparentObjects.push_back(explosionEffectJob);
|
||||
} else {
|
||||
explosionEffectJob->CalculateHash();
|
||||
Jobs.OpaqueShieldedObjects.push_back(explosionEffectJob);
|
||||
@@ -294,20 +295,20 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
cModel,
|
||||
m_World,
|
||||
fillColor,
|
||||
fillPercentage
|
||||
fillPercentage,
|
||||
isShielded
|
||||
));
|
||||
if (m_World->HasComponent(cModel.EntityID, "Shield")) {
|
||||
modelJob->CalculateHash();
|
||||
Jobs.ShieldObjects.push_back(modelJob);
|
||||
} else if (m_World->HasComponent(cModel.EntityID, "Shielded")
|
||||
|| m_World->HasComponent(cModel.EntityID, "Player")) {
|
||||
} else if (isShielded) {
|
||||
|
||||
if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) {
|
||||
cModel["Transparent"] = true;
|
||||
}
|
||||
|
||||
if (cModel["Transparent"]) {
|
||||
Jobs.TransparentShieldedObjects.push_back(modelJob);
|
||||
Jobs.TransparentObjects.push_back(modelJob);
|
||||
} else {
|
||||
modelJob->CalculateHash();
|
||||
Jobs.OpaqueShieldedObjects.push_back(modelJob);
|
||||
|
||||
@@ -4,6 +4,8 @@ std::unordered_map<GLFWwindow*, Renderer*> Renderer::m_WindowToRenderer;
|
||||
|
||||
void Renderer::Initialize()
|
||||
{
|
||||
m_SSAO_Quality = m_Config->Get<int>("SSAO.Quality", 0);
|
||||
m_GLOW_Quality = m_Config->Get<int>("GLOW.Quality", 0);
|
||||
InitializeWindow();
|
||||
|
||||
InitializeRenderPasses();
|
||||
@@ -26,9 +28,9 @@ void Renderer::glfwFrameBufferCallback(GLFWwindow* window, int width, int height
|
||||
glViewport(0, 0, width, height);
|
||||
Renderer* currentRenderer = m_WindowToRenderer[window];
|
||||
currentRenderer->m_ViewportSize = Rectangle(width, height);
|
||||
currentRenderer->m_PickingPass->OnWindowResize();
|
||||
currentRenderer->m_DrawFinalPass->OnWindowResize();
|
||||
currentRenderer->m_LightCullingPass->OnWindowResize();
|
||||
currentRenderer->m_PickingPass->OnWindowResize();
|
||||
currentRenderer->m_DrawBloomPass->OnWindowResize();
|
||||
currentRenderer->m_SSAOPass->OnWindowResize();
|
||||
}
|
||||
@@ -107,7 +109,8 @@ void Renderer::Update(double dt)
|
||||
void Renderer::Draw(RenderFrame& frame)
|
||||
{
|
||||
GLERROR("PRE");
|
||||
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking\0Ambient Occlusion");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Ambient Occlusion");
|
||||
ImGui::Combo("CubeMap", &m_CubeMapTexture, "Nevada(512)\0Sky(1024)");
|
||||
if(m_CubeMapTexture == 0) {
|
||||
m_CubeMapPass->LoadTextures("Nevada");
|
||||
@@ -115,19 +118,16 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
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);
|
||||
ImGui::SliderInt("SSAO Quality", &m_SSAO_Quality, 0, 3);
|
||||
ImGui::SliderInt("Glow Quality", &m_GLOW_Quality, 0, 3);
|
||||
m_SSAOPass->ChangeQuality(m_SSAO_Quality);
|
||||
m_DrawBloomPass->ChangeQuality(m_GLOW_Quality);
|
||||
GLERROR("SSAO Settings");
|
||||
//clear buffer 0
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//Clear other buffers
|
||||
//Clear other buffers
|
||||
PerformanceTimer::StartTimer("Renderer-ClearBuffers");
|
||||
m_PickingPass->ClearPicking();
|
||||
m_DrawFinalPass->ClearBuffer();
|
||||
@@ -136,18 +136,16 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
PerformanceTimer::StopTimer("Renderer-ClearBuffers");
|
||||
GLERROR("ClearBuffers");
|
||||
for (auto scene : frame.RenderScenes) {
|
||||
PerformanceTimer::StartTimer("Renderer-Depth");
|
||||
PerformanceTimer::StartTimer("Renderer-PickingPass");
|
||||
m_PickingPass->Draw(*scene);
|
||||
GLERROR("Drawing pickingpass");
|
||||
PerformanceTimer::StopTimer("Renderer-Depth");
|
||||
PerformanceTimer::StopTimer("Renderer-PickingPass");
|
||||
}
|
||||
PerformanceTimer::StartTimer("AO generation");
|
||||
m_SSAOPass->Draw(m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera);
|
||||
GLuint ao = m_SSAOPass->SSAOTexture();
|
||||
PerformanceTimer::StopTimer("AO generation");
|
||||
PerformanceTimer::StartTimer("Renderer-AO generation");
|
||||
m_SSAOPass->Draw(*m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera);
|
||||
PerformanceTimer::StopTimer("Renderer-AO generation");
|
||||
for (auto scene : frame.RenderScenes){
|
||||
|
||||
PerformanceTimer::StartTimer("Renderer-Drawing PickingPass");
|
||||
PerformanceTimer::StartTimer("Renderer-Depth");
|
||||
SortRenderJobsByDepth(*scene);
|
||||
GLERROR("SortByDepth");
|
||||
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums");
|
||||
@@ -159,8 +157,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");
|
||||
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light");
|
||||
m_DrawFinalPass->Draw(*scene);
|
||||
GLERROR("Draw Geometry+Light");
|
||||
//m_DrawScenePass->Draw(*scene);
|
||||
|
||||
@@ -176,7 +174,7 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
|
||||
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);
|
||||
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), frame.Gamma, frame.Exposure);
|
||||
PerformanceTimer::StopTimer("Renderer-Color Correction Pass");
|
||||
}
|
||||
|
||||
@@ -188,18 +186,12 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTexture());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 3) {
|
||||
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTextureLowRes());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 4) {
|
||||
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTextureLowRes());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 5) {
|
||||
m_DrawScreenQuadPass->Draw(m_DrawBloomPass->GaussianTexture());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 6) {
|
||||
if (m_DebugTextureToDraw == 4) {
|
||||
m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 7) {
|
||||
if (m_DebugTextureToDraw == 5) {
|
||||
m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture());
|
||||
}
|
||||
PerformanceTimer::StopTimer("Renderer-Misc Debug Draws");
|
||||
@@ -207,8 +199,11 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass");
|
||||
m_ImGuiRenderPass->Draw();
|
||||
GLERROR("Imgui draw");
|
||||
PerformanceTimer::StopTimer("Renderer-ImGuiRenderPass");
|
||||
|
||||
PerformanceTimer::StartTimer("Renderer-SwapBuffer");
|
||||
glfwSwapBuffers(m_Window);
|
||||
PerformanceTimer::StopTimer("Renderer-ImGuiRenderPass");
|
||||
PerformanceTimer::StopTimer("Renderer-SwapBuffer");
|
||||
}
|
||||
|
||||
PickData Renderer::Pick(glm::vec2 screenCoord)
|
||||
@@ -248,9 +243,10 @@ void Renderer::InitializeRenderPasses()
|
||||
m_PickingPass = new PickingPass(this, m_EventBroker);
|
||||
m_LightCullingPass = new LightCullingPass(this);
|
||||
m_CubeMapPass = new CubeMapPass(this);
|
||||
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass);
|
||||
m_SSAOPass = new SSAOPass(this, m_Config);
|
||||
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass);
|
||||
m_DrawScreenQuadPass = new DrawScreenQuadPass(this);
|
||||
m_DrawBloomPass = new DrawBloomPass(this);
|
||||
m_DrawBloomPass = new DrawBloomPass(this, m_Config);
|
||||
m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this);
|
||||
m_SSAOPass = new SSAOPass(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +1,168 @@
|
||||
#include "Rendering/SSAOPass.h"
|
||||
|
||||
SSAOPass::SSAOPass(IRenderer* renderer)
|
||||
SSAOPass::SSAOPass(IRenderer* renderer, ConfigFile* config)
|
||||
: m_Renderer(renderer)
|
||||
, m_Config(config)
|
||||
{
|
||||
m_Renderer = renderer;
|
||||
m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false);
|
||||
|
||||
ChangeQuality(m_Config->Get<int>("SSAO.Quality", 0));
|
||||
|
||||
}
|
||||
|
||||
void SSAOPass::ChangeQuality(int quality)
|
||||
{
|
||||
if (m_Quality == quality) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Quality = quality;
|
||||
|
||||
if (m_Quality == 0) {
|
||||
CommonFunctions::DeleteTexture(&m_SSAOTexture);
|
||||
CommonFunctions::DeleteTexture(&m_SSAOViewSpaceZTexture);
|
||||
CommonFunctions::DeleteTexture(&m_Gaussian_horiz);
|
||||
CommonFunctions::DeleteTexture(&m_Gaussian_vert);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string qStr = std::to_string(m_Quality);
|
||||
Setting(
|
||||
m_Config->Get<float>("SSAO" + qStr + ".Radius", 0.01),
|
||||
m_Config->Get<float>("SSAO" + qStr + ".Bias", 0.012),
|
||||
m_Config->Get<float>("SSAO" + qStr + ".Contrast", 1.0),
|
||||
m_Config->Get<float>("SSAO" + qStr + ".Intensity", 1.0),
|
||||
m_Config->Get<int>("SSAO" + qStr + ".NumSamples", 0),
|
||||
m_Config->Get<int>("SSAO" + qStr + ".NumTurns", 0),
|
||||
m_Config->Get<int>("SSAO" + qStr + ".NumIterations", 0),
|
||||
m_Config->Get<int>("SSAO" + qStr + ".TextureQuality", 4)
|
||||
);
|
||||
|
||||
|
||||
|
||||
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();
|
||||
if (m_SSAOProgram->GetHandle() == 0) {
|
||||
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();
|
||||
if (m_SSAOViewSpaceZProgram->GetHandle() == 0) {
|
||||
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();
|
||||
}
|
||||
|
||||
m_GaussianProgram_horiz = ResourceManager::Load<ShaderProgram>("##GaussianProgramHoriz");
|
||||
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");
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
CommonFunctions::GenerateTexture(&m_SSAOTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R8, GL_RED, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_SSAOViewSpaceZTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R32F, GL_RED, GL_FLOAT);
|
||||
|
||||
CommonFunctions::GenerateTexture(&m_Gaussian_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R8, GL_RED, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_Gaussian_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R8, GL_RED, GL_FLOAT);
|
||||
}
|
||||
|
||||
void SSAOPass::InitializeBuffer()
|
||||
{
|
||||
m_SSAOFramBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SSAOTexture, GL_COLOR_ATTACHMENT0)));
|
||||
if (m_SSAOFramBuffer.GetHandle() == 0) {
|
||||
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)));
|
||||
|
||||
if (m_SSAOViewSpaceZFramBuffer.GetHandle() == 0) {
|
||||
m_SSAOViewSpaceZFramBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SSAOViewSpaceZTexture, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_SSAOViewSpaceZFramBuffer.Generate();
|
||||
|
||||
|
||||
|
||||
if (m_GaussianFrameBuffer_horiz.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_Gaussian_horiz, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
|
||||
|
||||
if (m_GaussianFrameBuffer_vert.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_Gaussian_vert, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
|
||||
}
|
||||
|
||||
void SSAOPass::ClearBuffer()
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
m_SSAOFramBuffer.Bind();
|
||||
glClearColor(1.f, 1.f, 1.f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_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);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_SSAOViewSpaceZFramBuffer.Unbind();
|
||||
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
glClearColor(1.f, 1.f, 1.f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
glClearColor(1.f, 1.f, 1.f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
}
|
||||
|
||||
void SSAOPass::Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns) {
|
||||
void SSAOPass::Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int numOfTurns, int iterations, int quality) {
|
||||
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");
|
||||
m_NumOfTurns = numOfTurns;
|
||||
m_Iterations = iterations;
|
||||
m_TextureQuality = quality;
|
||||
}
|
||||
|
||||
void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSAOPassState state;
|
||||
GLuint viewSpaceZPShaderHandle = m_SSAOViewSpaceZProgram->GetHandle();
|
||||
GLuint SSAOShaderHandle = m_SSAOProgram->GetHandle();
|
||||
@@ -98,6 +182,7 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
(-1.0f),
|
||||
(+1.0f)
|
||||
);*/
|
||||
glViewport(0, 0, (m_Renderer->GetViewportSize().Width >> m_TextureQuality), (m_Renderer->GetViewportSize().Height >> m_TextureQuality)); //JOHAN TODO: Get this into state
|
||||
glUniform3fv(glGetUniformLocation(viewSpaceZPShaderHandle, "ClipInfo"), 1, glm::value_ptr(clipInfo));
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
@@ -107,9 +192,9 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
|
||||
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])),
|
||||
(-2.0 / ((m_Renderer->GetViewportSize().Width >> m_TextureQuality) * camera->ProjectionMatrix()[0][0])),
|
||||
((1.0 + camera->ProjectionMatrix()[1][2]) / camera->ProjectionMatrix()[1][1]),
|
||||
(-2.0 / (m_Renderer->GetViewportSize().Height * camera->ProjectionMatrix()[1][1]))
|
||||
(-2.0 / ((m_Renderer->GetViewportSize().Height >> m_TextureQuality) * camera->ProjectionMatrix()[1][1]))
|
||||
);
|
||||
|
||||
|
||||
@@ -120,26 +205,84 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
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, "uProjScale"), (m_Renderer->GetViewportSize().Height >> m_TextureQuality) / (-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);;
|
||||
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);
|
||||
DrawBloomPassState BloomState;
|
||||
GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle();
|
||||
GLuint shaderHandle_vert = m_GaussianProgram_vert->GetHandle();
|
||||
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_SSAOTexture);
|
||||
|
||||
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
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Gaussian_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
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
//horizontal pass
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Gaussian_vert);
|
||||
|
||||
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);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
}
|
||||
|
||||
//final vertical gaussian after the iterations are done
|
||||
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Gaussian_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
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
|
||||
glViewport(0, 0, (m_Renderer->GetViewportSize().Width), (m_Renderer->GetViewportSize().Height));
|
||||
}
|
||||
|
||||
void SSAOPass::OnWindowResize() {
|
||||
m_DrawBloomPass->OnWindowResize();
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeTexture();
|
||||
m_SSAOFramBuffer.Generate();
|
||||
m_SSAOViewSpaceZFramBuffer.Generate();
|
||||
InitializeBuffer();
|
||||
}
|
||||
@@ -17,3 +17,46 @@ Texture* CommonFunctions::LoadTexture(std::string path, bool threaded)
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void CommonFunctions::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
||||
{
|
||||
glDeleteTextures(1, texture);
|
||||
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 CommonFunctions::GenerateMultiSampleTexture(GLuint* texture, int numSamples, glm::vec2 dimensions, GLint internalFormat)
|
||||
{
|
||||
glDeleteTextures(1, texture);
|
||||
glGenTextures(1, texture);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, *texture);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples, internalFormat, dimensions.x, dimensions.y, false);
|
||||
GLERROR("Texture initialization failed");
|
||||
}
|
||||
|
||||
|
||||
void CommonFunctions::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps)
|
||||
{
|
||||
glGenTextures(1, texture);
|
||||
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||
glTexStorage2D(GL_TEXTURE_2D, numMipMaps, GL_RGBA8, dimensions.x, dimensions.y);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dimensions.x, dimensions.y, format, type, texture);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
GLERROR("MipMap Texture initialization failed");
|
||||
}
|
||||
|
||||
void CommonFunctions::DeleteTexture(GLuint* texture)
|
||||
{
|
||||
glDeleteTextures(1, texture);
|
||||
*texture = 0;
|
||||
}
|
||||
@@ -31,22 +31,27 @@ glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float scr
|
||||
|
||||
ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
||||
{
|
||||
GLERROR("Pre");
|
||||
PickDataBuffer->Bind();
|
||||
unsigned char pdata[3];
|
||||
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pdata);
|
||||
GLERROR("glReadPixels(pdata) Error");
|
||||
PickDataBuffer->Unbind();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
||||
GLERROR("glBindFramebuffer(DepthBuffer) Error");
|
||||
float depthData;
|
||||
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
||||
GLERROR("glReadPixels(depthData) Error");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
GLERROR("glBindFramebuffer(0) Error");
|
||||
|
||||
PixelData p;
|
||||
p.Color[0] = (int)pdata[0];
|
||||
p.Color[1] = (int)pdata[1];
|
||||
p.Depth = depthData;
|
||||
|
||||
GLERROR("ScreenCoords::ToPixelData Error");
|
||||
GLERROR("End");
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user