245 lines
6.9 KiB
C++
245 lines
6.9 KiB
C++
//
|
|
// Created by aurailus on 17/12/18.
|
|
//
|
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <util/Timer.h>
|
|
|
|
#include "Renderer.h"
|
|
|
|
Renderer::Renderer() : Renderer({ 1366, 768 }) {};
|
|
|
|
Renderer::Renderer(glm::ivec2 win) :
|
|
// activeTexture(nullptr),
|
|
window(win),
|
|
|
|
world(win, 2),
|
|
entity(win, 2),
|
|
ssao(win, 1, 24),
|
|
blur(win, 1),
|
|
light(win, 2) {
|
|
|
|
camera.create(window.getSize().x, window.getSize().y, glm::vec3(0, 1, 0));
|
|
|
|
ssao.createFromFile("../assets/shader/post/passThrough.vs", "../assets/shader/post/ssaoCalc.fs");
|
|
blur.createFromFile("../assets/shader/post/passThrough.vs", "../assets/shader/post/ssaoBlur.fs");
|
|
light.createFromFile("../assets/shader/post/passThrough.vs", "../assets/shader/post/deferredLighting.fs");
|
|
world.createFromFile("../assets/shader/world/world.vs", "../assets/shader/world/world.fs",
|
|
"../assets/shader/world/world.gs");
|
|
entity.createFromFile("../assets/shader/world/entity.vs", "../assets/shader/world/entity.fs");
|
|
|
|
guiShader = Shader();
|
|
guiShader.createFromFile("../assets/shader/ortho/hud.vs", "../assets/shader/ortho/hud.fs");
|
|
|
|
gu.matrix = camera.getOrthographicMatrix();
|
|
gu.ortho = guiShader.get("ortho");
|
|
gu.model = guiShader.get("model");
|
|
gu.bones = guiShader.get("uBones");
|
|
gu.clipBounds = guiShader.get("uClipBounds");
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
callbacks.emplace_back(window.resize.bind([&](glm::ivec2 win) {
|
|
ssao.windowResized(win);
|
|
blur.windowResized(win);
|
|
light.windowResized(win);
|
|
world.windowResized(win);
|
|
|
|
camera.changeWindowDimensions(win);
|
|
|
|
gu.matrix = camera.getOrthographicMatrix();
|
|
}));
|
|
|
|
//VSync 1 = On, 0 = Off
|
|
// glfwSwapInterval(1);
|
|
}
|
|
|
|
void Renderer::update(double delta) {
|
|
elapsedTime += delta;
|
|
|
|
window.update();
|
|
world.updateSwayMap(delta);
|
|
}
|
|
|
|
void Renderer::beginChunkDeferredCalls() {
|
|
// activeTexture = nullptr;
|
|
currentModelUniform = world.uniforms.model;
|
|
|
|
glClearColor(0, 0, 0, 0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
glDisable(GL_BLEND);
|
|
|
|
glViewport(0, 0, static_cast<int>(world.windowSize.x * world.bufferScale),
|
|
static_cast<int>(world.windowSize.y * world.bufferScale));
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, light.gBuffer);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
const float skyColor[] = { clearColor.x, clearColor.y, clearColor.z, 1 };
|
|
static const float clearTransparent[] = { 0, 0, 0, 1 };
|
|
glClearBufferfv(GL_COLOR, 0, clearTransparent);
|
|
glClearBufferfv(GL_COLOR, 1, clearTransparent);
|
|
glClearBufferfv(GL_COLOR, 2, skyColor);
|
|
|
|
setShader(world);
|
|
world.set(world.uniforms.proj, camera.getProjectionMatrix());
|
|
world.set(world.uniforms.view, camera.getViewMatrix());
|
|
world.set(world.uniforms.time, static_cast<float>(elapsedTime));
|
|
world.swayTex.use(1);
|
|
}
|
|
|
|
void Renderer::beginEntityDeferredCalls() {
|
|
glEnable(GL_BLEND);
|
|
|
|
currentModelUniform = entity.uniforms.model;
|
|
|
|
setShader(entity);
|
|
entity.set(entity.uniforms.proj, camera.getProjectionMatrix());
|
|
entity.set(entity.uniforms.view, camera.getViewMatrix());
|
|
}
|
|
|
|
void Renderer::endDeferredCalls() {
|
|
glDisable(GL_BLEND);
|
|
|
|
// activeTexture = nullptr;
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, ssao.fbo);
|
|
glClearColor(clearColor.x, clearColor.y, clearColor.z, 0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
setShader(ssao);
|
|
ssao.set(ssao.uniforms.proj, camera.getProjectionMatrix());
|
|
ssao.set(ssao.uniforms.view, camera.getViewMatrix());
|
|
ssao.set(ssao.uniforms.kernelCount, ssao.kernelCount);
|
|
|
|
for (unsigned int i = 0; i < ssao.kernelCount; i++) {
|
|
GLint uni = ssao.get("samples[" + std::to_string(i) + "]");
|
|
ssao.set(uni, ssao.kernels[i]);
|
|
}
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, light.gPosition);
|
|
glActiveTexture(GL_TEXTURE1);
|
|
glBindTexture(GL_TEXTURE_2D, light.gNormal);
|
|
glActiveTexture(GL_TEXTURE2);
|
|
glBindTexture(GL_TEXTURE_2D, ssao.tex);
|
|
|
|
renderQuad();
|
|
|
|
auto winSize = window.getSize();
|
|
glViewport(0, 0, static_cast<int>(winSize.x), static_cast<int>(winSize.y));
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, blur.fbo);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
setShader(blur);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, ssao.colorBuffer);
|
|
renderQuad();
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
setShader(light);
|
|
light.set(light.uniforms.camPosition, camera.getPos());
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, light.gPosition);
|
|
glActiveTexture(GL_TEXTURE1);
|
|
glBindTexture(GL_TEXTURE_2D, light.gNormal);
|
|
glActiveTexture(GL_TEXTURE2);
|
|
glBindTexture(GL_TEXTURE_2D, light.gColorSpec);
|
|
glActiveTexture(GL_TEXTURE3);
|
|
glBindTexture(GL_TEXTURE_2D, blur.colorBuffer);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
renderQuad();
|
|
}
|
|
|
|
void Renderer::beginGUIDrawCalls() {
|
|
// activeTexture = nullptr;
|
|
currentModelUniform = gu.model;
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_CULL_FACE);
|
|
glEnable(GL_BLEND);
|
|
|
|
setShader(guiShader);
|
|
guiShader.set(gu.ortho, gu.matrix);
|
|
}
|
|
|
|
void Renderer::swapBuffers() {
|
|
Shader::clearShader();
|
|
window.swapBuffers();
|
|
}
|
|
|
|
void Renderer::setShader(Shader& s) {
|
|
s.use();
|
|
this->currentShader = &s;
|
|
}
|
|
|
|
void Renderer::setClearColor(unsigned char r, unsigned char g, unsigned char b) {
|
|
clearColor = { static_cast<float>(r) / 255.f, static_cast<float>(g) / 255.f, static_cast<float>(b) / 255.f, 1 };
|
|
}
|
|
|
|
void Renderer::toggleDepthTest(bool enable) {
|
|
enable ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
void Renderer::clearDepthBuffer() {
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
|
|
void Renderer::setModelMatrix(const glm::mat4& modelMatrix) {
|
|
glUniformMatrix4fv(currentModelUniform, 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
|
}
|
|
|
|
void Renderer::setBones(std::vector<glm::mat4>& transforms) {
|
|
if (transforms.empty()) return;
|
|
currentShader->setArr((currentShader == &entity ? entity.uniforms.bones : gu.bones),
|
|
static_cast<GLsizei>(transforms.size()), transforms.at(0));
|
|
}
|
|
|
|
void Renderer::setClipBounds(glm::vec4 bounds) {
|
|
guiShader.set(gu.clipBounds, { bounds.x, window.getSize().y - bounds.w, bounds.z, window.getSize().y - bounds.y });
|
|
}
|
|
|
|
void Renderer::enableTexture(const Texture& texture) {
|
|
// if (texture != *activeTexture) {
|
|
// activeTexture = texture;
|
|
texture.use(0);
|
|
// }
|
|
}
|
|
|
|
void Renderer::renderQuad() {
|
|
if (quadVAO == 0) {
|
|
float quadVertices[] = {
|
|
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
|
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
|
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
|
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
|
};
|
|
|
|
glGenVertexArrays(1, &quadVAO);
|
|
glGenBuffers(1, &quadVBO);
|
|
glBindVertexArray(quadVAO);
|
|
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*) nullptr);
|
|
glEnableVertexAttribArray(1);
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*) (3 * sizeof(float)));
|
|
}
|
|
|
|
glBindVertexArray(quadVAO);
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
|