initial commit

This commit is contained in:
MihailRis 2025-05-07 20:42:50 +03:00
parent 27b194816b
commit fc46b7c434
36 changed files with 755 additions and 71 deletions

View File

@ -6,10 +6,12 @@
"lines",
"entity",
"background",
"skybox_gen"
"skybox_gen",
"shadows"
],
"post-effects": [
"default"
"default",
"ssao"
],
"textures": [
"gui/menubg",

View File

@ -4,5 +4,8 @@
"third-person-front",
"third-person-back",
"cinematic"
],
"post-effect-slot": [
"default"
]
}

View File

@ -55,4 +55,8 @@ function on_hud_open()
player.set_vel(pid, 0, 1, 0)
end
end)
local slot = gfx.posteffects.index("core:default")
gfx.posteffects.set_effect(slot, "ssao")
--gfx.posteffects.set_intensity(slot, 1.0)
end

View File

@ -1,9 +1,13 @@
in vec3 v_coord;
out vec4 f_color;
layout (location = 0) out vec4 f_color;
layout (location = 1) out vec4 f_position;
layout (location = 2) out vec4 f_normal;
uniform samplerCube u_cubemap;
void main(){
vec3 dir = normalize(v_coord);
f_position = vec4(100000.0);
f_normal = vec4(0.0);
f_color = texture(u_cubemap, dir);
}

View File

@ -2,8 +2,15 @@ in vec2 v_uv;
out vec4 f_color;
uniform sampler2D u_screen;
uniform sampler2D u_position;
uniform sampler2D u_normal;
uniform sampler2D u_noise;
uniform sampler2D u_shadows;
uniform ivec2 u_screenSize;
uniform float u_intensity;
uniform float u_timer;
uniform mat4 u_projection;
#include <__effect__>

View File

@ -1,3 +1,50 @@
vec4 effect() {
return texture(u_screen, v_uv);
uniform vec3 samples[64];
int kernelSize = 32;
float radius = 0.25;
float bias = 0.025;
float near_plane = 0.5f;
float far_plane = 200.0f;
// required when using a perspective projection matrix
float linearize_depth(float depth) {
float z = depth * 2.0 - 1.0; // Back to NDC
return (2.0 * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane));
}
float fmod(float x, float y) {
return x - y * floor(x/y);
}
vec4 effect() {
vec2 noiseScale = u_screenSize / 4.0;
vec3 position = texture(u_position, v_uv).xyz;
vec3 color = texture(u_screen, v_uv).rgb;
vec3 normal = texture(u_normal, v_uv).xyz;
vec3 randomVec = normalize(texture(u_noise, v_uv * noiseScale).xyz);
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);
float occlusion = 0.0;
for(int i = 0; i < kernelSize; ++i)
{
vec3 samplePos = TBN * samples[i];
samplePos = position + samplePos * radius;
vec4 offset = vec4(samplePos, 1.0);
offset = u_projection * offset;
offset.xyz /= offset.w;
offset.xyz = offset.xyz * 0.5 + 0.5;
float sampleDepth = texture(u_position, offset.xy).z;
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(position.z - sampleDepth));
occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck;
}
occlusion = 1.1 - (occlusion / kernelSize);
float d = texture(u_shadows, v_uv).r;
return vec4(color * occlusion, 1.0);
}

View File

@ -0,0 +1,11 @@
uniform vec3 samples[64];
vec4 effect() {
vec2 noiseScale = u_screenSize / 4.0;
vec3 position = texture(u_position, v_uv).xyz;
vec3 color = texture(u_screen, v_uv).rgb;
vec3 normal = texture(u_normal, v_uv).xyz;
vec3 randomVec = texture(u_noise, v_uv * noiseScale).xyz;
return vec4(randomVec, 1.0);
}

View File

@ -1,8 +1,13 @@
in vec4 a_color;
in vec2 a_texCoord;
in vec3 a_position;
in vec3 a_dir;
in vec3 a_normal;
in float a_fog;
out vec4 f_color;
layout (location = 0) out vec4 f_color;
layout (location = 1) out vec4 f_position;
layout (location = 2) out vec4 f_normal;
uniform sampler2D u_texture0;
uniform samplerCube u_cubemap;
@ -20,4 +25,6 @@ void main() {
discard;
f_color = mix(a_color * tex_color, vec4(fogColor,1.0), a_fog);
f_color.a = alpha;
f_position = vec4(a_position, 1.0);
f_normal = vec4(a_normal, 1.0);
}

View File

@ -7,7 +7,9 @@ layout (location = 3) in vec4 v_light;
out vec4 a_color;
out vec2 a_texCoord;
out vec3 a_normal;
out float a_fog;
out vec3 a_position;
out vec3 a_dir;
uniform mat4 u_model;
@ -31,6 +33,8 @@ void main() {
vec3 pos3d = modelpos.xyz - u_cameraPos;
modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d);
a_normal = vec3(0.0, 1.0, 0.0);//v_normal.xyz * 2.0 - 1.0;
vec3 light = v_light.rgb;
float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) /
u_torchlightDistance);
@ -48,4 +52,6 @@ void main() {
a_fog = min(1.0, max(pow(depth * u_fogFactor, u_fogCurve),
min(pow(depth * u_weatherFogDencity, u_weatherFogCurve), u_weatherFogOpacity)));
gl_Position = u_proj * u_view * modelpos;
a_position = (u_view * modelpos).xyz;
}

View File

@ -1,19 +1,53 @@
layout (location = 0) out vec4 f_color;
layout (location = 1) out vec4 f_position;
layout (location = 2) out vec4 f_normal;
in vec4 a_color;
in vec2 a_texCoord;
in float a_fog;
in vec3 a_position;
in vec3 a_dir;
out vec4 f_color;
in vec3 a_normal;
in vec3 a_realnormal;
in vec4 a_modelpos;
uniform sampler2D u_texture0;
uniform samplerCube u_cubemap;
uniform sampler2DShadow u_shadows;
// flags
uniform bool u_alphaClip;
uniform bool u_debugLights;
uniform bool u_debugNormals;
uniform bool u_enableShadows;
uniform mat4 u_shadowsMatrix;
const int BLUR_SAMPLES = 6;
void main() {
float shadow = 1.0;
if (u_enableShadows) {
vec4 mpos = u_shadowsMatrix * vec4(a_modelpos.xyz, 1.0);
vec3 projCoords = mpos.xyz / mpos.w;
projCoords = projCoords * 0.5 + 0.5;
projCoords.z -= 0.0001;
shadow = 0.0;
for (int i = 0; i < BLUR_SAMPLES; i++) {
shadow += texture(u_shadows, projCoords.xyz + vec3(
-0.002*(i%2==0?1:0)*i/BLUR_SAMPLES,
-0.002*(i%2==0?0:1)*i/BLUR_SAMPLES,
-0.0005 * i/BLUR_SAMPLES));
}
shadow /= BLUR_SAMPLES;
shadow += 0.5;
shadow = shadow * 0.7 + 0.3;
}
vec3 fogColor = texture(u_cubemap, a_dir).rgb;
vec4 tex_color = texture(u_texture0, a_texCoord);
if (u_debugLights)
tex_color.rgb = vec3(1.0);
float alpha = a_color.a * tex_color.a;
if (u_alphaClip) {
if (alpha < 0.2f)
@ -23,6 +57,14 @@ void main() {
if (alpha < 0.002f)
discard;
}
if (u_debugLights)
tex_color.rgb = u_debugNormals ? (a_normal * 0.5 + 0.5) : vec3(1.0);
else if (u_debugNormals) {
tex_color.rgb *= a_normal * 0.5 + 0.5;
}
f_color = mix(a_color * tex_color, vec4(fogColor,1.0), a_fog);
f_color.rgb *= shadow;
f_color.a = alpha;
f_position = vec4(a_position, 1.0);
f_normal = vec4(a_normal, 1.0);
}

View File

@ -3,12 +3,17 @@
layout (location = 0) in vec3 v_position;
layout (location = 1) in vec2 v_texCoord;
layout (location = 2) in vec4 v_light;
layout (location = 3) in vec4 v_normal;
out vec4 a_color;
out vec2 a_texCoord;
out vec3 a_normal;
out float a_distance;
out float a_fog;
out vec3 a_position;
out vec4 a_modelpos;
out vec3 a_dir;
out vec3 a_realnormal;
uniform mat4 u_model;
uniform mat4 u_proj;
@ -25,12 +30,19 @@ uniform samplerCube u_cubemap;
uniform vec3 u_torchlightColor;
uniform float u_torchlightDistance;
uniform bool u_enableShadows;
void main() {
vec4 modelpos = u_model * vec4(v_position, 1.0f);
vec3 pos3d = modelpos.xyz-u_cameraPos;
modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d);
a_realnormal = v_normal.xyz;
mat3 normalMatrix = transpose(inverse(mat3(u_view * u_model)));
a_normal = v_normal.xyz * 2.0 - 1.0;
a_normal = normalMatrix * (false ? -a_normal : a_normal);
//a_normal = v_normal.xyz * 2.0 - 1.0;
vec3 light = v_light.rgb;
float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) /
u_torchlightDistance);
@ -47,4 +59,7 @@ void main() {
a_fog = min(1.0, max(pow(depth * u_fogFactor, u_fogCurve),
min(pow(depth * u_weatherFogDencity, u_weatherFogCurve), u_weatherFogOpacity)));
gl_Position = u_proj * u_view * modelpos;
a_position = (u_view * modelpos).xyz;
a_modelpos = modelpos;
}

11
res/shaders/shadows.glslf Normal file
View File

@ -0,0 +1,11 @@
in vec2 a_texCoord;
uniform sampler2D u_texture0;
void main() {
vec4 tex_color = texture(u_texture0, a_texCoord);
if (tex_color.a < 0.5) {
discard;
}
// depth will be written anyway
}

17
res/shaders/shadows.glslv Normal file
View File

@ -0,0 +1,17 @@
#include <commons>
layout (location = 0) in vec3 v_position;
layout (location = 1) in vec2 v_texCoord;
layout (location = 2) in vec4 v_light;
layout (location = 3) in vec4 v_normal;
out vec2 a_texCoord;
uniform mat4 u_model;
uniform mat4 u_proj;
uniform mat4 u_view;
void main() {
a_texCoord = v_texCoord;
gl_Position = u_proj * u_view * u_model * vec4(v_position, 1.0f);
}

View File

@ -178,6 +178,8 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
uicamera = std::make_unique<Camera>(glm::vec3(), 1);
uicamera->perspective = false;
uicamera->flipped = true;
uicamera->near = -1.0f;
uicamera->far = 1.0f;
debugPanel = create_debug_panel(
engine, frontend.getLevel(), player, allowDebugCheats

View File

@ -22,6 +22,8 @@ MenuScreen::MenuScreen(Engine& engine) : Screen(engine) {
uicamera =
std::make_unique<Camera>(glm::vec3(), engine.getWindow().getSize().y);
uicamera->perspective = false;
uicamera->near = -1.0f;
uicamera->far = 1.0f;
uicamera->flipped = true;
}

View File

@ -100,7 +100,7 @@ void DrawContext::setViewport(const glm::uvec2& viewport) {
glViewport(0, 0, viewport.x, viewport.y);
}
void DrawContext::setFramebuffer(Framebuffer* fbo) {
void DrawContext::setFramebuffer(Bindable* fbo) {
if (this->fbo == fbo)
return;
this->fbo = fbo;

View File

@ -16,7 +16,7 @@ class DrawContext {
glm::uvec2 viewport;
Batch2D* g2d;
Flushable* flushable = nullptr;
Framebuffer* fbo = nullptr;
Bindable* fbo = nullptr;
bool depthMask = true;
bool depthTest = false;
bool cullFace = false;
@ -37,7 +37,7 @@ public:
DrawContext sub(Flushable* flushable=nullptr) const;
void setViewport(const glm::uvec2& viewport);
void setFramebuffer(Framebuffer* fbo);
void setFramebuffer(Bindable* fbo);
void setDepthMask(bool flag);
void setDepthTest(bool flag);
void setCullFace(bool flag);

View File

@ -2,6 +2,9 @@
#include <GL/glew.h>
#include "Texture.hpp"
#include "debug/Logger.hpp"
static debug::Logger logger("gl-framebuffer");
Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
: fbo(fbo), depth(depth), texture(std::move(texture))
@ -38,18 +41,41 @@ Framebuffer::Framebuffer(uint width, uint height, bool alpha)
// Setup color attachment (texture)
texture = create_texture(width, height, format);
glGenTextures(1, &positions);
glBindTexture(GL_TEXTURE_2D, positions);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positions, 0);
glGenTextures(1, &normals);
glBindTexture(GL_TEXTURE_2D, normals);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normals, 0);
unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, attachments);
// Setup depth attachment
glGenRenderbuffers(1, &depth);
glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
logger.error() << "framebuffer is not complete!";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Framebuffer::~Framebuffer() {
glDeleteFramebuffers(1, &fbo);
glDeleteRenderbuffers(1, &depth);
glDeleteTextures(1, &normals);
glDeleteTextures(1, &depth);
}
void Framebuffer::bind() {
@ -60,6 +86,19 @@ void Framebuffer::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Framebuffer::bindBuffers() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->getId());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, positions);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normals);
glActiveTexture(GL_TEXTURE0);
}
void Framebuffer::resize(uint width, uint height) {
if (this->width == width && this->height == height) {
return;
@ -67,11 +106,22 @@ void Framebuffer::resize(uint width, uint height) {
this->width = width;
this->height = height;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindTexture(GL_TEXTURE_2D, positions);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positions, 0);
glBindTexture(GL_TEXTURE_2D, normals);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normals, 0);
glBindTexture(GL_TEXTURE_2D, 0);
texture = create_texture(width, height, format);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

View File

@ -1,14 +1,17 @@
#pragma once
#include "typedefs.hpp"
#include "commons.hpp"
#include <memory>
class Texture;
class Framebuffer {
class Framebuffer : public Bindable {
uint fbo;
uint depth;
uint positions;
uint normals;
uint width;
uint height;
uint format;
@ -19,10 +22,12 @@ public:
~Framebuffer();
/// @brief Use framebuffer
void bind();
void bind() override;
/// @brief Stop using framebuffer
void unbind();
void unbind() override;
void bindBuffers();
/// @brief Update framebuffer texture size
/// @param width new width

View File

@ -0,0 +1,186 @@
#include "GBuffer.hpp"
#include <GL/glew.h>
#include "debug/Logger.hpp"
static debug::Logger logger("gl-gbuffer");
void GBuffer::createColorBuffer() {
glGenTextures(1, &colorBuffer);
glBindTexture(GL_TEXTURE_2D, colorBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
width,
height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0
);
}
void GBuffer::createPositionsBuffer() {
glGenTextures(1, &positionsBuffer);
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F,
width,
height,
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionsBuffer, 0
);
}
void GBuffer::createNormalsBuffer() {
glGenTextures(1, &normalsBuffer);
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F,
width,
height,
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalsBuffer, 0
);
}
void GBuffer::createDepthBuffer() {
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer
);
}
GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
createColorBuffer();
createPositionsBuffer();
createNormalsBuffer();
GLenum attachments[3] = {
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2
};
glDrawBuffers(3, attachments);
createDepthBuffer();
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
logger.error() << "framebuffer is not complete!";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
GBuffer::~GBuffer() {
glDeleteTextures(1, &colorBuffer);
glDeleteTextures(1, &positionsBuffer);
glDeleteTextures(1, &normalsBuffer);
glDeleteRenderbuffers(1, &depthBuffer);
glDeleteFramebuffers(1, &fbo);
}
void GBuffer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}
void GBuffer::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void GBuffer::bindBuffers() {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorBuffer);
}
void GBuffer::resize(uint width, uint height) {
if (this->width == width && this->height == height) {
return;
}
this->width = width;
this->height = height;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, colorBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
width,
height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr
);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0
);
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr
);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionsBuffer, 0
);
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr
);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalsBuffer, 0
);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
uint GBuffer::getWidth() const {
return width;
}
uint GBuffer::getHeight() const {
return height;
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "typedefs.hpp"
#include "commons.hpp"
class GBuffer : public Bindable{
public:
GBuffer(uint width, uint height);
~GBuffer();
void bind() override;
void unbind() override;
void bindBuffers();
void resize(uint width, uint height);
uint getWidth() const;
uint getHeight() const;
private:
uint width;
uint height;
uint fbo;
uint colorBuffer;
uint positionsBuffer;
uint normalsBuffer;
uint depthBuffer;
void createColorBuffer();
void createPositionsBuffer();
void createNormalsBuffer();
void createDepthBuffer();
};

View File

@ -6,22 +6,56 @@
#include "DrawContext.hpp"
#include "PostEffect.hpp"
#include "assets/Assets.hpp"
#include "window/Camera.hpp"
#include <stdexcept>
#include <random>
PostProcessing::PostProcessing(size_t effectSlotsCount)
: effectSlots(effectSlotsCount) {
// Fullscreen quad mesh bulding
PostProcessingVertex meshData[]{
{{-1.0f, -1.0f}},
{{-1.0f, 1.0f}},
{{1.0f, 1.0f}},
{{-1.0f, -1.0f}},
{{1.0f, 1.0f}},
{{1.0f, -1.0f}},
PostProcessingVertex meshData[] {
{{-1.0f, -1.0f}},
{{-1.0f, 1.0f}},
{{1.0f, 1.0f}},
{{-1.0f, -1.0f}},
{{1.0f, 1.0f}},
{{1.0f, -1.0f}},
};
quadMesh = std::make_unique<Mesh<PostProcessingVertex>>(meshData, 6);
std::vector<glm::vec3> ssaoNoise;
for (unsigned int i = 0; i < 16; i++)
{
glm::vec3 noise(
(rand() / static_cast<float>(RAND_MAX)) * 2.0 - 1.0,
(rand() / static_cast<float>(RAND_MAX)) * 2.0 - 1.0,
0.0f);
ssaoNoise.push_back(noise);
}
glGenTextures(1, &noiseTexture);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 4, 4, 0, GL_RGB, GL_FLOAT, ssaoNoise.data());
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_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, 0);
std::uniform_real_distribution<float> randomFloats(0.0, 1.0);
std::default_random_engine generator;
for (unsigned int i = 0; i < 64; ++i)
{
glm::vec3 sample(
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator)
);
sample = glm::normalize(sample);
sample *= randomFloats(generator);
ssaoKernel.push_back(sample);
}
}
PostProcessing::~PostProcessing() = default;
@ -39,7 +73,7 @@ void PostProcessing::use(DrawContext& context) {
}
void PostProcessing::render(
const DrawContext& context, const Assets& assets, float timer
const DrawContext& context, const Assets& assets, float timer, const Camera& camera, uint depthMap
) {
if (fbo == nullptr) {
throw std::runtime_error("'use(...)' was never called");
@ -51,8 +85,38 @@ void PostProcessing::render(
if (totalPasses == 0) {
auto& effect = assets.require<PostEffect>("default");
effect.use();
fbo->getTexture()->bind();
fbo->bindBuffers();
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, depthMap);
glActiveTexture(GL_TEXTURE0);
const auto& viewport = context.getViewport();
auto& shader = effect.use();
if (!ssaoConfigured) {
for (unsigned int i = 0; i < 64; ++i) {
auto name = "samples["+ std::to_string(i) + "]";
shader.uniform3f(name, ssaoKernel[i]);
}
ssaoConfigured = true;
}
shader.uniform1i("u_screen", 0);
shader.uniform1i("u_position", 1);
shader.uniform1i("u_normal", 2);
shader.uniform1i("u_noise", 3);
shader.uniform1i("u_shadows", 4);
shader.uniform2i("u_screenSize", viewport);
shader.uniform1f("u_timer", timer);
shader.uniform1f("near_plane", camera.near);
shader.uniform1f("far_plane", camera.far);
shader.uniformMatrix("u_projection", camera.getProjection());
quadMesh->draw();
return;
}
@ -64,15 +128,25 @@ void PostProcessing::render(
}
auto& shader = effect->use();
for (unsigned int i = 0; i < 64; ++i) {
shader.uniform3f("samples["+ std::to_string(i) + "]", ssaoKernel[i]);
}
const auto& viewport = context.getViewport();
shader.uniform1i("u_screen", 0);
shader.uniform1i("u_position", 1);
shader.uniform1i("u_normal", 2);
shader.uniform1i("u_noise", 3);
shader.uniform2i("u_screenSize", viewport);
shader.uniform1f("u_timer", timer);
shader.uniformMatrix("u_projection", camera.getProjView(false));
fbo->getTexture()->bind();
fbo->bindBuffers();
if (currentPass < totalPasses) {
fboSecond->bind();
}
quadMesh->draw();
if (currentPass < totalPasses) {
fboSecond->unbind();

View File

@ -11,6 +11,7 @@ class Framebuffer;
class DrawContext;
class ImageData;
class PostEffect;
class Camera;
struct PostProcessingVertex {
glm::vec2 position;
@ -30,6 +31,10 @@ class PostProcessing {
/// @brief Fullscreen quad mesh as the post-processing canvas
std::unique_ptr<Mesh<PostProcessingVertex>> quadMesh;
std::vector<std::shared_ptr<PostEffect>> effectSlots;
std::vector<glm::vec3> ssaoKernel;
uint noiseTexture;
bool ssaoConfigured = false;
public:
PostProcessing(size_t effectSlotsCount);
~PostProcessing();
@ -42,7 +47,7 @@ public:
/// with framebuffer texture bound
/// @param context graphics context
/// @throws std::runtime_error if use(...) wasn't called before
void render(const DrawContext& context, const Assets& assets, float timer);
void render(const DrawContext& context, const Assets& assets, float timer, const Camera& camera, uint depthMap);
void setEffect(size_t slot, std::shared_ptr<PostEffect> effect);

View File

@ -0,0 +1,47 @@
#include "ShadowMap.hpp"
#include <GL/glew.h>
ShadowMap::ShadowMap(int resolution) : resolution(resolution) {
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
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_R, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
float border[4] {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR, border);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
ShadowMap::~ShadowMap() {
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &depthMap);
}
void ShadowMap::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_DEPTH_BUFFER_BIT);
}
void ShadowMap::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
uint ShadowMap::getDepthMap() const {
return depthMap;
}
int ShadowMap::getResolution() const {
return resolution;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "typedefs.hpp"
class ShadowMap {
public:
ShadowMap(int resolution);
~ShadowMap();
void bind();
void unbind();
uint getDepthMap() const;
int getResolution() const;
private:
uint fbo;
uint depthMap;
int resolution;
};

View File

@ -69,3 +69,11 @@ public:
virtual void flush() = 0;
};
class Bindable {
public:
virtual ~Bindable() = default;
virtual void bind() = 0;
virtual void unbind() = 0;
};

View File

@ -10,7 +10,7 @@
#include "frontend/ContentGfxCache.hpp"
const glm::vec3 BlocksRenderer::SUN_VECTOR(0.528265f, 0.833149f, -0.163704f);
const float DIRECTIONAL_LIGHT_FACTOR = 0.3f;
const float DIRECTIONAL_LIGHT_FACTOR = 0.2f;
BlocksRenderer::BlocksRenderer(
size_t capacity,
@ -39,13 +39,17 @@ BlocksRenderer::~BlocksRenderer() {
/// Basic vertex add method
void BlocksRenderer::vertex(
const glm::vec3& coord, float u, float v, const glm::vec4& light
const glm::vec3& coord, float u, float v, const glm::vec4& light, const glm::vec3& normal
) {
vertexBuffer[vertexCount].position = coord;
vertexBuffer[vertexCount].uv = {u,v};
vertexBuffer[vertexCount].normal[0] = static_cast<uint8_t>(normal.r * 127 + 128);
vertexBuffer[vertexCount].normal[1] = static_cast<uint8_t>(normal.g * 127 + 128);
vertexBuffer[vertexCount].normal[2] = static_cast<uint8_t>(normal.b * 127 + 128);
vertexBuffer[vertexCount].color[0] = static_cast<uint8_t>(light.r * 255);
vertexBuffer[vertexCount].color[1] = static_cast<uint8_t>(light.g * 255);
vertexBuffer[vertexCount].color[2] = static_cast<uint8_t>(light.b * 255);
@ -82,10 +86,10 @@ void BlocksRenderer::face(
auto Y = axisY * h;
auto Z = axisZ * d;
float s = 0.5f;
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, lights[0] * tint);
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, lights[1] * tint);
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, lights[2] * tint);
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, lights[3] * tint);
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, lights[0] * tint, axisZ);
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, lights[1] * tint, axisZ);
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, lights[2] * tint, axisZ);
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, lights[3] * tint, axisZ);
index(0, 1, 3, 1, 2, 3);
}
@ -103,7 +107,7 @@ void BlocksRenderer::vertexAO(
axisX,
axisY
);
vertex(coord, u, v, light * tint);
vertex(coord, u, v, light * tint, axisZ);
}
void BlocksRenderer::faceAO(
@ -134,11 +138,12 @@ void BlocksRenderer::faceAO(
vertexAO(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, axisX, axisY, axisZ);
vertexAO(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, axisX, axisY, axisZ);
} else {
auto axisZ = glm::normalize(Z);
glm::vec4 tint(1.0f);
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint);
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint);
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint);
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint);
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, axisZ);
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, axisZ);
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, axisZ);
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, axisZ);
}
index(0, 1, 2, 0, 2, 3);
}
@ -163,10 +168,10 @@ void BlocksRenderer::face(
d = (1.0f - DIRECTIONAL_LIGHT_FACTOR) + d * DIRECTIONAL_LIGHT_FACTOR;
tint *= d;
}
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint);
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint);
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint);
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint);
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, Z);
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, Z);
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, Z);
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, Z);
index(0, 1, 2, 0, 2, 3);
}
@ -337,7 +342,8 @@ void BlocksRenderer::blockCustomModel(
coord + vcoord.x * X + vcoord.y * Y + vcoord.z * Z,
vertex.uv.x,
vertex.uv.y,
glm::vec4(d, d, d, d) * aoColor
glm::vec4(d, d, d, d) * aoColor,
n
);
indexBuffer[indexCount++] = vertexOffset++;
}

View File

@ -44,7 +44,7 @@ class BlocksRenderer {
SortingMeshData sortingMesh;
void vertex(const glm::vec3& coord, float u, float v, const glm::vec4& light);
void vertex(const glm::vec3& coord, float u, float v, const glm::vec4& light, const glm::vec3& normal);
void index(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f);
void vertexAO(

View File

@ -143,7 +143,7 @@ void ChunksRenderer::update() {
}
const Mesh<ChunkVertex>* ChunksRenderer::retrieveChunk(
size_t index, const Camera& camera, Shader& shader, bool culling
size_t index, const Camera& camera, bool culling
) {
auto chunk = chunks.getChunks()[index];
if (chunk == nullptr) {
@ -219,7 +219,7 @@ void ChunksRenderer::drawChunks(
// TODO: minimize draw calls number
for (int i = indices.size()-1; i >= 0; i--) {
auto& chunk = chunks.getChunks()[indices[i].index];
auto mesh = retrieveChunk(indices[i].index, camera, shader, culling);
auto mesh = retrieveChunk(indices[i].index, camera, culling);
if (mesh) {
glm::vec3 coord(

View File

@ -50,7 +50,7 @@ class ChunksRenderer {
std::vector<ChunksSortEntry> indices;
util::ThreadPool<std::shared_ptr<Chunk>, RendererResult> threadPool;
const Mesh<ChunkVertex>* retrieveChunk(
size_t index, const Camera& camera, Shader& shader, bool culling
size_t index, const Camera& camera, bool culling
);
public:
ChunksRenderer(

View File

@ -136,8 +136,8 @@ void Skybox::draw(
batch3d->sprite(pos, glm::vec3(0, 0, 1),
up, 1, 1, UVRegion(), tint);
}
drawStars(angle, opacity);
batch3d->flush();
//drawStars(angle, opacity);
}
void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) {

View File

@ -41,6 +41,8 @@
#include "graphics/core/Shader.hpp"
#include "graphics/core/Texture.hpp"
#include "graphics/core/Font.hpp"
#include "graphics/core/ShadowMap.hpp"
#include "graphics/core/GBuffer.hpp"
#include "BlockWrapsRenderer.hpp"
#include "ParticlesRenderer.hpp"
#include "PrecipitationRenderer.hpp"
@ -100,6 +102,10 @@ WorldRenderer::WorldRenderer(
settings.graphics.skyboxResolution.get(),
assets->require<Shader>("skybox_gen")
);
shadowMap = std::make_unique<ShadowMap>(1024);
shadowCamera = std::make_unique<Camera>();
}
WorldRenderer::~WorldRenderer() = default;
@ -119,6 +125,7 @@ void WorldRenderer::setupWorldShader(
shader.uniform1f("u_fogFactor", fogFactor);
shader.uniform1f("u_fogCurve", settings.graphics.fogCurve.get());
shader.uniform1i("u_debugLights", lightsDebug);
shader.uniform1i("u_debugNormals", false);
shader.uniform1f("u_weatherFogOpacity", weather.fogOpacity());
shader.uniform1f("u_weatherFogDencity", weather.fogDencity());
shader.uniform1f("u_weatherFogCurve", weather.fogCurve());
@ -126,6 +133,15 @@ void WorldRenderer::setupWorldShader(
shader.uniform2f("u_lightDir", skybox->getLightDir());
shader.uniform3f("u_cameraPos", camera.position);
shader.uniform1i("u_cubemap", 1);
shader.uniform1i("u_enableShadows", gbufferPipeline);
if (gbufferPipeline) {
shader.uniformMatrix("u_shadowsMatrix", shadowCamera->getProjView());
glActiveTexture(GL_TEXTURE4);
shader.uniform1i("u_shadows", 4);
glBindTexture(GL_TEXTURE_2D, shadowMap->getDepthMap());
glActiveTexture(GL_TEXTURE0);
}
auto indices = level.content.getIndices();
// Light emission when an emissive item is chosen
@ -354,10 +370,52 @@ void WorldRenderer::draw(
const auto& assets = *engine.getAssets();
auto& linesShader = assets.require<Shader>("lines");
auto& shadowsShader = assets.require<Shader>("shadows");
if (gbufferPipeline) {
float shadowMapScale = 0.05f;
float shadowMapSize = shadowMap->getResolution() * shadowMapScale;
*shadowCamera = Camera(camera.position, shadowMapSize);
shadowCamera->near = 0.5f;
shadowCamera->far = 600.0f;
shadowCamera->perspective = false;
shadowCamera->setAspectRatio(1.0f);
shadowCamera->rotate(glm::radians(-65.0f), glm::radians(-35.0f), glm::radians(-35.0f));
//shadowCamera.perspective = false;
/*shadowCamera.rotation = //glm::inverse(
glm::lookAt({}, glm::normalize(shadowCamera.position-camera.position), glm::vec3(0, 1, 0));
//);*/
shadowCamera->updateVectors();
//shadowCamera->position += camera.dir * shadowMapSize * 0.5f;
shadowCamera->position -= shadowCamera->front * 100.0f;
shadowCamera->position -= shadowCamera->right * (shadowMap->getResolution() * shadowMapScale) * 0.5f;
shadowCamera->position -= shadowCamera->up * (shadowMap->getResolution() * shadowMapScale) * 0.5f;
shadowCamera->position = glm::floor(shadowCamera->position);
{
frustumCulling->update(shadowCamera->getProjView());
auto sctx = pctx.sub();
sctx.setDepthTest(true);
sctx.setCullFace(true);
sctx.setViewport({shadowMap->getResolution(), shadowMap->getResolution()});
shadowMap->bind();
setupWorldShader(shadowsShader, *shadowCamera, settings, 0.0f);
chunks->drawChunks(*shadowCamera, shadowsShader);
shadowMap->unbind();
}
}
/* World render scope with diegetic HUD included */ {
DrawContext wctx = pctx.sub();
postProcessing.use(wctx);
if (gbufferPipeline) {
if (gbuffer == nullptr) {
gbuffer = std::make_unique<GBuffer>(vp.x, vp.y);
} else {
gbuffer->resize(vp.x, vp.y);
}
wctx.setFramebuffer(gbuffer.get());
} else {
postProcessing.use(wctx);
}
display::clearDepth();
@ -370,25 +428,25 @@ void WorldRenderer::draw(
ctx.setCullFace(true);
renderLevel(ctx, camera, settings, uiDelta, pause, hudVisible);
// Debug lines
if (hudVisible) {
if (debug) {
guides->renderDebugLines(
ctx, camera, *lineBatch, linesShader, showChunkBorders
);
}
if (player.currentCamera == player.fpCamera) {
renderHands(camera, delta);
}
}
// if (hudVisible) {
// if (debug) {
// guides->renderDebugLines(
// ctx, camera, *lineBatch, linesShader, showChunkBorders
// );
// }
// if (player.currentCamera == player.fpCamera) {
// renderHands(camera, delta);
// }
// }
}
{
DrawContext ctx = wctx.sub();
texts->render(ctx, camera, settings, hudVisible, true);
}
renderBlockOverlay(wctx);
// {
// DrawContext ctx = wctx.sub();
// texts->render(ctx, camera, settings, hudVisible, true);
// }
//renderBlockOverlay(wctx);
}
postProcessing.render(pctx, assets, timer);
postProcessing.render(pctx, assets, timer, camera, shadowMap->getDepthMap());
}
void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) {

View File

@ -30,6 +30,8 @@ class PostProcessing;
class DrawContext;
class ModelBatch;
class Assets;
class ShadowMap;
class GBuffer;
struct EngineSettings;
class WorldRenderer {
@ -44,12 +46,18 @@ class WorldRenderer {
std::unique_ptr<GuidesRenderer> guides;
std::unique_ptr<ChunksRenderer> chunks;
std::unique_ptr<Skybox> skybox;
std::unique_ptr<ShadowMap> shadowMap;
Weather weather {};
std::unique_ptr<Camera> shadowCamera;
float timer = 0.0f;
bool debug = false;
bool lightsDebug = false;
std::unique_ptr<GBuffer> gbuffer;
bool gbufferPipeline = false;
/// @brief Render block selection lines
void renderBlockSelection();

View File

@ -14,11 +14,13 @@ struct ChunkVertex {
glm::vec3 position;
glm::vec2 uv;
std::array<uint8_t, 4> color;
std::array<uint8_t, 4> normal;
static constexpr VertexAttribute ATTRIBUTES[] = {
{VertexAttribute::Type::FLOAT, false, 3},
{VertexAttribute::Type::FLOAT, false, 2},
{VertexAttribute::Type::UNSIGNED_BYTE, true, 4},
{VertexAttribute::Type::UNSIGNED_BYTE, true, 4},
{{}, 0}};
};

View File

@ -38,6 +38,8 @@ GUI::GUI(Engine& engine)
std::make_unique<Camera>(glm::vec3(), engine.getWindow().getSize().y);
uicamera->perspective = false;
uicamera->flipped = true;
uicamera->near = -1.0f;
uicamera->far = 1.0f;
menu = std::make_shared<Menu>(*this);
menu->setId("menu");

View File

@ -31,9 +31,9 @@ glm::mat4 Camera::getProjection() const {
if (perspective) {
return glm::perspective(fov * zoom, ar, near, far);
} else if (flipped) {
return glm::ortho(0.0f, fov * ar, fov, 0.0f);
return glm::ortho(0.0f, fov * ar, fov, 0.0f, near, far);
} else {
return glm::ortho(0.0f, fov * ar, 0.0f, fov);
return glm::ortho(0.0f, fov * ar, 0.0f, fov, near, far);
}
}
@ -45,7 +45,8 @@ glm::mat4 Camera::getView(bool pos) const {
if (perspective) {
return glm::lookAt(camera_pos, camera_pos + front, up);
} else {
return glm::translate(glm::mat4(1.0f), camera_pos);
return glm::lookAt(camera_pos, camera_pos + front, up);
//return glm::translate(glm::mat4(1.0f), camera_pos);
}
}