实现力的显示

main
wuyize 2023-04-18 23:58:56 +08:00
parent c5b8729ed6
commit 588bfecd65
21 changed files with 419 additions and 245 deletions

View File

@ -0,0 +1,14 @@
#version 450 core
layout (location = 4) out vec4 gDebug;
in vec2 TexCoords;
in vec3 WorldPos;
in vec3 Normal;
uniform vec3 color;
void main()
{
gDebug = vec4(color,1);
}

View File

@ -0,0 +1,22 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
out vec2 TexCoords;
out vec3 WorldPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = aTexCoords;
WorldPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(model) * aNormal;
gl_Position = projection * view * vec4(WorldPos, 1.0);
}

View File

@ -5,7 +5,9 @@ out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D gBaseColor;
uniform sampler2D gDebug;
uniform float exposure = 1;
uniform bool showDebug = false;
vec3 ACESToneMapping(vec3 color)
{
@ -20,7 +22,8 @@ vec3 ACESToneMapping(vec3 color)
void main()
{
vec4 rgbm = texture(gBaseColor, TexCoords);
if(rgbm.a==0)
vec4 debug = texture(gDebug, TexCoords);
if(rgbm.a==0 && (showDebug ? debug.a==0 : true))
{
//FragColor = vec4(1,0,0,1);
//return;
@ -34,5 +37,6 @@ void main()
//color = color / (color + vec3(1.0));
color = pow(color, vec3(1.0/2.2));
FragColor = vec4(color, 1.0);
return;
if(showDebug)
FragColor = mix(FragColor, debug, debug.a);
}

View File

@ -14,6 +14,7 @@ layout (location = 0) out vec4 gBaseColor;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec3 gPosition;
layout (location = 3) out vec2 gMetallicRoughness;
layout (location = 4) out vec4 gDebug;
in vec2 TexCoords;
in vec3 WorldPos;
@ -55,4 +56,6 @@ void main()
gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).bg;
else
gMetallicRoughness = metallicRoughness;
gDebug = vec4(0);
}

View File

@ -32,6 +32,7 @@
<ClInclude Include="src\Model.h" />
<ClInclude Include="src\Particle.h" />
<ClInclude Include="src\RenderPass.h" />
<ClInclude Include="src\RenderPassContext.h" />
<ClInclude Include="src\Shader.h" />
<ClInclude Include="src\World.h" />
</ItemGroup>
@ -51,6 +52,7 @@
<ClCompile Include="src\Model.cpp" />
<ClCompile Include="src\Particle.cpp" />
<ClCompile Include="src\RenderPass.cpp" />
<ClCompile Include="src\Shader.cpp" />
<ClCompile Include="src\World.cpp" />
</ItemGroup>
<ItemGroup>
@ -58,6 +60,8 @@
<None Include="Shaders\cubemap.frag" />
<None Include="Shaders\cubemap.vert" />
<None Include="Shaders\cubemap_prefilter.frag" />
<None Include="Shaders\debug.frag" />
<None Include="Shaders\debug.vert" />
<None Include="Shaders\final.frag" />
<None Include="Shaders\final.vert" />
<None Include="Shaders\irradiance_convolution.frag" />

View File

@ -26,7 +26,7 @@ void Actor::rendererTick(float deltaTime)
}
void Actor::draw(Shader& shader)
void Actor::draw(const RenderPassContext& context, Shader& shader)
{
gl->BindBufferBase(GL_UNIFORM_BUFFER, 1, animator.getFinalBonesMatricesUBO());
model.draw(shader);

View File

@ -3,6 +3,7 @@
#include <glm/gtc/quaternion.hpp>
#include "Animation.h"
#include "Animator.h"
#include "RenderPassContext.h"
class Actor
{
@ -12,7 +13,7 @@ public:
virtual ~Actor() = default;
virtual void logicalTick(float deltaTime);
virtual void rendererTick(float deltaTime);
virtual void draw(Shader& shader);
virtual void draw(const RenderPassContext& context, Shader& shader);
void setPosition(const glm::vec3& position);
void setScale(const glm::vec3& scale);

View File

@ -98,7 +98,7 @@ private:
dest.transformation = glm::transpose(glm::make_mat4((float*)&src->mTransformation));
dest.childrenCount = src->mNumChildren;
for (int i = 0; i < src->mNumChildren; i++)
for (auto i = 0U; i < src->mNumChildren; i++)
{
AssimpNodeData newData;
ReadHeirarchyData(newData, src->mChildren[i]);

View File

@ -31,10 +31,9 @@ class Bone
{
public:
Bone(const std::string& name, int ID, const aiNodeAnim* channel)
:
m_Name(name),
m_ID(ID),
m_LocalTransform(1.0f)
: m_Name(name)
, m_ID(ID)
, m_LocalTransform(1.0f)
{
m_NumPositions = channel->mNumPositionKeys;
@ -65,7 +64,7 @@ public:
aiVector3D scale = channel->mScalingKeys[keyIndex].mValue;
float timeStamp = channel->mScalingKeys[keyIndex].mTime;
KeyScale data;
data.scale = glm::vec3(scale.x, scale.y,scale.z);
data.scale = glm::vec3(scale.x, scale.y, scale.z);
data.timeStamp = timeStamp;
m_Scales.push_back(data);
}

View File

@ -23,7 +23,7 @@ DemoWorld::DemoWorld()
auto particle = std::make_shared<Particle>(10);
particle->setPosition({ 4, 5, 0 });
particle->addForce(glm::vec3(0, -particle->getMass() * 9.8f, 0));
particle->addForce(std::make_shared<Force>(glm::vec3(0.f, -particle->getMass() * 9.8f, 0.f)));
addActor(actor);
addActor(actor2);

View File

@ -31,6 +31,9 @@ int MainWindow::exec()
glfwSetScrollCallback(window, [](GLFWwindow* window, double xoffset, double yoffset) {
MainWindow::instance().scrollCallback(window, xoffset, yoffset);
});
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
MainWindow::instance().keyCallback(window, key, scancode, action, mods);
});
int xpos, ypos, width, height;
glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
glfwSetWindowPos(window, xpos + (width - (kWindowWidth * xscale)) / 2, ypos + (height - kWindowHeight * yscale) / 2);
@ -47,10 +50,11 @@ int MainWindow::exec()
if (type == GL_DEBUG_TYPE_ERROR)
std::cerr << std::format("GL_ERROR: type = {:#x}, severity = {:#x}, message = {}", type, severity, message);
}, 0);
gl->ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl->Enable(GL_DEPTH_TEST);
gl->DepthFunc(GL_LEQUAL);
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
gl->LineWidth(5 * xscale);
std::unique_ptr<World> world = std::make_unique<DemoWorld>();
@ -66,7 +70,7 @@ int MainWindow::exec()
GeometryPass geometryPass(gl.get(), frameWidth, frameHeight, fbo, *world, projection, view);
LightingPass lightingPass(gl.get(), frameWidth, frameHeight, view, camera, light, mainLightRadiance,
gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
FinalPass finalPass(gl.get(), frameWidth, frameHeight, gbuffers, exposure);
FinalPass finalPass(gl.get(), frameWidth, frameHeight, gBaseColor, gDebug, exposure);
SkyboxPass skyboxPass(gl.get(), projection, view, exposure, skyCubemap);
int w, h;
@ -109,6 +113,7 @@ int MainWindow::exec()
shadowMapPass.dispatch();
geometryPass.dispatch();
lightingPass.dispatch();
finalPass.setShowDebug(showDebug);
finalPass.dispatch();
skyboxPass.dispatch();
@ -174,45 +179,30 @@ void MainWindow::framebufferSizeCallback(GLFWwindow* window, int width, int heig
gl->DeleteFramebuffers(1, &fbo);
}
gl->CreateFramebuffers(1, &fbo);
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
{
gl->GenTextures(gbuffers.size(), gbuffers.data());
//BaseColor
gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, frameWidth, frameHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gbuffers[0], 0);
//Normal
gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]);
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0);
//Position
gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]);
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0);
//MetallicRoughness
gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]);
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0);
gl->CreateFramebuffers(1, &fbo);
gl->CreateTextures(GL_TEXTURE_2D, gbuffers.size(), gbuffers.data());
gl->TextureStorage2D(gBaseColor, 1, GL_RGBA8, frameWidth, frameHeight);
gl->TextureStorage2D(gNormal, 1, GL_RGB16F, frameWidth, frameHeight);
gl->TextureStorage2D(gPosition, 1, GL_RGB32F, frameWidth, frameHeight);
gl->TextureStorage2D(gMetallicRoughness, 1, GL_RG8, frameWidth, frameHeight);
gl->TextureStorage2D(gDebug, 1, GL_RGBA8, frameWidth, frameHeight);
std::array<GLenum, 4> attachments = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
gl->DrawBuffers(attachments.size(), attachments.data());
gl->GenRenderbuffers(1, &rboDepth);
gl->BindRenderbuffer(GL_RENDERBUFFER, rboDepth);
gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, frameWidth, frameHeight);
gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);
if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::vector<GLenum> attachments;
for (auto i = 0U; i < gbuffers.size(); i++)
{
gl->TextureParameteri(gbuffers[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TextureParameteri(gbuffers[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, gbuffers[i], 0);
attachments.push_back(GL_COLOR_ATTACHMENT0 + i);
}
gl->NamedFramebufferDrawBuffers(fbo, attachments.size(), attachments.data());
gl->CreateRenderbuffers(1, &rboDepth);
gl->NamedRenderbufferStorage(rboDepth, GL_DEPTH_COMPONENT, frameWidth, frameHeight);
gl->NamedFramebufferRenderbuffer(fbo, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);
if (gl->CheckNamedFramebufferStatus(fbo, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cerr << "Framebuffer not complete!\n";
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
}
if (shadowFboHandle != 0)
@ -282,6 +272,12 @@ void MainWindow::scrollCallback(GLFWwindow* window, double xoffset, double yoffs
camera.processMouseScroll(yoffset);
}
void MainWindow::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_TAB && action == GLFW_PRESS)
showDebug = !showDebug;
}
MainWindow& MainWindow::instance()
{
static MainWindow window;

View File

@ -18,6 +18,7 @@ private:
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
void mouseCallback(GLFWwindow* window, double xpos, double ypos);
void scrollCallback(GLFWwindow* window, double xoffset, double yoffset);
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
void processInput(GLFWwindow* window, float deltaTime);
static constexpr int kWindowWidth = 1200;
@ -33,10 +34,18 @@ private:
std::unique_ptr<GladGLContext> gl;
GLuint fbo = 0;
std::array<GLuint, 4> gbuffers;
std::array<GLuint, 5> gbuffers;
GLuint& gBaseColor = gbuffers[0];
GLuint& gNormal = gbuffers[1];
GLuint& gPosition = gbuffers[2];
GLuint& gMetallicRoughness = gbuffers[3];
GLuint& gDebug = gbuffers[4];
GLuint rboDepth = 0;
GLuint shadowFboHandle = 0;
GLuint shadowGbuffer;
int shadowMapResolution;
bool showDebug = false;
};

View File

@ -1,28 +1,76 @@
#include "Particle.h"
#include "RenderPass.h"
Particle::Particle(float mass)
: Actor()
, mass(mass)
, debugShader(gl, "Shaders/debug.vert", "Shaders/debug.frag")
{
model = Model::createSphere(gl);
setScale(glm::vec3(0.5));
setScale(glm::vec3(0.4));
}
void Particle::logicalTick(float deltaTime)
{
auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
speed += resultantForce / mass * deltaTime;
if (speed.y < 0 && pos.y < 0.5)
if (speed.y < 0 && pos.y < 0.4)
{
speed.y = -speed.y;
}
setPosition(pos);
}
void Particle::addForce(glm::vec3 force)
void Particle::draw(const RenderPassContext& context, Shader& shader)
{
forces.push_back(force);
resultantForce += force;
Actor::draw(context, shader);
if (context.passType == typeid(GeometryPass))
{
static unsigned int vao = 0;
static unsigned int vbo;
if (vao == 0)
{
float vertices[] = {
// positions
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
};
// setup plane VAO
gl->GenVertexArrays(1, &vao);
gl->GenBuffers(1, &vbo);
gl->BindVertexArray(vao);
gl->BindBuffer(GL_ARRAY_BUFFER, vbo);
gl->BufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
gl->EnableVertexAttribArray(0);
gl->VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
}
debugShader.use();
debugShader.setUniformValue("projection", *context.projection);
debugShader.setUniformValue("view", *context.view);
glm::mat4 modelMatrix = glm::translate(glm::mat4(1), getPosition()) * glm::scale(glm::mat4(1), getScale()) * glm::mat4_cast(getRotation());
gl->BindVertexArray(vao);
for (auto& force : forces)
{
debugShader.setUniformValue("model", modelMatrix * glm::scale(glm::mat4(1), glm::vec3(5)) * glm::mat4_cast(glm::rotation(glm::vec3(1, 0, 0), glm::normalize(force->value))));
debugShader.setUniformValue("color", glm::vec3(0, 1, 0));
gl->DrawArrays(GL_LINES, 0, 2);
}
gl->BindVertexArray(0);
shader.use();
}
}
void Particle::addForce(std::shared_ptr<Force> force)
{
forces.insert(force);
resultantForce += force->value;
}
void Particle::removeForce(std::shared_ptr<Force> force)
{
forces.erase(force);
resultantForce -= force->value;
}
float Particle::getMass()

View File

@ -1,5 +1,12 @@
#pragma once
#include "Actor.h"
#include "Shader.h"
struct Force
{
glm::vec3 value;
Force(glm::vec3 value) :value(value) {}
};
class Particle : public Actor
{
@ -7,12 +14,15 @@ public:
Particle(float mass);
virtual ~Particle() = default;
virtual void logicalTick(float deltaTime);
void addForce(glm::vec3 force);
virtual void draw(const RenderPassContext& context, Shader& shader);
void addForce(std::shared_ptr<Force> force);
void removeForce(std::shared_ptr<Force> force);
float getMass();
private:
float mass;
glm::vec3 speed = glm::vec3(0.f);
std::vector<glm::vec3> forces;
std::set<std::shared_ptr<Force>> forces;
glm::vec3 resultantForce = glm::vec3(0);
Shader debugShader;
};

View File

@ -3,7 +3,7 @@
#include "Mesh.h"
ShadowMapPass::ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world, Light& light)
: RenderPass(gl)
: RenderPass(gl, { typeid(ShadowMapPass) })
, modelShadowShader(gl, "Shaders/model_shadow.vert", "Shaders/model_shadow.frag", "Shaders/model_shadow.geom")
, shadowFboHandle(shadowFboHandle)
, shadowMapResolution(shadowMapResolution)
@ -24,13 +24,13 @@ void ShadowMapPass::dispatch()
gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
gl->Clear(GL_DEPTH_BUFFER_BIT);
modelShadowShader.use();
world.draw(modelShadowShader);
world.draw(context, modelShadowShader);
modelShadowShader.release();
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
}
GeometryPass::GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& fbo, World& world, glm::mat4& projection, glm::mat4& view)
: RenderPass(gl)
: RenderPass(gl, { typeid(GeometryPass) })
, modelShader(gl, "Shaders/model.vert", "Shaders/model.frag")
, plainShader(gl, "Shaders/plain.vert", "Shaders/plain.frag")
, frameWidth(frameWidth)
@ -44,6 +44,9 @@ GeometryPass::GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned
void GeometryPass::dispatch()
{
context.projection = &projection;
context.view = &view;
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl->Viewport(0, 0, frameWidth, frameHeight);
@ -51,7 +54,7 @@ void GeometryPass::dispatch()
modelShader.use();
modelShader.setUniformValue("projection", projection);
modelShader.setUniformValue("view", view);
world.draw(modelShader);
world.draw(context, modelShader);
modelShader.release();
/// Debug Lighting
@ -86,8 +89,8 @@ void GeometryPass::dispatch()
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
}
LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, glm::mat4& view, Camera& camera, Light& light, glm::vec3& mainLightRadiance, std::array<GLuint, 4>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture)
: RenderPass(gl)
LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, glm::mat4& view, Camera& camera, Light& light, glm::vec3& mainLightRadiance, std::array<GLuint, 5>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture)
: RenderPass(gl, { typeid(LightingPass) })
, pbrShader(gl, "Shaders/pbr.comp")
, frameWidth(frameWidth)
, frameHeight(frameHeight)
@ -138,16 +141,18 @@ void LightingPass::dispatch()
pbrShader.release();
}
FinalPass::FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, std::array<GLuint, 4>& gbuffers, float& exposure)
: RenderPass(gl)
FinalPass::FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& colorBuffer, GLuint& debugBuffer, float& exposure)
: RenderPass(gl, { typeid(FinalPass) })
, finalShader(gl, "Shaders/final.vert", "Shaders/final.frag")
, frameWidth(frameWidth)
, frameHeight(frameHeight)
, gbuffers(gbuffers)
, colorBuffer(colorBuffer)
, debugBuffer(debugBuffer)
, exposure(exposure)
{
finalShader.use();
finalShader.setUniformValue("gBaseColor", 0);
finalShader.setUniformValue("gDebug", 1);
finalShader.release();
}
@ -157,13 +162,25 @@ void FinalPass::dispatch()
gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
finalShader.use();
finalShader.setUniformValue("exposure", exposure);
gl->BindTextureUnit(0, gbuffers[0]);
finalShader.setUniformValue("showDebug", showDebug);
gl->BindTextureUnit(0, colorBuffer);
gl->BindTextureUnit(1, debugBuffer);
IblUtils::renderQuad(gl);
finalShader.release();
}
void FinalPass::setShowDebug(bool enable)
{
showDebug = enable;
}
bool FinalPass::getShowDebug()
{
return showDebug;
}
SkyboxPass::SkyboxPass(GladGLContext* gl, glm::mat4& projection, glm::mat4& view, float& exposure, GLuint& skyCubemap)
: RenderPass(gl)
: RenderPass(gl, { typeid(SkyboxPass) })
, skyBoxShader(gl, "Shaders/skybox.vert", "Shaders/skybox.frag")
, projection(projection)
, view(view)

View File

@ -5,14 +5,16 @@
#include "Light.h"
#include <array>
#include "Animator.h"
#include "RenderPassContext.h"
class RenderPass
{
public:
RenderPass(GladGLContext* gl) :gl(gl) {};
RenderPass(GladGLContext* gl, RenderPassContext context) : gl(gl), context(context) {};
virtual void dispatch() = 0;
protected:
GladGLContext* gl = nullptr;
RenderPassContext context;
};
class ShadowMapPass : public RenderPass
@ -38,7 +40,6 @@ public:
private:
Shader modelShader;
Shader plainShader;
GLuint finalBonesMatricesUBO;
unsigned int& frameWidth;
unsigned int& frameHeight;
GLuint& fbo;
@ -52,7 +53,7 @@ class LightingPass : public RenderPass
public:
LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight,
glm::mat4& view, Camera& camera, Light& light, glm::vec3& mainLightRadiance,
std::array<GLuint, 4>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap,
std::array<GLuint, 5>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap,
GLuint& prefilterMap, GLuint& brdfLUTTexture);
void dispatch();
private:
@ -63,7 +64,7 @@ private:
Camera& camera;
Light& light;
glm::vec3& mainLightRadiance;
std::array<GLuint, 4>& gbuffers;
std::array<GLuint, 5>& gbuffers;
GLuint& shadowGbuffer;
GLuint& irradianceMap;
GLuint& prefilterMap;
@ -73,13 +74,17 @@ private:
class FinalPass : public RenderPass
{
public:
FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, std::array<GLuint, 4>& gbuffers, float& exposure);
FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& colorBuffer, GLuint& debugBuffer, float& exposure);
void dispatch();
void setShowDebug(bool enable);
bool getShowDebug();
private:
Shader finalShader;
bool showDebug = false;
unsigned int& frameWidth;
unsigned int& frameHeight;
std::array<GLuint, 4>& gbuffers;
GLuint& colorBuffer;
GLuint& debugBuffer;
float& exposure;
};

View File

@ -0,0 +1,9 @@
#pragma once
#include <typeinfo>
struct RenderPassContext
{
const std::type_info& passType;
glm::mat4* projection = nullptr;
glm::mat4* view = nullptr;
};

176
ToyEngine/src/Shader.cpp Normal file
View File

@ -0,0 +1,176 @@
#include "Shader.h"
Shader::Shader(GladGLContext* gl, const char* vertexPath, const char* fragmentPath, const char* geometryPath)
: Shader(gl)
{
addShaderFromSourceFile(ShaderType::Vertex, vertexPath);
addShaderFromSourceFile(ShaderType::Fragment, fragmentPath);
if (geometryPath)
addShaderFromSourceFile(ShaderType::Geometry, geometryPath);
link();
}
Shader::Shader(GladGLContext* gl, const char* computePath)
: Shader(gl)
{
addShaderFromSourceFile(ShaderType::Compute, computePath);
link();
}
Shader::Shader(GladGLContext* gl)
: gl(gl)
{
ID = gl->CreateProgram();
}
bool Shader::addShaderFromSourceFile(ShaderType type, const char* path)
{
// 1. retrieve the vertex/fragment source code from filePath
std::string shaderCode;
std::ifstream shaderFile;
// ensure ifstream objects can throw exceptions:
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
shaderFile.open(path);
std::stringstream gShaderStream;
gShaderStream << shaderFile.rdbuf();
shaderFile.close();
shaderCode = gShaderStream.str();
}
catch (std::ifstream::failure&)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
return false;
}
unsigned int shader;
const char* gShaderCode = shaderCode.c_str();
shader = gl->CreateShader((GLenum)type);
gl->ShaderSource(shader, 1, &gShaderCode, NULL);
gl->CompileShader(shader);
if (!checkCompileErrors(shader))
return false;
// shader Program
gl->AttachShader(ID, shader);
// delete the shaders as they're linked into our program now and no longer necessery
gl->DeleteShader(shader);
return true;
}
bool Shader::link()
{
gl->LinkProgram(ID);
return checkLinkErrors(ID);
}
// activate the shader
// ------------------------------------------------------------------------
void Shader::use()
{
gl->UseProgram(ID);
}
void Shader::release()
{
gl->UseProgram(0);
}
// utility uniform functions
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, bool value) const
{
gl->Uniform1i(gl->GetUniformLocation(ID, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, int value) const
{
gl->Uniform1i(gl->GetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, float value) const
{
gl->Uniform1f(gl->GetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, const glm::vec2& value) const
{
gl->Uniform2fv(gl->GetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void Shader::setUniformValue(const std::string& name, float x, float y) const
{
gl->Uniform2f(gl->GetUniformLocation(ID, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, const glm::vec3& value) const
{
gl->Uniform3fv(gl->GetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void Shader::setUniformValue(const std::string& name, float x, float y, float z) const
{
gl->Uniform3f(gl->GetUniformLocation(ID, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, const glm::vec4& value) const
{
gl->Uniform4fv(gl->GetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void Shader::setUniformValue(const std::string& name, float x, float y, float z, float w)
{
gl->Uniform4f(gl->GetUniformLocation(ID, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, const glm::mat2& mat) const
{
gl->UniformMatrix2fv(gl->GetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, const glm::mat3& mat) const
{
gl->UniformMatrix3fv(gl->GetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void Shader::setUniformValue(const std::string& name, const glm::mat4& mat) const
{
gl->UniformMatrix4fv(gl->GetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void Shader::setUniformValueArray(const std::string& name, const glm::vec3* value, int count) const
{
gl->Uniform3fv(gl->GetUniformLocation(ID, name.c_str()), count, &value->x);
}
// ------------------------------------------------------------------------
void Shader::setUniformValueArray(const std::string& name, const GLfloat* values, int count) const
{
gl->Uniform1fv(gl->GetUniformLocation(ID, name.c_str()), count, values);
}
bool Shader::checkCompileErrors(GLuint shader)
{
GLint success;
GLchar infoLog[1024];
gl->GetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
gl->GetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR" << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
return success;
}
bool Shader::checkLinkErrors(GLuint shader)
{
GLint success;
GLchar infoLog[1024];
gl->GetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
gl->GetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR" << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
return success;
}

View File

@ -9,7 +9,7 @@
#include <sstream>
#include <iostream>
enum class ShaderType
enum class ShaderType : GLenum
{
Vertex = GL_VERTEX_SHADER,
Fragment = GL_FRAGMENT_SHADER,
@ -23,180 +23,36 @@ class Shader
{
public:
unsigned int ID;
// constructor generates the shader on the fly
// ------------------------------------------------------------------------
Shader(GladGLContext* gl, const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr)
: Shader(gl)
{
addShaderFromSourceFile(ShaderType::Vertex, vertexPath);
addShaderFromSourceFile(ShaderType::Fragment, fragmentPath);
if (geometryPath)
addShaderFromSourceFile(ShaderType::Geometry, geometryPath);
link();
}
Shader(GladGLContext* gl, const char* computePath)
: Shader(gl)
{
addShaderFromSourceFile(ShaderType::Compute, computePath);
link();
}
Shader(GladGLContext* gl, const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr);
Shader(GladGLContext* gl, const char* computePath);
Shader(GladGLContext* gl);
Shader(GladGLContext* gl)
: gl(gl)
{
ID = gl->CreateProgram();
}
bool addShaderFromSourceFile(ShaderType type, const char* path)
{
// 1. retrieve the vertex/fragment source code from filePath
std::string shaderCode;
std::ifstream shaderFile;
// ensure ifstream objects can throw exceptions:
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
shaderFile.open(path);
std::stringstream gShaderStream;
gShaderStream << shaderFile.rdbuf();
shaderFile.close();
shaderCode = gShaderStream.str();
}
catch (std::ifstream::failure& e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
return false;
}
unsigned int shader;
const char* gShaderCode = shaderCode.c_str();
shader = gl->CreateShader((GLenum)type);
gl->ShaderSource(shader, 1, &gShaderCode, NULL);
gl->CompileShader(shader);
if (!checkCompileErrors(shader))
return false;
// shader Program
gl->AttachShader(ID, shader);
// delete the shaders as they're linked into our program now and no longer necessery
gl->DeleteShader(shader);
return true;
}
bool link()
{
gl->LinkProgram(ID);
return checkCompileErrors(ID, true);
}
// activate the shader
// ------------------------------------------------------------------------
void use()
{
gl->UseProgram(ID);
}
void release()
{
gl->UseProgram(0);
}
bool addShaderFromSourceFile(ShaderType type, const char* path);
bool link();
void use();
void release();
// utility uniform functions
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, bool value) const
{
gl->Uniform1i(gl->GetUniformLocation(ID, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, int value) const
{
gl->Uniform1i(gl->GetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, float value) const
{
gl->Uniform1f(gl->GetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, const glm::vec2& value) const
{
gl->Uniform2fv(gl->GetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setUniformValue(const std::string& name, float x, float y) const
{
gl->Uniform2f(gl->GetUniformLocation(ID, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, const glm::vec3& value) const
{
gl->Uniform3fv(gl->GetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setUniformValue(const std::string& name, float x, float y, float z) const
{
gl->Uniform3f(gl->GetUniformLocation(ID, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, const glm::vec4& value) const
{
gl->Uniform4fv(gl->GetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setUniformValue(const std::string& name, float x, float y, float z, float w)
{
gl->Uniform4f(gl->GetUniformLocation(ID, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, const glm::mat2& mat) const
{
gl->UniformMatrix2fv(gl->GetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, const glm::mat3& mat) const
{
gl->UniformMatrix3fv(gl->GetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setUniformValue(const std::string& name, const glm::mat4& mat) const
{
gl->UniformMatrix4fv(gl->GetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setUniformValueArray(const std::string& name, const glm::vec3* value, int count) const
{
gl->Uniform3fv(gl->GetUniformLocation(ID, name.c_str()), count, &value->x);
}
// ------------------------------------------------------------------------
void setUniformValueArray(const std::string& name, const GLfloat* values, int count) const
{
gl->Uniform1fv(gl->GetUniformLocation(ID, name.c_str()), count, values);
}
void setUniformValue(const std::string& name, bool value) const;
void setUniformValue(const std::string& name, int value) const;
void setUniformValue(const std::string& name, float value) const;
void setUniformValue(const std::string& name, const glm::vec2& value) const;
void setUniformValue(const std::string& name, float x, float y) const;
void setUniformValue(const std::string& name, const glm::vec3& value) const;
void setUniformValue(const std::string& name, float x, float y, float z) const;
void setUniformValue(const std::string& name, const glm::vec4& value) const;
void setUniformValue(const std::string& name, float x, float y, float z, float w);
void setUniformValue(const std::string& name, const glm::mat2& mat) const;
void setUniformValue(const std::string& name, const glm::mat3& mat) const;
void setUniformValue(const std::string& name, const glm::mat4& mat) const;
void setUniformValueArray(const std::string& name, const glm::vec3* value, int count) const;
void setUniformValueArray(const std::string& name, const GLfloat* values, int count) const;
private:
GladGLContext* gl;
// utility function for checking shader compilation/linking errors.
// ------------------------------------------------------------------------
bool checkCompileErrors(GLuint shader, bool link = false)
{
GLint success;
GLchar infoLog[1024];
if (!link)
{
gl->GetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
gl->GetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR" << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
else
{
gl->GetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
gl->GetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR" << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
return success;
}
bool checkCompileErrors(GLuint shader);
bool checkLinkErrors(GLuint shader);
};
#endif

View File

@ -12,10 +12,10 @@ void World::rendererTick(float deltaTime)
actor->rendererTick(deltaTime);
}
void World::draw(Shader& shader)
void World::draw(const RenderPassContext& context, Shader& shader)
{
for (auto& actor : actors)
actor->draw(shader);
actor->draw(context, shader);
}
void World::addActor(std::shared_ptr<Actor> actor)

View File

@ -1,5 +1,6 @@
#pragma once
#include "Actor.h"
#include "RenderPassContext.h"
class World
{
@ -7,7 +8,7 @@ public:
std::vector<std::shared_ptr<Actor>> actors;
virtual void logicalTick(float deltaTime);
virtual void rendererTick(float deltaTime);
void draw(Shader& shader);
void draw(const RenderPassContext& context, Shader& shader);
void addActor(std::shared_ptr<Actor> actor);
std::pair<glm::vec3, glm::vec3> getAABB();
};