Added basic shadows to point lights; Better than directional shadows
This commit is contained in:
parent
4b14362a04
commit
1a8320feab
@ -13,7 +13,7 @@ void MainState::onEnter() {
|
|||||||
text.centered(true);
|
text.centered(true);
|
||||||
uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5);
|
uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5);
|
||||||
button.create(nf::Vec2(0.8, 0.025), "Reset");
|
button.create(nf::Vec2(0.8, 0.025), "Reset");
|
||||||
light.create(nf::Vec3(5.0, 300.0, 100.0), nf::Vec3(1.0, 1.0, 1.0), 1.5, nf::Light::Type::DIRECTIONAL);
|
light.create(nf::Vec3(0.0, 5.0, 0.0), nf::Vec3(1.0, 1.0, 1.0), 1.5);
|
||||||
cm.create(nf::BaseAssets::cubemap);
|
cm.create(nf::BaseAssets::cubemap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,5 +20,4 @@ private:
|
|||||||
nf::Cubemap cm;
|
nf::Cubemap cm;
|
||||||
|
|
||||||
float xrot, yrot;
|
float xrot, yrot;
|
||||||
|
|
||||||
};
|
};
|
@ -24,7 +24,8 @@ struct Light {
|
|||||||
vec3 pos;
|
vec3 pos;
|
||||||
vec3 color;
|
vec3 color;
|
||||||
float strength;
|
float strength;
|
||||||
sampler2D depthTex;
|
sampler2D directionalDepthTex;
|
||||||
|
samplerCube pointDepthTex;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform Camera camera;
|
uniform Camera camera;
|
||||||
@ -32,20 +33,20 @@ uniform Material material;
|
|||||||
uniform Light light[100];
|
uniform Light light[100];
|
||||||
uniform int numberOfLights;
|
uniform int numberOfLights;
|
||||||
uniform bool isContinued;
|
uniform bool isContinued;
|
||||||
|
uniform float farPlane;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
float calcShadow(int lightNum, vec4 fragPosLight, vec3 no, vec3 lDir) {
|
float calcShadowDirectional(int lightNum, vec4 fragPosLight, vec3 no, vec3 lDir) {
|
||||||
vec3 fp = fragPosLight.xyz / fragPosLight.w;
|
vec3 fp = fragPosLight.xyz / fragPosLight.w;
|
||||||
fp = fp * 0.5 + 0.5;
|
fp = fp * 0.5 + 0.5;
|
||||||
float current = fp.z;
|
float current = fp.z;
|
||||||
float bias = max(0.05 * (1.0 - dot(no, lDir)), 0.005);
|
float bias = max(0.05 * (1.0 - dot(no, lDir)), 0.005);
|
||||||
float shad = 0.0f;
|
float shad = 0.0f;
|
||||||
vec2 texSize = 1.0 / textureSize(light[lightNum].depthTex, 0);
|
vec2 texSize = 1.0 / textureSize(light[lightNum].directionalDepthTex, 0);
|
||||||
|
|
||||||
for (int x = -1; x <= 1; x++) {
|
for (int x = -1; x <= 1; x++) {
|
||||||
for (int y = -1; y <= 1; y++) {
|
for (int y = -1; y <= 1; y++) {
|
||||||
float pcfDepth = texture(light[lightNum].depthTex, fp.xy + vec2(x, y) * texSize).r;
|
float pcfDepth = texture(light[lightNum].directionalDepthTex, fp.xy + vec2(x, y) * texSize).r;
|
||||||
shad += current - bias > pcfDepth ? 1.0 : 0.0;
|
shad += current - bias > pcfDepth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,6 +56,33 @@ float calcShadow(int lightNum, vec4 fragPosLight, vec3 no, vec3 lDir) {
|
|||||||
return shad;
|
return shad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 offsets[20] = vec3[](
|
||||||
|
vec3(1, 1, 1), vec3(1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
||||||
|
vec3(1, 1, -1), vec3(1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
||||||
|
vec3(1, 1, 0), vec3(1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
||||||
|
vec3(1, 0, 1), vec3(-1, 0, 1), vec3(1, 0, -1), vec3(-1, 0, -1),
|
||||||
|
vec3(0, 1, 1), vec3(0, -1, 1), vec3(0, -1, -1), vec3(0, 1, -1)
|
||||||
|
);
|
||||||
|
|
||||||
|
float calcShadowPoint(int lightNum, vec3 no, vec3 lDir) {
|
||||||
|
vec3 fragLight = fragPos - light[lightNum].pos;
|
||||||
|
float current = length(fragLight);
|
||||||
|
float bias = 0.15;
|
||||||
|
float closest = 0.0f;
|
||||||
|
float shad = 0.0f;
|
||||||
|
int samples = 20;
|
||||||
|
float viewDist = length(camera.pos - fragPos);
|
||||||
|
float disk = (1.0 + (viewDist / farPlane)) / 50.0f;
|
||||||
|
for (int i = 0; i < samples; i++) {
|
||||||
|
closest = texture(light[lightNum].pointDepthTex, fragLight + offsets[i] * disk).r;
|
||||||
|
closest *= farPlane;
|
||||||
|
if (current - bias > closest)
|
||||||
|
shad += 1.0f;
|
||||||
|
}
|
||||||
|
shad /= float(samples);
|
||||||
|
return shad;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 color = vec3(0.0);
|
vec3 color = vec3(0.0);
|
||||||
|
|
||||||
@ -73,9 +101,6 @@ void main() {
|
|||||||
if (!isContinued)
|
if (!isContinued)
|
||||||
color += ambient;
|
color += ambient;
|
||||||
for (int i = 0; i < numberOfLights; i++) {
|
for (int i = 0; i < numberOfLights; i++) {
|
||||||
if (i == numberOfLights - 1 && numberOfLights == 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (light[i].type == 1) {
|
if (light[i].type == 1) {
|
||||||
vec3 lightDir = normalize(light[i].pos - fragPos);
|
vec3 lightDir = normalize(light[i].pos - fragPos);
|
||||||
@ -88,7 +113,7 @@ void main() {
|
|||||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
|
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
|
||||||
vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.0f);
|
vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.0f);
|
||||||
|
|
||||||
float shadow = calcShadow(i, fragPosLightSpace[i], norm, lightDir);
|
float shadow = calcShadowDirectional(i, fragPosLightSpace[i], norm, lightDir);
|
||||||
color += (diffuse + specular) * (1.0 - shadow);
|
color += (diffuse + specular) * (1.0 - shadow);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -96,17 +121,18 @@ void main() {
|
|||||||
vec3 lightDir = normalize(light[i].pos - fragPos);
|
vec3 lightDir = normalize(light[i].pos - fragPos);
|
||||||
vec3 norm = normalize(normals);
|
vec3 norm = normalize(normals);
|
||||||
float diff = max(dot(norm, lightDir), 0.0);
|
float diff = max(dot(norm, lightDir), 0.0);
|
||||||
vec3 diffuse = light[i].color * (diff * matDiff) * (light[i].strength / 2.0f);
|
vec3 diffuse = light[i].color * (diff * matDiff);
|
||||||
|
|
||||||
vec3 viewDir = normalize(camera.pos - fragPos);
|
vec3 viewDir = normalize(camera.pos - fragPos);
|
||||||
vec3 reflectDir = reflect(-lightDir, norm);
|
vec3 reflectDir = reflect(-lightDir, norm);
|
||||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
|
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
|
||||||
vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.0f);
|
vec3 specular = light[i].color * spec * matSpec;
|
||||||
|
|
||||||
float length = length(light[i].pos - fragPos);
|
float length = length(light[i].pos - fragPos);
|
||||||
float att = clamp(10.0 / length, 0.0, 1.0) * light[i].strength;
|
float att = 1.0 / (1.0 + 0.09 * length + 0.032 * (length * length));
|
||||||
|
|
||||||
color += ((diffuse + specular) * att);
|
float shadow = calcShadowPoint(i, norm, lightDir);
|
||||||
|
color += (((diffuse + specular) * (1.0 - shadow)) * att) * light[i].strength;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec4 fragPos;
|
||||||
|
|
||||||
|
uniform vec3 lightPos;
|
||||||
|
uniform float farPlane;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float dist = length(fragPos.xyz - lightPos);
|
||||||
|
dist /= farPlane;
|
||||||
|
gl_FragDepth = dist;
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(triangles) in;
|
||||||
|
layout(triangle_strip, max_vertices = 18) out;
|
||||||
|
|
||||||
|
uniform mat4 lightSpaceMat[6];
|
||||||
|
|
||||||
|
out vec4 fragPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
for (int face = 0; face < 6; face++) {
|
||||||
|
gl_Layer = face;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
fragPos = gl_in[i].gl_Position;
|
||||||
|
gl_Position = lightSpaceMat[face] * fragPos;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 pos;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = model * vec4(pos, 1.0);
|
||||||
|
}
|
@ -145,7 +145,7 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Application::isKeyHeld(unsigned int code) {
|
bool Application::isKeyHeld(unsigned int code) {
|
||||||
if (code > 7 && code < 164)
|
if (code > 7 && code < 164 && GetForegroundWindow() == m_window)
|
||||||
return GetKeyState(code) & 0x8000;
|
return GetKeyState(code) & 0x8000;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -328,6 +328,7 @@ namespace nf {
|
|||||||
m_currentState = m_states[m_nextState];
|
m_currentState = m_states[m_nextState];
|
||||||
m_currentState->setup(this);
|
m_currentState->setup(this);
|
||||||
m_currentState->onEnter();
|
m_currentState->onEnter();
|
||||||
|
m_currentState->setRunning();
|
||||||
m_renderer->setFade(true, false, false);
|
m_renderer->setFade(true, false, false);
|
||||||
m_stateChange = false;
|
m_stateChange = false;
|
||||||
once = true;
|
once = true;
|
||||||
@ -364,12 +365,12 @@ namespace nf {
|
|||||||
return MNC_CLOSE << 16;
|
return MNC_CLOSE << 16;
|
||||||
}
|
}
|
||||||
case WM_KEYDOWN: {
|
case WM_KEYDOWN: {
|
||||||
if (wParam < 164 && !(lParam & (1 << 30)))
|
if (wParam < 164 && !(lParam & (1 << 30)) && GetFocus() == hWnd)
|
||||||
app->m_keysPressed[wParam] = true;
|
app->m_keysPressed[wParam] = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case WM_KEYUP: {
|
case WM_KEYUP: {
|
||||||
if (wParam < 164)
|
if (wParam < 164 && GetFocus() == hWnd)
|
||||||
app->m_keysPressed[wParam] = false;
|
app->m_keysPressed[wParam] = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -230,9 +230,11 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packName != "base.nfpack")
|
if (packName != "base.nfpack") {
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Asset* AssetPack::operator[](const char* in) {
|
Asset* AssetPack::operator[](const char* in) {
|
||||||
if (m_assets.find(in) == m_assets.end())
|
if (m_assets.find(in) == m_assets.end())
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
namespace nf {
|
namespace nf {
|
||||||
Gamestate::Gamestate() :
|
Gamestate::Gamestate() :
|
||||||
app(nullptr),
|
app(nullptr),
|
||||||
camera(nullptr)
|
camera(nullptr),
|
||||||
|
m_running(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -14,12 +15,21 @@ namespace nf {
|
|||||||
void Gamestate::setup(Application* app) {
|
void Gamestate::setup(Application* app) {
|
||||||
this->app = app;
|
this->app = app;
|
||||||
camera = new Camera(this->app);
|
camera = new Camera(this->app);
|
||||||
|
m_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gamestate::onEnter() {
|
void Gamestate::onEnter() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Gamestate::isRunning() {
|
||||||
|
return m_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gamestate::setRunning() {
|
||||||
|
m_running = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Gamestate::update(double deltaTime) {
|
void Gamestate::update(double deltaTime) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ namespace nf {
|
|||||||
m_vao->push<float>(2);
|
m_vao->push<float>(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +132,6 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button::~Button() {
|
Button::~Button() {
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -114,6 +114,7 @@ namespace nf {
|
|||||||
m_vao->push<float>(3);
|
m_vao->push<float>(3);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +141,6 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Cubemap::~Cubemap() {
|
Cubemap::~Cubemap() {
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,6 +31,7 @@ namespace nf {
|
|||||||
model->loadedModel = m_model;
|
model->loadedModel = m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +98,6 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Entity::~Entity() {
|
Entity::~Entity() {
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ namespace nf {
|
|||||||
m_type = type;
|
m_type = type;
|
||||||
m_strength = (float)strength;
|
m_strength = (float)strength;
|
||||||
|
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +89,6 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Light::~Light() {
|
Light::~Light() {
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -68,6 +68,7 @@ namespace nf {
|
|||||||
m_string = "Loading...";
|
m_string = "Loading...";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +96,7 @@ namespace nf {
|
|||||||
void Text::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight, bool onButton, float buttonWidth, float buttonHeight, const Vec2& buttonPos) {
|
void Text::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight, bool onButton, float buttonWidth, float buttonHeight, const Vec2& buttonPos) {
|
||||||
float scale = windowWidth / 4000.0f;
|
float scale = windowWidth / 4000.0f;
|
||||||
if (onButton)
|
if (onButton)
|
||||||
scale *= buttonHeight / 100.0f;
|
scale *= buttonWidth / 400.0f;
|
||||||
float currX = (float)m_position.x * windowWidth, currY = (float)m_position.y * windowHeight;
|
float currX = (float)m_position.x * windowWidth, currY = (float)m_position.y * windowHeight;
|
||||||
std::string::const_iterator si;
|
std::string::const_iterator si;
|
||||||
if (m_centeredX || m_centeredY) {
|
if (m_centeredX || m_centeredY) {
|
||||||
@ -177,6 +178,6 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text::~Text() {
|
Text::~Text() {
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -47,6 +47,7 @@ namespace nf {
|
|||||||
m_vao->push<float>(2);
|
m_vao->push<float>(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +101,6 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UITexture::~UITexture() {
|
UITexture::~UITexture() {
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,6 +18,8 @@
|
|||||||
namespace nf {
|
namespace nf {
|
||||||
Renderer::Renderer(Application* app) :
|
Renderer::Renderer(Application* app) :
|
||||||
m_shadowMapFBO(0),
|
m_shadowMapFBO(0),
|
||||||
|
m_directionalDepthTexSize(0),
|
||||||
|
m_pointDepthTexSize(0),
|
||||||
m_cubemap(nullptr),
|
m_cubemap(nullptr),
|
||||||
m_fadeIn(false),
|
m_fadeIn(false),
|
||||||
m_fadeOut(false),
|
m_fadeOut(false),
|
||||||
@ -71,6 +73,8 @@ namespace nf {
|
|||||||
|
|
||||||
loadBaseAssets();
|
loadBaseAssets();
|
||||||
|
|
||||||
|
m_directionalDepthTexSize = 4096;
|
||||||
|
m_pointDepthTexSize = 1024;
|
||||||
createShadowMap();
|
createShadowMap();
|
||||||
|
|
||||||
if (!m_app->isCustomWindowIcon()) {
|
if (!m_app->isCustomWindowIcon()) {
|
||||||
@ -176,7 +180,7 @@ namespace nf {
|
|||||||
currLightsDrawn = lightsRemaining;
|
currLightsDrawn = lightsRemaining;
|
||||||
lightsRemaining -= currLightsDrawn;
|
lightsRemaining -= currLightsDrawn;
|
||||||
currLight += (int)currLightsDrawn;
|
currLight += (int)currLightsDrawn;
|
||||||
m_entityShader->setUniform("numberOfLights", (int)currLightsDrawn + 1);
|
m_entityShader->setUniform("numberOfLights", (int)currLightsDrawn);
|
||||||
for (unsigned int j = 0; j < currLightsDrawn; j++) {
|
for (unsigned int j = 0; j < currLightsDrawn; j++) {
|
||||||
m_lights[j + (unsigned int)currLight]->bind(m_entityShader, j);
|
m_lights[j + (unsigned int)currLight]->bind(m_entityShader, j);
|
||||||
}
|
}
|
||||||
@ -269,21 +273,26 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::renderShadowMaps(unsigned int startingLight, unsigned int count) {
|
void Renderer::renderShadowMaps(unsigned int startingLight, unsigned int count) {
|
||||||
glViewport(0, 0, 4096, 4096);
|
float nearP = 0.1f, farP = 400.0f;
|
||||||
float nearP = 0.1f, farP = 500.0f;
|
glm::mat4 directionalLightProj = glm::ortho(-50.0f, 50.0f, -50.0f, 50.0f, nearP, farP);
|
||||||
glm::mat4 lightProj = glm::ortho(-50.0f, 50.0f, -50.0f, 50.0f, nearP, farP);
|
glm::mat4 pointLightProj = glm::perspective(glm::radians(90.0f), 1.0f, nearP, farP);
|
||||||
glm::mat4 lightView;
|
glm::mat4 lightView;
|
||||||
glm::mat4 lightSpaceMat;
|
glm::mat4 lightSpaceMat;
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMaps[i], 0);
|
Light::Type type = m_lights[i]->getType();
|
||||||
|
unsigned int tex = type == Light::Type::DIRECTIONAL ? m_directionalShadowMaps[i] : m_pointShadowMaps[i];
|
||||||
|
switch (type) {
|
||||||
|
case Light::Type::DIRECTIONAL: {
|
||||||
|
glViewport(0, 0, m_directionalDepthTexSize, m_directionalDepthTexSize);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
|
||||||
glDrawBuffer(GL_NONE);
|
glDrawBuffer(GL_NONE);
|
||||||
glReadBuffer(GL_NONE);
|
glReadBuffer(GL_NONE);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
Vec3 posTemp = m_lights[startingLight + i]->getPosition();
|
Vec3 posTemp = m_lights[startingLight + i]->getPosition();
|
||||||
glm::vec3 posTemp2(posTemp.x, posTemp.y, posTemp.z);
|
glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
|
||||||
lightView = glm::lookAt(posTemp2, glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));
|
lightView = glm::lookAt(lightPos, glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));
|
||||||
lightSpaceMat = lightProj * lightView;
|
lightSpaceMat = directionalLightProj * lightView;
|
||||||
m_directionalShadowShader->setUniform("lightSpace", lightSpaceMat);
|
m_directionalShadowShader->setUniform("lightSpace", lightSpaceMat);
|
||||||
std::string stringPos = "lightSpaceMat[";
|
std::string stringPos = "lightSpaceMat[";
|
||||||
stringPos += std::to_string(i);
|
stringPos += std::to_string(i);
|
||||||
@ -294,10 +303,48 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
stringPos = "light[";
|
stringPos = "light[";
|
||||||
stringPos += std::to_string(i);
|
stringPos += std::to_string(i);
|
||||||
stringPos += "].depthTex";
|
stringPos += "].directionalDepthTex";
|
||||||
glActiveTexture(GL_TEXTURE3 + i);
|
glActiveTexture(GL_TEXTURE3 + i);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_shadowMaps[i]);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
m_entityShader->setUniform(stringPos, 3 + (int)i);
|
m_entityShader->setUniform(stringPos, 3 + (int)i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Light::Type::POINT: {
|
||||||
|
glViewport(0, 0, m_pointDepthTexSize, m_pointDepthTexSize);
|
||||||
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, 0);
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
|
glReadBuffer(GL_NONE);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
Vec3 posTemp = m_lights[startingLight + i]->getPosition();
|
||||||
|
glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
|
||||||
|
std::vector<glm::mat4> lightSpaceMats;
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
for (int j = 0; j < 6; j++) {
|
||||||
|
std::string stringPos = "lightSpaceMat[";
|
||||||
|
stringPos += std::to_string(j);
|
||||||
|
stringPos += "]";
|
||||||
|
m_pointShadowShader->setUniform(stringPos, lightSpaceMats[j]);
|
||||||
|
}
|
||||||
|
m_pointShadowShader->setUniform("farPlane", farP);
|
||||||
|
m_pointShadowShader->setUniform("lightPos", lightPos);
|
||||||
|
for (Entity* curr : m_lGame) {
|
||||||
|
curr->render(m_pointShadowShader, true);
|
||||||
|
}
|
||||||
|
std::string stringPos = "light[";
|
||||||
|
stringPos += std::to_string(i);
|
||||||
|
stringPos += "].pointDepthTex";
|
||||||
|
glActiveTexture(GL_TEXTURE3 + i);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
||||||
|
m_entityShader->setUniform(stringPos, 3 + (int)i);
|
||||||
|
m_entityShader->setUniform("farPlane", farP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_entityShader->setUniform("numMats", (int)count);
|
m_entityShader->setUniform("numMats", (int)count);
|
||||||
}
|
}
|
||||||
@ -322,6 +369,10 @@ namespace nf {
|
|||||||
const char* directionalShadowVertex = m_baseAP["directionalShadowVertex.shader"]->data;
|
const char* directionalShadowVertex = m_baseAP["directionalShadowVertex.shader"]->data;
|
||||||
const char* directionalShadowFragment = m_baseAP["directionalShadowFragment.shader"]->data;
|
const char* directionalShadowFragment = m_baseAP["directionalShadowFragment.shader"]->data;
|
||||||
m_directionalShadowShader = new Shader(directionalShadowVertex, directionalShadowFragment);
|
m_directionalShadowShader = new Shader(directionalShadowVertex, directionalShadowFragment);
|
||||||
|
const char* pointShadowVertex = m_baseAP["pointShadowVertex.shader"]->data;
|
||||||
|
const char* pointShadowGeometry = m_baseAP["pointShadowGeometry.shader"]->data;
|
||||||
|
const char* pointShadowFragment = m_baseAP["pointShadowFragment.shader"]->data;
|
||||||
|
m_pointShadowShader = new Shader(pointShadowVertex, pointShadowFragment, pointShadowGeometry);
|
||||||
|
|
||||||
BaseAssets::cube = (AModel*)m_baseAP["cube.obj"];
|
BaseAssets::cube = (AModel*)m_baseAP["cube.obj"];
|
||||||
BaseAssets::plane = (AModel*)m_baseAP["plane.obj"];
|
BaseAssets::plane = (AModel*)m_baseAP["plane.obj"];
|
||||||
@ -340,17 +391,28 @@ namespace nf {
|
|||||||
glGenFramebuffers(1, &m_shadowMapFBO);
|
glGenFramebuffers(1, &m_shadowMapFBO);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
||||||
for (unsigned int i = 0; i < m_texSlots; i++) {
|
for (unsigned int i = 0; i < m_texSlots; i++) {
|
||||||
unsigned int depthMap;
|
unsigned int directionalDepthMap, pointDepthMap;
|
||||||
glGenTextures(1, &depthMap);
|
glGenTextures(1, &directionalDepthMap);
|
||||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
glGenTextures(1, &pointDepthMap);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 4096, 4096, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
glBindTexture(GL_TEXTURE_2D, directionalDepthMap);
|
||||||
|
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, m_directionalDepthTexSize, m_directionalDepthTexSize);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
m_shadowMaps.push_back(depthMap);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, pointDepthMap);
|
||||||
|
glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT24, m_pointDepthTexSize, m_pointDepthTexSize);
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
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);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
m_directionalShadowMaps.push_back(directionalDepthMap);
|
||||||
|
m_pointShadowMaps.push_back(pointDepthMap);
|
||||||
}
|
}
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,30 @@
|
|||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
namespace nf {
|
namespace nf {
|
||||||
Shader::Shader(const char* vertexSource, const char* fragmentSource) {
|
Shader::Shader(const char* vertexSource, const char* fragmentSource, const char* geometrySource) {
|
||||||
m_id = glCreateProgram();
|
m_id = glCreateProgram();
|
||||||
unsigned int vs = glCreateShader(GL_VERTEX_SHADER);
|
unsigned int vs = glCreateShader(GL_VERTEX_SHADER);
|
||||||
unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
|
unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
unsigned int gs = 0;
|
||||||
glShaderSource(vs, 1, &vertexSource, nullptr);
|
glShaderSource(vs, 1, &vertexSource, nullptr);
|
||||||
glShaderSource(fs, 1, &fragmentSource, nullptr);
|
glShaderSource(fs, 1, &fragmentSource, nullptr);
|
||||||
glCompileShader(vs);
|
glCompileShader(vs);
|
||||||
glCompileShader(fs);
|
glCompileShader(fs);
|
||||||
for (int i = 0; i < 2; i++) {
|
if (geometrySource) {
|
||||||
unsigned int curr = (i == 0 ? vs : fs);
|
gs = glCreateShader(GL_GEOMETRY_SHADER);
|
||||||
|
glShaderSource(gs, 1, &geometrySource, nullptr);
|
||||||
|
glCompileShader(gs);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
unsigned int curr;
|
||||||
|
if (i == 0)
|
||||||
|
curr = vs;
|
||||||
|
else if (i == 1)
|
||||||
|
curr = fs;
|
||||||
|
else if (i == 2)
|
||||||
|
curr = gs;
|
||||||
|
if (curr == 0)
|
||||||
|
break;
|
||||||
int result;
|
int result;
|
||||||
glGetShaderiv(curr, GL_COMPILE_STATUS, &result);
|
glGetShaderiv(curr, GL_COMPILE_STATUS, &result);
|
||||||
if (result != GL_TRUE) {
|
if (result != GL_TRUE) {
|
||||||
@ -28,6 +42,7 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
glAttachShader(m_id, vs);
|
glAttachShader(m_id, vs);
|
||||||
glAttachShader(m_id, fs);
|
glAttachShader(m_id, fs);
|
||||||
|
if (gs) glAttachShader(m_id, gs);
|
||||||
glLinkProgram(m_id);
|
glLinkProgram(m_id);
|
||||||
glValidateProgram(m_id);
|
glValidateProgram(m_id);
|
||||||
int result;
|
int result;
|
||||||
@ -39,8 +54,14 @@ namespace nf {
|
|||||||
glGetProgramInfoLog(m_id, length, &length, message);
|
glGetProgramInfoLog(m_id, length, &length, message);
|
||||||
Error("OpenGL Error: " + (std::string)message);
|
Error("OpenGL Error: " + (std::string)message);
|
||||||
}
|
}
|
||||||
|
glDetachShader(m_id, vs);
|
||||||
|
glDetachShader(m_id, fs);
|
||||||
glDeleteShader(vs);
|
glDeleteShader(vs);
|
||||||
glDeleteShader(fs);
|
glDeleteShader(fs);
|
||||||
|
if (gs) {
|
||||||
|
glDetachShader(m_id, gs);
|
||||||
|
glDeleteShader(gs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::bind() {
|
void Shader::bind() {
|
||||||
|
@ -17,6 +17,8 @@ namespace nf {
|
|||||||
void setup(Application* app);
|
void setup(Application* app);
|
||||||
|
|
||||||
virtual void onEnter();
|
virtual void onEnter();
|
||||||
|
bool isRunning();
|
||||||
|
void setRunning();
|
||||||
|
|
||||||
virtual void update(double deltaTime);
|
virtual void update(double deltaTime);
|
||||||
Camera* getCamera();
|
Camera* getCamera();
|
||||||
@ -29,5 +31,6 @@ namespace nf {
|
|||||||
protected:
|
protected:
|
||||||
Application* app;
|
Application* app;
|
||||||
Camera* camera;
|
Camera* camera;
|
||||||
|
bool m_running;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -52,7 +52,10 @@ namespace nf {
|
|||||||
AssetPack m_baseAP;
|
AssetPack m_baseAP;
|
||||||
|
|
||||||
unsigned int m_shadowMapFBO;
|
unsigned int m_shadowMapFBO;
|
||||||
std::vector<unsigned int> m_shadowMaps;
|
int m_directionalDepthTexSize;
|
||||||
|
int m_pointDepthTexSize;
|
||||||
|
std::vector<unsigned int> m_directionalShadowMaps;
|
||||||
|
std::vector<unsigned int> m_pointShadowMaps;
|
||||||
unsigned int m_texSlots;
|
unsigned int m_texSlots;
|
||||||
|
|
||||||
std::vector<Light*> m_lights;
|
std::vector<Light*> m_lights;
|
||||||
@ -65,6 +68,7 @@ namespace nf {
|
|||||||
Shader* m_cubemapShader;
|
Shader* m_cubemapShader;
|
||||||
Shader* m_fadeShader;
|
Shader* m_fadeShader;
|
||||||
Shader* m_directionalShadowShader;
|
Shader* m_directionalShadowShader;
|
||||||
|
Shader* m_pointShadowShader;
|
||||||
|
|
||||||
bool m_fadeIn, m_fadeOut;
|
bool m_fadeIn, m_fadeOut;
|
||||||
bool m_fadeNoText;
|
bool m_fadeNoText;
|
||||||
|
@ -45,7 +45,10 @@ namespace nf {
|
|||||||
AssetPack m_baseAP;
|
AssetPack m_baseAP;
|
||||||
|
|
||||||
unsigned int m_shadowMapFBO;
|
unsigned int m_shadowMapFBO;
|
||||||
std::vector<unsigned int> m_shadowMaps;
|
int m_directionalDepthTexSize;
|
||||||
|
int m_pointDepthTexSize;
|
||||||
|
std::vector<unsigned int> m_directionalShadowMaps;
|
||||||
|
std::vector<unsigned int> m_pointShadowMaps;
|
||||||
unsigned int m_texSlots;
|
unsigned int m_texSlots;
|
||||||
|
|
||||||
std::vector<Light*> m_lights;
|
std::vector<Light*> m_lights;
|
||||||
@ -58,6 +61,7 @@ namespace nf {
|
|||||||
Shader* m_cubemapShader;
|
Shader* m_cubemapShader;
|
||||||
Shader* m_fadeShader;
|
Shader* m_fadeShader;
|
||||||
Shader* m_directionalShadowShader;
|
Shader* m_directionalShadowShader;
|
||||||
|
Shader* m_pointShadowShader;
|
||||||
|
|
||||||
bool m_fadeIn, m_fadeOut;
|
bool m_fadeIn, m_fadeOut;
|
||||||
bool m_fadeNoText;
|
bool m_fadeNoText;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
namespace nf {
|
namespace nf {
|
||||||
class Shader {
|
class Shader {
|
||||||
public:
|
public:
|
||||||
Shader(const char* vertexSource, const char* fragmentSource);
|
Shader(const char* vertexSource, const char* fragmentSource, const char* geometrySource = nullptr);
|
||||||
|
|
||||||
void bind();
|
void bind();
|
||||||
void setUniform(const std::string& name, glm::mat4& data);
|
void setUniform(const std::string& name, glm::mat4& data);
|
||||||
|
Reference in New Issue
Block a user