|
@@ -4,6 +4,7 @@
|
|
#include <unordered_map>
|
|
#include <unordered_map>
|
|
#include <cmath>
|
|
#include <cmath>
|
|
#include <cstring>
|
|
#include <cstring>
|
|
|
|
+#include <array>
|
|
|
|
|
|
#include "common/utils/Types.h"
|
|
#include "common/utils/Types.h"
|
|
#include "client/GameClient.h"
|
|
#include "client/GameClient.h"
|
|
@@ -62,6 +63,13 @@ struct Shaders
|
|
postWorld("resources/shader/worldPostVertex.vs", "resources/shader/worldPostFragment.fs"),
|
|
postWorld("resources/shader/worldPostVertex.vs", "resources/shader/worldPostFragment.fs"),
|
|
text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs")
|
|
text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs")
|
|
{
|
|
{
|
|
|
|
+ worldProj.set(11, -1.0f);
|
|
|
|
+ worldProj.set(14, 1.0f);
|
|
|
|
+ worldProj.set(15, 0.0f);
|
|
|
|
+
|
|
|
|
+ worldShadowProj.set(11, -1.0f);
|
|
|
|
+ worldShadowProj.set(14, 1.0f);
|
|
|
|
+ worldShadowProj.set(15, 0.0f);
|
|
}
|
|
}
|
|
|
|
|
|
Shader world;
|
|
Shader world;
|
|
@@ -72,37 +80,12 @@ struct Shaders
|
|
Shader text;
|
|
Shader text;
|
|
bool once = true;
|
|
bool once = true;
|
|
|
|
|
|
- float worldProj[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 worldView[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
|
|
|
|
- };
|
|
|
|
|
|
+ Matrix worldProj;
|
|
|
|
+ Matrix worldView;
|
|
|
|
|
|
- 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
|
|
|
|
- };
|
|
|
|
|
|
+ Matrix worldShadowProj;
|
|
|
|
+ Matrix worldShadowView;
|
|
|
|
+ Matrix worldShadowProjView;
|
|
|
|
|
|
bool isValid() const
|
|
bool isValid() const
|
|
{
|
|
{
|
|
@@ -115,17 +98,17 @@ struct Shaders
|
|
float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
|
|
float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
|
|
float q = 1.0f / tan;
|
|
float q = 1.0f / tan;
|
|
float aspect = (float) width / height;
|
|
float aspect = (float) width / height;
|
|
- worldProj[0] = q / aspect;
|
|
|
|
- worldProj[5] = q;
|
|
|
|
- worldProj[10] = (nearClip + farClip) / (nearClip - farClip);
|
|
|
|
- worldProj[14] = (2.0f * nearClip * farClip) / (nearClip - farClip);
|
|
|
|
|
|
+ worldProj.set(0, q / aspect);
|
|
|
|
+ worldProj.set(5, q);
|
|
|
|
+ worldProj.set(10,(nearClip + farClip) / (nearClip - farClip));
|
|
|
|
+ worldProj.set(14, (2.0f * nearClip * farClip) / (nearClip - farClip));
|
|
|
|
|
|
if(once)
|
|
if(once)
|
|
{
|
|
{
|
|
- worldShadowProj[0] = q / aspect;
|
|
|
|
- worldShadowProj[5] = q;
|
|
|
|
- worldShadowProj[10] = (nearClip + farClip) / (nearClip - farClip);
|
|
|
|
- worldShadowProj[14] = (2.0f * nearClip * farClip) / (nearClip - farClip);
|
|
|
|
|
|
+ worldShadowProj.set(0, q / aspect);
|
|
|
|
+ worldShadowProj.set(5, q);
|
|
|
|
+ worldShadowProj.set(10,(nearClip + farClip) / (nearClip - farClip));
|
|
|
|
+ worldShadowProj.set(14, (2.0f * nearClip * farClip) / (nearClip - farClip));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -136,44 +119,45 @@ struct Shaders
|
|
const Vector up = cam.getUp();
|
|
const Vector up = cam.getUp();
|
|
const Vector back = cam.getBack();
|
|
const Vector back = cam.getBack();
|
|
const Vector pos = cam.getPosition();
|
|
const Vector pos = cam.getPosition();
|
|
- worldView[0] = right.getX();
|
|
|
|
- worldView[1] = up.getX();
|
|
|
|
- worldView[2] = back.getX();
|
|
|
|
- worldView[4] = right.getY();
|
|
|
|
- worldView[5] = up.getY();
|
|
|
|
- worldView[6] = back.getY();
|
|
|
|
- worldView[8] = right.getZ();
|
|
|
|
- worldView[9] = up.getZ();
|
|
|
|
- worldView[10] = back.getZ();
|
|
|
|
- worldView[12] = right.dotInverse(pos);
|
|
|
|
- worldView[13] = up.dotInverse(pos);
|
|
|
|
- worldView[14] = back.dotInverse(pos);
|
|
|
|
|
|
+ worldView.set(0, right.getX());
|
|
|
|
+ worldView.set(1, up.getX());
|
|
|
|
+ worldView.set(2, back.getX());
|
|
|
|
+ worldView.set(4, right.getY());
|
|
|
|
+ worldView.set(5, up.getY());
|
|
|
|
+ worldView.set(6, back.getY());
|
|
|
|
+ worldView.set(8, right.getZ());
|
|
|
|
+ worldView.set(9, up.getZ());
|
|
|
|
+ worldView.set(10, back.getZ());
|
|
|
|
+ worldView.set(12, right.dotInverse(pos));
|
|
|
|
+ worldView.set(13, up.dotInverse(pos));
|
|
|
|
+ worldView.set(14, back.dotInverse(pos));
|
|
|
|
|
|
if(once)
|
|
if(once)
|
|
{
|
|
{
|
|
once = false;
|
|
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);
|
|
|
|
|
|
+ worldShadowView.set(0, right.getX());
|
|
|
|
+ worldShadowView.set(1, up.getX());
|
|
|
|
+ worldShadowView.set(2, back.getX());
|
|
|
|
+ worldShadowView.set(4, right.getY());
|
|
|
|
+ worldShadowView.set(5, up.getY());
|
|
|
|
+ worldShadowView.set(6, back.getY());
|
|
|
|
+ worldShadowView.set(8, right.getZ());
|
|
|
|
+ worldShadowView.set(9, up.getZ());
|
|
|
|
+ worldShadowView.set(10, back.getZ());
|
|
|
|
+ worldShadowView.set(12, right.dotInverse(pos));
|
|
|
|
+ worldShadowView.set(13, up.dotInverse(pos));
|
|
|
|
+ worldShadowView.set(14, back.dotInverse(pos));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
struct Framebuffers
|
|
struct Framebuffers
|
|
{
|
|
{
|
|
- Framebuffers(u32 w, u32 h) : world(w, h, Framebuffer::POSITION |
|
|
|
|
- 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)
|
|
|
|
|
|
+ Framebuffers(u32 w, u32 h) :
|
|
|
|
+ world(w, h, Framebuffer::POSITION | Framebuffer::NORMAL | Framebuffer::COLOR | Framebuffer::RED | Framebuffer::DEPTH24_STENCIL8, 0),
|
|
|
|
+ ssao(w, h, Framebuffer::RED, 0),
|
|
|
|
+ ssaoBlur(w, h, Framebuffer::RED, 0),
|
|
|
|
+ shadow(w, h, Framebuffer::DEPTH24_STENCIL8, GL_LEQUAL)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
@@ -328,8 +312,9 @@ static void renderShadow(float lag, Shaders& shaders, InternGame& game, Framebuf
|
|
fb.shadow.bind();
|
|
fb.shadow.bind();
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_DEPTH_TEST);
|
|
shaders.shadow.use();
|
|
shaders.shadow.use();
|
|
- shaders.shadow.setMatrix("proj", shaders.worldShadowProj);
|
|
|
|
- shaders.shadow.setMatrix("view", shaders.worldShadowView);
|
|
|
|
|
|
+ shaders.worldShadowProjView = shaders.worldShadowProj;
|
|
|
|
+ shaders.worldShadowProjView.mul(shaders.worldShadowView);
|
|
|
|
+ shaders.shadow.setMatrix("projView", shaders.worldShadowProjView.getValues());
|
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
|
glPolygonOffset(2.0f, 4.0f);
|
|
glPolygonOffset(2.0f, 4.0f);
|
|
game.game.renderWorld(lag, game.model, shaders.shadow);
|
|
game.game.renderWorld(lag, game.model, shaders.shadow);
|
|
@@ -341,10 +326,15 @@ static void renderWorld(float lag, Shaders& shaders, InternGame& game, Framebuff
|
|
fb.world.bind();
|
|
fb.world.bind();
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_DEPTH_TEST);
|
|
shaders.world.use();
|
|
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);
|
|
|
|
|
|
+
|
|
|
|
+ Matrix rWorldShadowProjView;
|
|
|
|
+ rWorldShadowProjView.translate(0.5f, 0.5f, 0.5f);
|
|
|
|
+ rWorldShadowProjView.scale(0.5f, 0.5f, 0.5f);
|
|
|
|
+ rWorldShadowProjView.mul(shaders.worldShadowProjView);
|
|
|
|
+
|
|
|
|
+ shaders.world.setMatrix("projViewShadow", rWorldShadowProjView.getValues());
|
|
|
|
+ shaders.world.setMatrix("proj", shaders.worldProj.getValues());
|
|
|
|
+ shaders.world.setMatrix("view", shaders.worldView.getValues());
|
|
game.model.clear();
|
|
game.model.clear();
|
|
shaders.world.setMatrix("model", game.model.get().getValues());
|
|
shaders.world.setMatrix("model", game.model.get().getValues());
|
|
fb.shadow.bindDepthTexture(1);
|
|
fb.shadow.bindDepthTexture(1);
|
|
@@ -355,8 +345,13 @@ static void renderSSAO(Shaders& shaders, InternGame& game, Framebuffers& fb)
|
|
{
|
|
{
|
|
// ssao
|
|
// ssao
|
|
shaders.ssao.use();
|
|
shaders.ssao.use();
|
|
- shaders.ssao.setMatrix("view", shaders.worldView);
|
|
|
|
- shaders.ssao.setMatrix("proj", shaders.worldProj);
|
|
|
|
|
|
+
|
|
|
|
+ Matrix rProj;
|
|
|
|
+ rProj.translate(0.5f, 0.5f, 0.5f);
|
|
|
|
+ rProj.scale(0.5f, 0.5f, 0.5f);
|
|
|
|
+ rProj.mul(shaders.worldProj);
|
|
|
|
+
|
|
|
|
+ shaders.ssao.setMatrix("proj", rProj.getValues());
|
|
shaders.ssao.setInt("width", width);
|
|
shaders.ssao.setInt("width", width);
|
|
shaders.ssao.setInt("height", height);
|
|
shaders.ssao.setInt("height", height);
|
|
fb.world.bindPositionTexture(0);
|
|
fb.world.bindPositionTexture(0);
|
|
@@ -385,6 +380,11 @@ static void renderPostWorld(Shaders& shaders, InternGame& game, Framebuffers& fb
|
|
game.rectangle.draw();
|
|
game.rectangle.draw();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static u64 last = 0;
|
|
|
|
+static u64 sum = 0;
|
|
|
|
+static u64 tindex = 0;
|
|
|
|
+static std::array<u64, 128> values;
|
|
|
|
+
|
|
static void renderTextOverlay(float lag, Shaders& shaders, InternGame& game)
|
|
static void renderTextOverlay(float lag, Shaders& shaders, InternGame& game)
|
|
{
|
|
{
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_DEPTH_TEST);
|
|
@@ -402,12 +402,22 @@ static void renderTextOverlay(float lag, Shaders& shaders, InternGame& game)
|
|
glEnable(GL_BLEND);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glBlendEquation(GL_FUNC_ADD);
|
|
glBlendEquation(GL_FUNC_ADD);
|
|
|
|
+ char buffer[50];
|
|
|
|
+ snprintf(buffer, 50, "FPS: %f", 128000000000.0f / sum);
|
|
|
|
+ game.fontRenderer.drawString(20, 20, buffer);
|
|
game.game.renderTextOverlay(lag, game.model, shaders.text, game.fontRenderer);
|
|
game.game.renderTextOverlay(lag, game.model, shaders.text, game.fontRenderer);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_BLEND);
|
|
}
|
|
}
|
|
|
|
|
|
static void renderTick(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
|
|
static void renderTick(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
|
|
{
|
|
{
|
|
|
|
+ u64 current = getTimeNanos();
|
|
|
|
+ sum -= values[tindex];
|
|
|
|
+ values[tindex] = current - last;
|
|
|
|
+ sum += values[tindex];
|
|
|
|
+ last = current;
|
|
|
|
+ tindex = (tindex + 1) & (127);
|
|
|
|
+
|
|
if(resize)
|
|
if(resize)
|
|
{
|
|
{
|
|
fb.resize(width, height);
|
|
fb.resize(width, height);
|
|
@@ -440,6 +450,7 @@ static void loop()
|
|
}
|
|
}
|
|
InternGame game;
|
|
InternGame game;
|
|
|
|
|
|
|
|
+ last = getTimeNanos();
|
|
u64 lastTime = getTimeNanos();
|
|
u64 lastTime = getTimeNanos();
|
|
u64 lag = 0;
|
|
u64 lag = 0;
|
|
while(!glfwWindowShouldClose(client.window))
|
|
while(!glfwWindowShouldClose(client.window))
|