forked from Pyramiders/TombersAndPyramiders
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FogOfWarCamera.cpp
97 lines (83 loc) · 3.05 KB
/
FogOfWarCamera.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "FogOfWarCamera.h"
#include "SharedConstants.h"
#include "GameManager.h"
#include "SpriteRendererManager.h"
#include "HelperFunctions.h"
#include "Light.h"
void FogOfWarCamera::init()
{
m_regularPass.init();
m_fogOfWarPass.init();
}
inline float lerp(float t, float a, float b)
{
return a * (1 - t) + b * t;
}
void FogOfWarCamera::updateFogOfWarMask()
{
const int downscale = 16;
const int gameWidth = SCREEN_WIDTH / downscale;
const int gameHeight = SCREEN_HEIGHT / downscale;
unsigned char bytes[gameWidth * gameHeight * 4] = { 0 };
for(int i = 0; i < gameWidth * gameHeight * 4; i += 4)
{
bytes[i + 3] = 235;
}
auto objectsInBounds = GameManager::getInstance()->getObjectsInBounds(getTransform()->getX(), getTransform()->getY(), getGameWidth(), getGameHeight());
for(int i = 0; i < objectsInBounds.size(); i++)
{
auto lightComponent = objectsInBounds[i]->getComponent<Light>();
if (lightComponent != nullptr) {
int lightR = 0;
int lightG = 0;
int lightB = 0;
float lightSize = lightComponent->getLight(lightR, lightG, lightB);
float lightSizePixels = lightSize * getUnitSize() / downscale;
auto lightTransform = objectsInBounds[i]->getTransform();
if (isOnScreen(lightTransform)) {
int screenX = gameWidth / 2.0 - ((getTransform()->getX() - lightTransform->getX()) * getUnitSize() / downscale);
int screenY = gameHeight / 2.0f - ((getTransform()->getY() - lightTransform->getY()) * getUnitSize() / downscale);
float dist = getTransform()->getDistance(lightTransform);
float t = 1 - std::min( std::max( dist / (getGameHeight() / 2.0f), 0.0f ), 1.0f);
unsigned char r = lerp(t, 0.0f, lightR);
unsigned char g = lerp(t, 0.0f, lightG);
unsigned char b = lerp(t, 0.0f, lightB);
unsigned char a = lerp(t, 255.0f, 0.0f);
if (t < 0.3f) {
r = lerp((1 - t), r, 0.0f);
g = lerp((1 - t), g, 0.0f);
b = lerp((1 - t), b, 0.0f);
a = lerp((1 - t), a, 255.0f);
}
int lightRadiusPixels = lightSizePixels / 2.0f;
for(int x = -lightRadiusPixels; x < lightRadiusPixels; x++ ) {
for(int y = -lightRadiusPixels; y < lightRadiusPixels; y++) {
int pos = ((screenY + y) * gameWidth + (screenX) + x) * 4;
if (pos >= 0 && pos < gameWidth * gameHeight * 4) {
int culmulativeDist = abs(x) + abs(y);
double hyp = sqrt(x*x + y*y);
if (hyp < lightRadiusPixels) {
bytes[pos] = std::max(bytes[pos], r);
bytes[pos + 1] = std::max(bytes[pos + 1], g);
bytes[pos + 2] = std::max(bytes[pos + 2], b);
bytes[pos + 3] = ((float)culmulativeDist / (float)lightRadiusPixels) * a;
}
}
}
}
}
}
}
SpriteRendererManager::getInstance()->generateTexture(gameWidth, gameHeight, bytes, &m_fogOfWarMask);
}
int testCounter = 0;
bool full = false;
void FogOfWarCamera::applyRenderFilters(SpriteRendererManager* rendererManager)
{
ensureInit();
updateFogOfWarMask();
m_regularPass.bindFrameBuffer();
rendererManager->renderPass();
m_regularPass.unbindFrameBuffer();
rendererManager->renderFogOfWar(m_fogOfWarMask, m_regularPass);
}