Rendering of perspective linearized depth map kind of works now
parent
fb3e1e7432
commit
0810224356
|
@ -4,13 +4,19 @@ in vec2 ioUV;
|
||||||
|
|
||||||
out vec3 outColor;
|
out vec3 outColor;
|
||||||
|
|
||||||
uniform sampler2D uTexture;
|
uniform sampler2D uDepthTexture;
|
||||||
|
uniform float uIsOrthographic;
|
||||||
uniform float uNear;
|
uniform float uNear;
|
||||||
uniform float uFar;
|
uniform float uFar;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float z = texture(uTexture, ioUV).r;
|
float z = texture(uDepthTexture, ioUV).r;
|
||||||
float c = (z - uNear) / (uFar - uNear);
|
float c;
|
||||||
|
if (uIsOrthographic == 1.0) {
|
||||||
|
c = (z - uNear) / (uFar - uNear);
|
||||||
|
} else {
|
||||||
|
c = (2.0 * uNear) / (uFar + uNear - z * (uFar - uNear));
|
||||||
|
}
|
||||||
|
|
||||||
outColor = vec3(c);
|
outColor = vec3(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#version 150 core
|
||||||
|
|
||||||
|
uniform vec4 uColor;
|
||||||
|
uniform vec3 uLightDirection;
|
||||||
|
uniform vec3 uViewPosition;
|
||||||
|
|
||||||
|
smooth in vec4 ioFragColor;
|
||||||
|
in vec3 ioNormal;
|
||||||
|
in vec3 ioFragPosition;
|
||||||
|
|
||||||
|
out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// ambient lighting
|
||||||
|
float ambient_strength = 0.1;
|
||||||
|
vec4 ambient = ambient_strength * ioFragColor;
|
||||||
|
|
||||||
|
// diffuse lighting
|
||||||
|
vec3 normal_dir = normalize(ioNormal);
|
||||||
|
vec3 light_dir = normalize(uLightDirection);
|
||||||
|
float diff = max(dot(normal_dir, light_dir), 0.0);
|
||||||
|
vec4 diffuse = diff * ioFragColor;
|
||||||
|
|
||||||
|
// specular lighting
|
||||||
|
vec3 view_dir = normalize(uViewPosition - ioFragPosition);
|
||||||
|
vec3 halfway_dir = normalize(light_dir + view_dir);
|
||||||
|
|
||||||
|
float spec = pow(max(dot(normal_dir, halfway_dir), 0.0), 32);
|
||||||
|
vec4 specular = spec * vec4(0.5);
|
||||||
|
|
||||||
|
outColor = ambient + diffuse + specular;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#version 150 core
|
||||||
|
#extension GL_ARB_explicit_attrib_location : require
|
||||||
|
|
||||||
|
in vec4 inCoord;
|
||||||
|
in vec3 inNormal;
|
||||||
|
in vec2 inUV;
|
||||||
|
in vec4 inColor;
|
||||||
|
|
||||||
|
uniform mat4 uModelMatrix;
|
||||||
|
uniform mat4 uViewMatrix;
|
||||||
|
uniform mat4 uProjectionMatrix;
|
||||||
|
uniform mat3 uNormalMatrix;
|
||||||
|
uniform vec3 uLightDirection;
|
||||||
|
uniform vec3 uViewPosition;
|
||||||
|
|
||||||
|
smooth out vec4 ioFragColor;
|
||||||
|
out vec3 ioNormal;
|
||||||
|
out vec3 ioFragPosition;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * inCoord;
|
||||||
|
ioFragColor = inColor;
|
||||||
|
ioNormal = uNormalMatrix * inNormal;
|
||||||
|
ioFragPosition = (uModelMatrix * inCoord).xyz;
|
||||||
|
}
|
|
@ -154,37 +154,31 @@ const struct module_api MODULE_API = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
void Light::Initialize() {
|
||||||
// Camera
|
gLog("Initializing light");
|
||||||
//
|
mShadowMapProgram = RenderProgram("data/shaders/vs_shadowmap.vert", "data/shaders/fs_shadowmap.frag");
|
||||||
void Camera::UpdateMatrices() {
|
|
||||||
mViewMatrix = LookAt(mEye, mPoi, mUp);
|
|
||||||
|
|
||||||
if (mIsOrthographic) {
|
bool load_result = mShadowMapProgram.Load();
|
||||||
mProjectionMatrix = Ortho(-1.0f, 1.0f, -1.0f, 1.0f, mNear, mFar);
|
mShadowMapProgram.RegisterFileModification();
|
||||||
} else {
|
assert(load_result);
|
||||||
mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar);
|
|
||||||
}
|
gLog("Initializing light render target size: %d, %d", mShadowMapSize, mShadowMapSize);
|
||||||
|
mShadowMapTarget.Initialize(mShadowMapSize, mShadowMapSize,
|
||||||
|
RenderTarget::EnableColor
|
||||||
|
| RenderTarget::EnableDepthTexture
|
||||||
|
| RenderTarget::EnableLinearizedDepthTexture);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapTarget.mFrameBufferId);
|
||||||
|
gLog("Framebuffer of light has id: %d", mShadowMapTarget.mFrameBufferId);
|
||||||
|
gLog("Initializing light done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::DrawGui() {
|
void Light::UpdateMatrices() {
|
||||||
ImGui::Text("Width %3.4f, Height %3.4f", mWidth, mHeight);
|
mLightProjection = Ortho (-mBBoxSize * 0.5f, mBBoxSize * 0.5f, -mBBoxSize * 0.5f, mBBoxSize * 0.5f, mNear, mFar);
|
||||||
|
mLightView = LookAt(mDirection * mBBoxSize * 0.5f, Vector3f (0.0f, 0.0f, 0.0f), Vector3f (0.0f, 1.0f, 0.0f));
|
||||||
ImGui::InputFloat3("Eye", mEye.data(), -10.0f, 10.0f);
|
mLightSpaceMatrix = mLightProjection * mLightView;
|
||||||
ImGui::SliderFloat3("EyeS", mEye.data(), -10.0f, 10.0f);
|
|
||||||
|
|
||||||
ImGui::InputFloat3("Poi", mPoi.data(), -10.0f, 10.0f);
|
|
||||||
ImGui::InputFloat3("Up", mUp.data(), -10.0f, 10.0f);
|
|
||||||
ImGui::Checkbox("Orthographic", &mIsOrthographic);
|
|
||||||
ImGui::SliderFloat("Fov", &mFov, 5, 160);
|
|
||||||
ImGui::SliderFloat("Near", &mNear, -10, 10);
|
|
||||||
ImGui::SliderFloat("Far", &mFar, -20, 50);
|
|
||||||
if (ImGui::Button("Reset")) {
|
|
||||||
*this = Camera();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Renderer
|
// Renderer
|
||||||
//
|
//
|
||||||
|
@ -300,20 +294,6 @@ void Renderer::Initialize(int width, int height) {
|
||||||
mDefaultProgram.RegisterFileModification();
|
mDefaultProgram.RegisterFileModification();
|
||||||
assert(load_result);
|
assert(load_result);
|
||||||
|
|
||||||
// Render Target
|
|
||||||
mRenderTarget = RenderTarget (width, height,
|
|
||||||
RenderTarget::EnableColor
|
|
||||||
| RenderTarget::EnableDepthTexture
|
|
||||||
| RenderTarget::EnableLinearizedDepthTexture);
|
|
||||||
|
|
||||||
// Render Target Quad
|
|
||||||
glGenVertexArrays(1, &mRenderQuadVertexArrayId);
|
|
||||||
glBindVertexArray(mRenderQuadVertexArrayId);
|
|
||||||
|
|
||||||
glGenBuffers(1, &mRenderQuadVertexBufferId);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// Program for color texture rendering
|
// Program for color texture rendering
|
||||||
mRenderQuadProgramColor = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_simpletexture.glsl");
|
mRenderQuadProgramColor = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_simpletexture.glsl");
|
||||||
load_result = mRenderQuadProgramColor.Load();
|
load_result = mRenderQuadProgramColor.Load();
|
||||||
|
@ -333,6 +313,27 @@ void Renderer::Initialize(int width, int height) {
|
||||||
muRenderQuadDepthNear = mRenderQuadProgramDepth.GetUniformLocation("uNear");
|
muRenderQuadDepthNear = mRenderQuadProgramDepth.GetUniformLocation("uNear");
|
||||||
muRenderQuadDepthFar = mRenderQuadProgramDepth.GetUniformLocation("uFar");
|
muRenderQuadDepthFar = mRenderQuadProgramDepth.GetUniformLocation("uFar");
|
||||||
|
|
||||||
|
// Render Target
|
||||||
|
gLog("Initializing main render target size: %d,%d", width, height);
|
||||||
|
mRenderTarget.Initialize(width, height,
|
||||||
|
RenderTarget::EnableColor
|
||||||
|
| RenderTarget::EnableDepthTexture
|
||||||
|
| RenderTarget::EnableLinearizedDepthTexture);
|
||||||
|
|
||||||
|
// Render Target Quad
|
||||||
|
glGenVertexArrays(1, &mRenderQuadVertexArrayId);
|
||||||
|
glBindVertexArray(mRenderQuadVertexArrayId);
|
||||||
|
|
||||||
|
glGenBuffers(1, &mRenderQuadVertexBufferId);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
mRenderTarget.mQuadVertexArray = mRenderQuadVertexArrayId;
|
||||||
|
mRenderTarget.mQuadVertexBuffer = mRenderQuadVertexBufferId;
|
||||||
|
mRenderTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth;
|
||||||
|
|
||||||
|
// Light
|
||||||
|
mLight.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shutdown() {
|
void Renderer::Shutdown() {
|
||||||
|
@ -348,14 +349,25 @@ void Renderer::RenderGl() {
|
||||||
mCamera.mHeight = mSceneAreaHeight;
|
mCamera.mHeight = mSceneAreaHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
|
// Shadow Map
|
||||||
mCamera.UpdateMatrices();
|
glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize);
|
||||||
|
mLight.mShadowMapTarget.Bind();
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
glUseProgram(mLight.mShadowMapProgram.mProgramId);
|
||||||
|
RenderScene(mLight.mShadowMapProgram);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
// TODO: render linearized depth for the light
|
||||||
|
// mLight.mShadowMapTarget.RenderToLinearizedDepth(mCamera);
|
||||||
|
|
||||||
|
// Regular rendering
|
||||||
glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
|
||||||
|
mCamera.UpdateMatrices();
|
||||||
|
|
||||||
Matrix44f model_matrix = TranslateMat44(0.0f, 0.0f, 0.0f);
|
Matrix44f model_matrix = TranslateMat44(0.0f, 0.0f, 0.0f);
|
||||||
Matrix44f model_view_projection =
|
Matrix44f model_view_projection =
|
||||||
model_matrix
|
model_matrix
|
||||||
|
@ -373,7 +385,7 @@ void Renderer::RenderGl() {
|
||||||
|
|
||||||
// clear color and depth
|
// clear color and depth
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
glUseProgram(mSimpleProgram.mProgramId);
|
glUseProgram(mSimpleProgram.mProgramId);
|
||||||
mSimpleProgram.SetMat44("uModelViewProj", model_view_projection);
|
mSimpleProgram.SetMat44("uModelViewProj", model_view_projection);
|
||||||
|
@ -399,65 +411,38 @@ void Renderer::RenderGl() {
|
||||||
gVertexArray.Bind();
|
gVertexArray.Bind();
|
||||||
gXZPlaneMesh.Draw(GL_LINES);
|
gXZPlaneMesh.Draw(GL_LINES);
|
||||||
|
|
||||||
// Unit cube
|
// Scene
|
||||||
glUseProgram(mDefaultProgram.mProgramId);
|
glUseProgram(mDefaultProgram.mProgramId);
|
||||||
gVertexArray.Bind();
|
glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
model_matrix = TranslateMat44(3.0f, 0.0f, 1.0f);
|
RenderScene(mDefaultProgram);
|
||||||
Matrix33f normal_matrix = model_matrix.block<3,3>(0,0).transpose();
|
|
||||||
normal_matrix = normal_matrix.inverse();
|
|
||||||
|
|
||||||
mDefaultProgram.SetMat44("uModelMatrix", model_matrix);
|
|
||||||
mDefaultProgram.SetMat44("uViewMatrix", mCamera.mViewMatrix);
|
|
||||||
mDefaultProgram.SetMat44("uProjectionMatrix", mCamera.mProjectionMatrix);
|
|
||||||
mDefaultProgram.SetMat33("uNormalMatrix", normal_matrix);
|
|
||||||
|
|
||||||
mDefaultProgram.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
mDefaultProgram.SetVec3("uLightDirection", mLight.mDirection);
|
|
||||||
mDefaultProgram.SetVec3("uViewPosition", mCamera.mEye);
|
|
||||||
gVertexArray.Bind();
|
|
||||||
gUnitCubeMesh.Draw(GL_TRIANGLES);
|
|
||||||
|
|
||||||
if (mSettings->DrawDepth) {
|
if (mSettings->DrawDepth) {
|
||||||
mRenderTarget.RenderToLinearizedDepth(true);
|
mRenderTarget.RenderToLinearizedDepth(mCamera);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
Matrix44f model_view_projection = Matrix44f::Identity();
|
|
||||||
|
|
||||||
// render depth texture
|
|
||||||
glUseProgram(mRenderQuadProgramDepth.mProgramId);
|
|
||||||
glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data());
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
|
|
||||||
glUniform1i(muRenderQuadTexture, 0);
|
|
||||||
|
|
||||||
// TODO: adjust for perspective
|
|
||||||
glUniform1f(muRenderQuadDepthNear, mCamera.mNear);
|
|
||||||
// TODO: why do I have to divide by depth range?
|
|
||||||
glUniform1f(muRenderQuadDepthFar, mCamera.mFar / (mCamera.mFar - mCamera.mNear));
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId);
|
|
||||||
glVertexAttribPointer(
|
|
||||||
0, // attribute 0
|
|
||||||
3, // size
|
|
||||||
GL_FLOAT, // type
|
|
||||||
GL_FALSE, // normalized?
|
|
||||||
0, // stride
|
|
||||||
(void*)0 // offset
|
|
||||||
);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total
|
|
||||||
|
|
||||||
mRenderTarget.RenderToLinearizedDepth(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderScene(RenderProgram &program) {
|
||||||
|
Matrix44f model_matrix = TranslateMat44(3.0f, 0.0f, 1.0f);
|
||||||
|
Matrix33f normal_matrix = model_matrix.block<3,3>(0,0).transpose();
|
||||||
|
normal_matrix = normal_matrix.inverse();
|
||||||
|
|
||||||
|
program.SetMat44("uModelMatrix", model_matrix);
|
||||||
|
program.SetMat44("uViewMatrix", mCamera.mViewMatrix);
|
||||||
|
program.SetMat44("uProjectionMatrix", mCamera.mProjectionMatrix);
|
||||||
|
program.SetMat33("uNormalMatrix", normal_matrix);
|
||||||
|
|
||||||
|
program.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
program.SetVec3("uLightDirection", mLight.mDirection);
|
||||||
|
program.SetVec3("uViewPosition", mCamera.mEye);
|
||||||
|
gVertexArray.Bind();
|
||||||
|
gUnitCubeMesh.Draw(GL_TRIANGLES);
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::RenderGui() {
|
void Renderer::RenderGui() {
|
||||||
if (ImGui::BeginDock("Scene")) {
|
if (ImGui::BeginDock("Scene")) {
|
||||||
ImGui::Checkbox("Draw Depth", &mSettings->DrawDepth);
|
ImGui::Checkbox("Draw Depth", &mSettings->DrawDepth);
|
||||||
|
@ -486,11 +471,17 @@ void Renderer::RenderGui() {
|
||||||
if (ImGui::BeginDock("Render Settings")) {
|
if (ImGui::BeginDock("Render Settings")) {
|
||||||
ImGui::Text("Light");
|
ImGui::Text("Light");
|
||||||
ImGui::SliderFloat3("Direction", mLight.mDirection.data(), -10.0f, 10.0f);
|
ImGui::SliderFloat3("Direction", mLight.mDirection.data(), -10.0f, 10.0f);
|
||||||
|
ImVec2 content_avail = ImGui::GetContentRegionAvail();
|
||||||
|
ImGui::Image((void*) mLight.mShadowMapTarget.mLinearizedDepthTexture,
|
||||||
|
ImVec2(content_avail.x, content_avail.x),
|
||||||
|
ImVec2(0.0f, 1.0f),
|
||||||
|
ImVec2(1.0f, 0.0f)
|
||||||
|
);
|
||||||
ImGui::Text("Camera");
|
ImGui::Text("Camera");
|
||||||
mCamera.DrawGui();
|
mCamera.DrawGui();
|
||||||
|
|
||||||
ImGui::Text("Default Texture");
|
ImGui::Text("Default Texture");
|
||||||
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
|
content_avail = ImGui::GetContentRegionAvail();
|
||||||
ImGui::Image((void*) mDefaultTexture.mTextureId,
|
ImGui::Image((void*) mDefaultTexture.mTextureId,
|
||||||
ImVec2(content_avail.x, content_avail.x),
|
ImVec2(content_avail.x, content_avail.x),
|
||||||
ImVec2(0.0f, 1.0f),
|
ImVec2(0.0f, 1.0f),
|
||||||
|
|
|
@ -14,94 +14,40 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "RenderUtils.h"
|
#include "RenderUtils.h"
|
||||||
|
|
||||||
struct Camera {
|
|
||||||
Vector3f mEye;
|
|
||||||
Vector3f mPoi;
|
|
||||||
Vector3f mUp;
|
|
||||||
|
|
||||||
float mNear;
|
|
||||||
float mFar;
|
|
||||||
float mFov;
|
|
||||||
bool mIsOrthographic;
|
|
||||||
float mWidth;
|
|
||||||
float mHeight;
|
|
||||||
|
|
||||||
Matrix44f mProjectionMatrix;
|
|
||||||
Matrix44f mViewMatrix;
|
|
||||||
|
|
||||||
Camera() :
|
|
||||||
mEye {5.f, 4.f, 5.f},
|
|
||||||
mPoi {0.f, 2.f, 0.f},
|
|
||||||
mUp {0.f, 1.f, 0.f},
|
|
||||||
mNear (0.1f),
|
|
||||||
mFar (150.f),
|
|
||||||
mFov (60.f),
|
|
||||||
mIsOrthographic (false),
|
|
||||||
mWidth (-1.f),
|
|
||||||
mHeight (-1.f),
|
|
||||||
|
|
||||||
mProjectionMatrix (
|
|
||||||
1.f, 0.f, 0.f, 0.f,
|
|
||||||
0.f, 1.f, 0.f, 0.f,
|
|
||||||
0.f, 0.f, 1.f, 0.f,
|
|
||||||
0.f, 0.f, 0.f, 1.f),
|
|
||||||
mViewMatrix (
|
|
||||||
1.f, 0.f, 0.f, 0.f,
|
|
||||||
0.f, 1.f, 0.f, 0.f,
|
|
||||||
0.f, 0.f, 1.f, 0.f,
|
|
||||||
0.f, 0.f, 0.f, 1.f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void UpdateMatrices();
|
|
||||||
void DrawGui();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
Vector3f mPosition;
|
Vector3f mPosition;
|
||||||
Vector3f mDirection;
|
Vector3f mDirection;
|
||||||
|
|
||||||
float mViewMatrix[16];
|
RenderTarget mShadowMapTarget;
|
||||||
float mProjectionMatrix[16];
|
RenderProgram mShadowMapProgram;
|
||||||
float mtxLight[16];
|
|
||||||
float mtxShadow[16];
|
|
||||||
|
|
||||||
float shadowMapBias;
|
float mShadowMapBias;
|
||||||
uint16_t shadowMapSize;
|
uint16_t mShadowMapSize;
|
||||||
|
|
||||||
bool enabled;
|
float mNear;
|
||||||
float near;
|
float mFar;
|
||||||
float far;
|
float mBBoxSize;
|
||||||
float area;
|
|
||||||
|
Matrix44f mLightProjection;
|
||||||
|
Matrix44f mLightView;
|
||||||
|
Matrix44f mLightSpaceMatrix;
|
||||||
|
|
||||||
Light() :
|
Light() :
|
||||||
mPosition (Vector3f(0.f, 10.f, 10.f)),
|
mPosition (Vector3f(0.f, 10.f, 10.f)),
|
||||||
mDirection (Vector3f(-1.f, -1.f, -1.f)),
|
mDirection (Vector3f(-1.f, -1.f, -1.f)),
|
||||||
mViewMatrix {
|
mShadowMapBias (0.004f),
|
||||||
1.f, 0.f, 0.f, 0.f,
|
mShadowMapSize (1024),
|
||||||
0.f, 1.f, 0.f, 0.f,
|
mNear (0.1f),
|
||||||
0.f, 0.f, 1.f, 0.f,
|
mFar (100.f),
|
||||||
0.f, 0.f, 0.f, 1.f
|
mBBoxSize (10.f),
|
||||||
},
|
mLightProjection(Matrix44f::Identity()),
|
||||||
mProjectionMatrix {
|
mLightView(Matrix44f::Identity()),
|
||||||
1.f, 0.f, 0.f, 0.f,
|
mLightSpaceMatrix(Matrix44f::Identity())
|
||||||
0.f, 1.f, 0.f, 0.f,
|
|
||||||
0.f, 0.f, 1.f, 0.f,
|
|
||||||
0.f, 0.f, 0.f, 1.f
|
|
||||||
},
|
|
||||||
mtxShadow {
|
|
||||||
1.f, 0.f, 0.f, 0.f,
|
|
||||||
0.f, 1.f, 0.f, 0.f,
|
|
||||||
0.f, 0.f, 1.f, 0.f,
|
|
||||||
0.f, 0.f, 0.f, 1.f
|
|
||||||
},
|
|
||||||
shadowMapBias (0.004f),
|
|
||||||
shadowMapSize (2048),
|
|
||||||
near (0.1f),
|
|
||||||
far (100.f),
|
|
||||||
area (10.f),
|
|
||||||
enabled (false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void UpdateMatrices();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RendererSettings;
|
struct RendererSettings;
|
||||||
|
@ -151,5 +97,6 @@ struct Renderer {
|
||||||
void Initialize(int width, int height);
|
void Initialize(int width, int height);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void RenderGl();
|
void RenderGl();
|
||||||
|
void RenderScene(RenderProgram &program);
|
||||||
void RenderGui();
|
void RenderGui();
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,11 +9,46 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "FileModificationObserver.h"
|
#include "FileModificationObserver.h"
|
||||||
|
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
#include "imgui_dock.h"
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
|
||||||
#include "stb/stb_image.h"
|
#include "stb/stb_image.h"
|
||||||
|
|
||||||
using namespace SimpleMath;
|
using namespace SimpleMath;
|
||||||
|
using namespace SimpleMath::GL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Camera
|
||||||
|
//
|
||||||
|
void Camera::UpdateMatrices() {
|
||||||
|
mViewMatrix = LookAt(mEye, mPoi, mUp);
|
||||||
|
|
||||||
|
if (mIsOrthographic) {
|
||||||
|
mProjectionMatrix = Ortho(-1.0f, 1.0f, -1.0f, 1.0f, mNear, mFar);
|
||||||
|
} else {
|
||||||
|
mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::DrawGui() {
|
||||||
|
ImGui::Text("Width %3.4f, Height %3.4f", mWidth, mHeight);
|
||||||
|
|
||||||
|
ImGui::InputFloat3("Eye", mEye.data(), -10.0f, 10.0f);
|
||||||
|
ImGui::SliderFloat3("EyeS", mEye.data(), -10.0f, 10.0f);
|
||||||
|
|
||||||
|
ImGui::InputFloat3("Poi", mPoi.data(), -10.0f, 10.0f);
|
||||||
|
ImGui::InputFloat3("Up", mUp.data(), -10.0f, 10.0f);
|
||||||
|
ImGui::Checkbox("Orthographic", &mIsOrthographic);
|
||||||
|
ImGui::SliderFloat("Fov", &mFov, 5, 160);
|
||||||
|
ImGui::SliderFloat("Near", &mNear, -10, 10);
|
||||||
|
ImGui::SliderFloat("Far", &mFar, -20, 50);
|
||||||
|
if (ImGui::Button("Reset")) {
|
||||||
|
*this = Camera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// RenderProgram
|
// RenderProgram
|
||||||
|
@ -230,15 +265,21 @@ bool RenderProgram::OnFileChanged(const std::string& filename) {
|
||||||
//
|
//
|
||||||
// RenderTarget
|
// RenderTarget
|
||||||
//
|
//
|
||||||
RenderTarget::RenderTarget(int width, int height, int flags) {
|
RenderTarget::~RenderTarget() {
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderTarget::Initialize(int width, int height, int flags) {
|
||||||
|
Cleanup();
|
||||||
|
|
||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
|
|
||||||
Cleanup();
|
|
||||||
Resize(width, height);
|
Resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTarget::~RenderTarget() {
|
void RenderTarget::Bind() {
|
||||||
Cleanup();
|
assert(glIsFramebuffer(mFrameBufferId));
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTarget::Cleanup() {
|
void RenderTarget::Cleanup() {
|
||||||
|
@ -277,7 +318,7 @@ void RenderTarget::Resize(int width, int height) {
|
||||||
|
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
gLog("Resizing RenderTarget");
|
gLog("Resizing RenderTarget to %d,%d", width, height);
|
||||||
|
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
mHeight = height;
|
mHeight = height;
|
||||||
|
@ -294,7 +335,7 @@ void RenderTarget::Resize(int width, int height) {
|
||||||
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_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFlags & EnableDepthTexture) {
|
if (mFlags & EnableDepthTexture) {
|
||||||
|
@ -310,7 +351,7 @@ void RenderTarget::Resize(int width, int height) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTexture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture, 0);
|
||||||
|
|
||||||
if (mFlags & EnableLinearizedDepthTexture) {
|
if (mFlags & EnableLinearizedDepthTexture) {
|
||||||
glGenTextures(1, &mLinearizedDepthTexture);
|
glGenTextures(1, &mLinearizedDepthTexture);
|
||||||
|
@ -329,15 +370,64 @@ void RenderTarget::Resize(int width, int height) {
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mWidth, mHeight);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mWidth, mHeight);
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if (result != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
switch (result) {
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: gLog("Error: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_UNDEFINED: gLog("Error: GL_FRAMEBUFFER_UNDEFINED");
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: gLog("Error: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
|
||||||
|
break;
|
||||||
|
default: gLog("Error when creating Framebuffer: %d", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(result == GL_FRAMEBUFFER_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTarget::RenderToLinearizedDepth(bool render_to_depth) {
|
void RenderTarget::RenderToLinearizedDepth(const Camera& camera) {
|
||||||
if (render_to_depth) {
|
|
||||||
assert(mFlags & EnableLinearizedDepthTexture);
|
assert(mFlags & EnableLinearizedDepthTexture);
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mLinearizedDepthTexture, 0);
|
assert(mLinearizedDepthTexture != -1);
|
||||||
} else {
|
assert(mQuadVertexArray != -1);
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0);
|
assert(mQuadVertexBuffer != -1);
|
||||||
}
|
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mLinearizedDepthTexture, 0);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
Matrix44f model_view_projection = Matrix44f::Identity();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mDepthTexture);
|
||||||
|
|
||||||
|
// render depth texture
|
||||||
|
glUseProgram(mLinearizeDepthProgram.mProgramId);
|
||||||
|
mLinearizeDepthProgram.SetMat44("uModelViewProj", model_view_projection);
|
||||||
|
mLinearizeDepthProgram.SetFloat("uNear", camera.mNear);
|
||||||
|
mLinearizeDepthProgram.SetFloat("uFar", camera.mFar);
|
||||||
|
mLinearizeDepthProgram.SetFloat("uIsOrthographic", camera.mIsOrthographic ? 1.0f : 0.0f);
|
||||||
|
mLinearizeDepthProgram.SetInt("uDepthTexture", 0);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
|
||||||
|
glVertexAttribPointer(
|
||||||
|
0, // attribute 0
|
||||||
|
3, // size
|
||||||
|
GL_FLOAT, // type
|
||||||
|
GL_FALSE, // normalized?
|
||||||
|
0, // stride
|
||||||
|
(void*)0 // offset
|
||||||
|
);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total
|
||||||
|
|
||||||
|
if (mFlags & EnableColor)
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture, 0);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -129,6 +129,50 @@ struct Transform {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Camera {
|
||||||
|
Vector3f mEye;
|
||||||
|
Vector3f mPoi;
|
||||||
|
Vector3f mUp;
|
||||||
|
|
||||||
|
float mNear;
|
||||||
|
float mFar;
|
||||||
|
float mFov;
|
||||||
|
bool mIsOrthographic;
|
||||||
|
float mWidth;
|
||||||
|
float mHeight;
|
||||||
|
|
||||||
|
Matrix44f mProjectionMatrix;
|
||||||
|
Matrix44f mViewMatrix;
|
||||||
|
|
||||||
|
Camera() :
|
||||||
|
mEye {5.f, 4.f, 5.f},
|
||||||
|
mPoi {0.f, 2.f, 0.f},
|
||||||
|
mUp {0.f, 1.f, 0.f},
|
||||||
|
mNear (0.1f),
|
||||||
|
mFar (150.f),
|
||||||
|
mFov (60.f),
|
||||||
|
mIsOrthographic (false),
|
||||||
|
mWidth (-1.f),
|
||||||
|
mHeight (-1.f),
|
||||||
|
|
||||||
|
mProjectionMatrix (
|
||||||
|
1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 1.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 1.f, 0.f,
|
||||||
|
0.f, 0.f, 0.f, 1.f),
|
||||||
|
mViewMatrix (
|
||||||
|
1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 1.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 1.f, 0.f,
|
||||||
|
0.f, 0.f, 0.f, 1.f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void UpdateMatrices();
|
||||||
|
void DrawGui();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct RenderProgram : AFileModificationListener {
|
struct RenderProgram : AFileModificationListener {
|
||||||
std::string mVertexShaderFilename;
|
std::string mVertexShaderFilename;
|
||||||
std::string mFragmentShaderFilename;
|
std::string mFragmentShaderFilename;
|
||||||
|
@ -153,6 +197,14 @@ struct RenderProgram : AFileModificationListener {
|
||||||
GLuint CompileFragmentShader();
|
GLuint CompileFragmentShader();
|
||||||
GLuint LinkProgram(GLuint vertex_shader, GLuint fragment_shader);
|
GLuint LinkProgram(GLuint vertex_shader, GLuint fragment_shader);
|
||||||
|
|
||||||
|
void SetInt(const char* name, const GLint& val) {
|
||||||
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
|
glUniform1i(location, val);
|
||||||
|
}
|
||||||
|
void SetFloat(const char* name, const float& val) {
|
||||||
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
|
glUniform1f(location, val);
|
||||||
|
}
|
||||||
void SetVec3(const char* name, const Vector3f& vec) {
|
void SetVec3(const char* name, const Vector3f& vec) {
|
||||||
GLint location = glGetUniformLocation(mProgramId, name);
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
glUniform3fv(location, 1, vec.data());
|
glUniform3fv(location, 1, vec.data());
|
||||||
|
@ -179,7 +231,7 @@ struct RenderProgram : AFileModificationListener {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderSettings;
|
struct RenderSettings;
|
||||||
|
struct RenderProgram;
|
||||||
|
|
||||||
struct RenderTarget {
|
struct RenderTarget {
|
||||||
int mWidth = 0;
|
int mWidth = 0;
|
||||||
|
@ -199,13 +251,19 @@ struct RenderTarget {
|
||||||
|
|
||||||
int mFlags = 0;
|
int mFlags = 0;
|
||||||
|
|
||||||
|
RenderProgram mLinearizeDepthProgram;
|
||||||
|
GLuint mQuadVertexArray = -1;
|
||||||
|
GLuint mQuadVertexBuffer = -1;
|
||||||
|
|
||||||
RenderTarget() {};
|
RenderTarget() {};
|
||||||
RenderTarget(int width, int height, int flags);
|
|
||||||
~RenderTarget();
|
~RenderTarget();
|
||||||
|
|
||||||
|
void Initialize(int width, int height, int flags);
|
||||||
|
void Bind();
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
void Resize(int width, int height);
|
void Resize(int width, int height);
|
||||||
void RenderToLinearizedDepth(bool render_to_depth);
|
|
||||||
|
void RenderToLinearizedDepth(const Camera &camera);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
|
|
Loading…
Reference in New Issue