|
@@ -58,6 +58,7 @@ struct Shaders
|
|
|
world("resources/shader/worldVertex.vs", "resources/shader/worldFragment.fs"),
|
|
|
ssao("resources/shader/ssaoVertex.vs", "resources/shader/ssaoFragment.fs"),
|
|
|
ssaoBlur("resources/shader/ssaoBlurVertex.vs", "resources/shader/ssaoBlurFragment.fs"),
|
|
|
+ shadow("resources/shader/worldShadowVertex.vs", "resources/shader/worldShadowFragment.fs"),
|
|
|
postWorld("resources/shader/worldPostVertex.vs", "resources/shader/worldPostFragment.fs"),
|
|
|
text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs")
|
|
|
{
|
|
@@ -66,8 +67,10 @@ struct Shaders
|
|
|
Shader world;
|
|
|
Shader ssao;
|
|
|
Shader ssaoBlur;
|
|
|
+ Shader shadow;
|
|
|
Shader postWorld;
|
|
|
Shader text;
|
|
|
+ bool once = true;
|
|
|
|
|
|
float worldProj[16] =
|
|
|
{
|
|
@@ -85,9 +88,26 @@ struct Shaders
|
|
|
0.0f, 0.0f, 0.0f, 1.0f
|
|
|
};
|
|
|
|
|
|
+ float worldShadowProj[16] =
|
|
|
+ {
|
|
|
+ 1.0f, 0.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 1.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 0.0f, 1.0f, -1.0f,
|
|
|
+ 0.0f, 0.0f, 1.0, 0.0f
|
|
|
+ };
|
|
|
+
|
|
|
+ float worldShadowView[16]=
|
|
|
+ {
|
|
|
+ 1.0f, 0.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 1.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 0.0f, 1.0f, 0.0f,
|
|
|
+ 0.0f, 0.0f, 0.0f, 1.0f
|
|
|
+ };
|
|
|
+
|
|
|
bool isValid() const
|
|
|
{
|
|
|
- return world.isValid() && ssao.isValid() && ssaoBlur.isValid() && postWorld.isValid() && text.isValid();
|
|
|
+ return world.isValid() && ssao.isValid() && ssaoBlur.isValid() &&
|
|
|
+ shadow.isValid() && postWorld.isValid() && text.isValid();
|
|
|
}
|
|
|
|
|
|
void updateWorldProjection()
|
|
@@ -99,6 +119,14 @@ struct Shaders
|
|
|
worldProj[5] = q;
|
|
|
worldProj[10] = (nearClip + farClip) / (nearClip - farClip);
|
|
|
worldProj[14] = (2.0f * nearClip * farClip) / (nearClip - farClip);
|
|
|
+
|
|
|
+ if(once)
|
|
|
+ {
|
|
|
+ worldShadowProj[0] = q / aspect;
|
|
|
+ worldShadowProj[5] = q;
|
|
|
+ worldShadowProj[10] = (nearClip + farClip) / (nearClip - farClip);
|
|
|
+ worldShadowProj[14] = (2.0f * nearClip * farClip) / (nearClip - farClip);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void updateWorldView(float lag, Camera& cam)
|
|
@@ -120,14 +148,32 @@ struct Shaders
|
|
|
worldView[12] = right.dotInverse(pos);
|
|
|
worldView[13] = up.dotInverse(pos);
|
|
|
worldView[14] = back.dotInverse(pos);
|
|
|
+
|
|
|
+ if(once)
|
|
|
+ {
|
|
|
+ once = false;
|
|
|
+ worldShadowView[0] = right.getX();
|
|
|
+ worldShadowView[1] = up.getX();
|
|
|
+ worldShadowView[2] = back.getX();
|
|
|
+ worldShadowView[4] = right.getY();
|
|
|
+ worldShadowView[5] = up.getY();
|
|
|
+ worldShadowView[6] = back.getY();
|
|
|
+ worldShadowView[8] = right.getZ();
|
|
|
+ worldShadowView[9] = up.getZ();
|
|
|
+ worldShadowView[10] = back.getZ();
|
|
|
+ worldShadowView[12] = right.dotInverse(pos);
|
|
|
+ worldShadowView[13] = up.dotInverse(pos);
|
|
|
+ worldShadowView[14] = back.dotInverse(pos);
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
|
|
|
struct Framebuffers
|
|
|
{
|
|
|
Framebuffers(u32 w, u32 h) : world(w, h, Framebuffer::POSITION |
|
|
|
- Framebuffer::NORMAL | Framebuffer::COLOR | Framebuffer::DEPTH24_STENCIL8),
|
|
|
- ssao(w, h, Framebuffer::RED), ssaoBlur(w, h, Framebuffer::RED)
|
|
|
+ Framebuffer::NORMAL | Framebuffer::COLOR | Framebuffer::RED | Framebuffer::DEPTH24_STENCIL8),
|
|
|
+ ssao(w, h, Framebuffer::RED), ssaoBlur(w, h, Framebuffer::RED),
|
|
|
+ shadow(w, h, Framebuffer::DEPTH24_STENCIL8)
|
|
|
{
|
|
|
}
|
|
|
|
|
@@ -136,6 +182,7 @@ struct Framebuffers
|
|
|
world.resize(w, h);
|
|
|
ssao.resize(w, h);
|
|
|
ssaoBlur.resize(w, h);
|
|
|
+ shadow.resize(w, h);
|
|
|
}
|
|
|
|
|
|
bool isValid() const
|
|
@@ -146,6 +193,7 @@ struct Framebuffers
|
|
|
Framebuffer world;
|
|
|
Framebuffer ssao;
|
|
|
Framebuffer ssaoBlur;
|
|
|
+ Framebuffer shadow;
|
|
|
};
|
|
|
|
|
|
struct InternGame
|
|
@@ -275,15 +323,31 @@ static void tick(InternGame& game)
|
|
|
mButtons.postTick();
|
|
|
}
|
|
|
|
|
|
+static void renderShadow(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
|
|
|
+{
|
|
|
+ fb.shadow.bind();
|
|
|
+ glEnable(GL_DEPTH_TEST);
|
|
|
+ shaders.shadow.use();
|
|
|
+ shaders.shadow.setMatrix("proj", shaders.worldShadowProj);
|
|
|
+ shaders.shadow.setMatrix("view", shaders.worldShadowView);
|
|
|
+ glEnable(GL_POLYGON_OFFSET_FILL);
|
|
|
+ glPolygonOffset(2.0f, 4.0f);
|
|
|
+ game.game.renderWorld(lag, game.model, shaders.shadow);
|
|
|
+ glDisable(GL_POLYGON_OFFSET_FILL);
|
|
|
+}
|
|
|
+
|
|
|
static void renderWorld(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
|
|
|
{
|
|
|
fb.world.bind();
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
shaders.world.use();
|
|
|
+ shaders.world.setMatrix("projShadow", shaders.worldShadowProj);
|
|
|
+ shaders.world.setMatrix("viewShadow", shaders.worldShadowView);
|
|
|
shaders.world.setMatrix("proj", shaders.worldProj);
|
|
|
shaders.world.setMatrix("view", shaders.worldView);
|
|
|
game.model.clear();
|
|
|
shaders.world.setMatrix("model", game.model.get().getValues());
|
|
|
+ fb.shadow.bindDepthTexture(1);
|
|
|
game.game.renderWorld(lag, game.model, shaders.world);
|
|
|
}
|
|
|
|
|
@@ -305,7 +369,6 @@ static void renderSSAO(Shaders& shaders, InternGame& game, Framebuffers& fb)
|
|
|
// ssao blur
|
|
|
shaders.ssaoBlur.use();
|
|
|
fb.ssao.bindRedTexture(0);
|
|
|
- fb.world.bindColorTexture(1);
|
|
|
fb.ssaoBlur.bind();
|
|
|
game.rectangle.draw();
|
|
|
}
|
|
@@ -317,6 +380,7 @@ static void renderPostWorld(Shaders& shaders, InternGame& game, Framebuffers& fb
|
|
|
shaders.postWorld.use();
|
|
|
fb.world.bindColorTexture(0);
|
|
|
fb.ssaoBlur.bindRedTexture(1);
|
|
|
+ fb.world.bindRedTexture(2);
|
|
|
shaders.postWorld.setInt("useSSAO", useSSAO);
|
|
|
game.rectangle.draw();
|
|
|
}
|
|
@@ -352,6 +416,7 @@ static void renderTick(float lag, Shaders& shaders, InternGame& game, Framebuffe
|
|
|
shaders.updateWorldProjection();
|
|
|
shaders.updateWorldView(lag, game.cam);
|
|
|
|
|
|
+ renderShadow(lag, shaders, game, fb);
|
|
|
renderWorld(lag, shaders, game, fb);
|
|
|
if(useSSAO)
|
|
|
{
|