Refactoring the render engine to feel a little better organized. One major issue remains with the model not rendering at the time. Possibly this is solved after fixing the outline render pass
This commit is contained in:
2023-02-03 16:33:02 +01:00
parent 4355a12b9a
commit 85263312cd
37 changed files with 405 additions and 8295 deletions

View File

@ -0,0 +1,42 @@
#include "FrameBuffer.h"
void FrameBuffer::Bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, id);
}
void FrameBuffer::Unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::Attach(const Texture& texture)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.id, 0);
}
void FrameBuffer::Attach(const RenderBuffer& renderbuffer)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer.id);
}
bool FrameBuffer::IsComplete()
{
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
}
FrameBuffer::FrameBuffer()
{
glGenFramebuffers(1, &id );
}
FrameBuffer::~FrameBuffer()
{
glDeleteFramebuffers(1, &id);
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "../Primitives/texture.h"
#include "RenderBuffer.h"
class FrameBuffer
{
public:
GLuint id;
void Bind();
void Unbind();
void Attach(const Texture& texture);
void Attach(const RenderBuffer& renderbuffer);
bool IsComplete();
FrameBuffer();
~FrameBuffer();
};

View File

@ -0,0 +1,65 @@
#include "OutlinePass.h"
#include "Renderer.h"
OutlinePass::OutlinePass(Model& sceneObject, glm::mat4& model, glm::mat4& projection, Camera& camera)
: RenderPass("Renderpass - Outline", "../Shaders/shader.vs", "../Shaders/outlineshader.fs" ) , m_model(sceneObject), camera(camera), projection(projection), model(model)
{
// Framebuffer outline effect
std::cout << "Create Framebuffer" << std::endl;
m_outlineFrameBuffer = FrameBuffer();
m_outlineFrameBuffer.Bind();
// Create a texture attachment (colour attachment)
std::cout << "Create Texture" << std::endl;
m_depthTexture = CreateTexture(800,600);
// attach texture to the frame buffer as a colour attachment
m_outlineFrameBuffer.Attach(*m_depthTexture);
// Add depth buffer attachment
std::cout << "Create RenderBuffer" << std::endl;
m_outlineRenderBuffer = RenderBuffer();
m_outlineRenderBuffer.Bind();
m_outlineRenderBuffer.UseDepthAndStencil();
m_outlineRenderBuffer.Unbind();
// attach depth buffer to our framebuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_outlineRenderBuffer.id);
m_outlineFrameBuffer.Unbind();
std::cout << "Success!" << std::endl;
}
OutlinePass::~OutlinePass(){
delete m_depthTexture;
}
void OutlinePass::Render()
{
std::cout << "Start outline render" << std::endl;
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
glDisable(GL_DEPTH_TEST);
m_shader.use();
m_shader.setMat4("model", model);
m_shader.setMat4("view", camera.GetViewMatrix());
m_shader.setMat4("projection", projection);
m_shader.setVec3("outlineColor", glm::vec3(0.28, 0.10, 0.26));
model = glm::scale(model, glm::vec3(1.05f,1.05f, 1.05f));
m_shader.setMat4("model", model);
std::cout << "Drawing model" << std::endl;
m_model.Draw(m_shader);
glStencilFunc(GL_ALWAYS, 1, 0xff);
glStencilMask(0xFF);
std::cout << "Finished outline render" << std::endl;
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <glm/glm.hpp>
#include "RenderPass.h"
#include "FrameBuffer.h"
#include "RenderBuffer.h"
#include "../model.h"
#include "../Primitives/texture.h"
#include "../Primitives/camera.h"
class OutlinePass : RenderPass {
public:
void Render() override;
OutlinePass (Model& sceneObject, glm::mat4& model , glm::mat4& projection, Camera& camera) ;
~OutlinePass();
private:
FrameBuffer m_outlineFrameBuffer;
RenderBuffer m_outlineRenderBuffer;
Texture* m_depthTexture;
glm::mat4 model;
glm::mat4 projection;
Model& m_model;
Camera& camera;
};

View File

@ -0,0 +1,25 @@
#include "RenderBuffer.h"
void RenderBuffer::UseDepthAndStencil (){
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600); /// NOTE: should be part of creating but kept seperate for now!
}
void RenderBuffer::Bind()
{
glBindRenderbuffer(GL_RENDERBUFFER, id);
}
void RenderBuffer::Unbind()
{
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
RenderBuffer::RenderBuffer()
{
glGenRenderbuffers(1, &id);
}
RenderBuffer::~RenderBuffer()
{
glDeleteRenderbuffers(GL_RENDERBUFFER, &id);
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <glad/glad.h>
#include <GLFW/glfw3.h>
class RenderBuffer
{
public:
GLuint id;
void Bind();
void Unbind();
void UseDepthAndStencil();
RenderBuffer();
~RenderBuffer();
};

19
src/Renderer/RenderPass.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <string>
#include "../Primitives/shader.h"
class RenderPass {
public :
virtual void Render() = 0;
RenderPass(const std::string& name,const std::string& VertexShaderFile, const std::string& FragmentShaderFile) : m_shader(VertexShaderFile.c_str(), FragmentShaderFile.c_str())
{
std::cout << "Created " << name << std::endl;
}
~RenderPass(){}
protected:
Shader m_shader;
};

133
src/Renderer/Renderer.cpp Normal file
View File

@ -0,0 +1,133 @@
#include "Renderer.h"
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <cmath>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
void Renderer::Setup()
{
framebuffer.Bind();
ColourBuffer = CreateTexture(800,600);
framebuffer.Attach(*ColourBuffer);
renderbufferObject.Bind();
renderbufferObject.UseDepthAndStencil();
renderbufferObject.Unbind();
framebuffer.Attach(renderbufferObject);
if(framebuffer.IsComplete() == false ){
std::cout << "ERROR::FRAMEBUFFER::Framebuffer is not complete! " << std::endl;
}
framebuffer.Unbind();
}
void Renderer::Render( )
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Recalculate the Camera's view matrix
view = camera.GetViewMatrix();
// Reset the model matrix to an identity matrix
model = glm::mat4(1.0f);
framebuffer.Bind();
// 1. Skybox pass
skyboxpass.Render();
// 2. Scene pass
scenepass.Render();
// 3. outline pass
outlinepass.Render();
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 4. draw result to screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_shader.use();
m_shader.setInt("screenTexture",0);
glBindVertexArray(ScreenVAO);
glBindTexture(GL_TEXTURE_2D, ColourBuffer->id);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Reset stencil
glStencilMask(0xFF);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glEnable(GL_DEPTH_TEST);
}
Renderer::Renderer(Camera& camera, Model& scene) :
camera(camera),
renderbufferObject(),
framebuffer(),
skybox(),
skyboxpass(skybox, camera, projection),
scenepass(skybox, scene,camera,projection, model),
outlinepass(scene, model, projection, camera),
m_shader("../Shaders/Framebuffers.vs", "../Shaders/Framebuffers.fs")
{
std::vector<std::string> faces = {
"../Textures/skybox/right.jpg",
"../Textures/skybox/left.jpg",
"../Textures/skybox/top.jpg",
"../Textures/skybox/bottom.jpg",
"../Textures/skybox/front.jpg",
"../Textures/skybox/back.jpg"
};
skybox.loadCubeTextures(faces);
// auto outlinepass = OutlinePass(scene , model, projection, camera);
// Create ScreenVAO
glGenVertexArrays(1, &ScreenVAO);
glBindVertexArray(ScreenVAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, ScreenVertices.size() * sizeof(float), &ScreenVertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2, GL_FLOAT,GL_FALSE, 4 * sizeof(float),(void*) 0 );
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,2,GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2*sizeof(float)));
glBindVertexArray(0);
// Enable features
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_MULTISAMPLE);
}
Renderer::~Renderer()
{
}

54
src/Renderer/Renderer.h Normal file
View File

@ -0,0 +1,54 @@
#pragma once
#include "../model.h"
#include "../Primitives/camera.h"
#include "../Primitives/shader.h"
#include "FrameBuffer.h"
#include "RenderBuffer.h"
#include "ScenePass.h"
#include "OutlinePass.h"
#include "SkyboxPass.h"
class Renderer
{
public:
void Render();
void Setup();
Renderer(Camera& camera,Model& scene);
~Renderer();
private:
ScenePass scenepass;
SkyboxPass skyboxpass;
OutlinePass outlinepass;
Camera& camera;
GLuint ScreenVAO, VBO;
FrameBuffer framebuffer;
RenderBuffer renderbufferObject;
Texture* ColourBuffer;
Skybox skybox;
Shader m_shader;
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view;
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)800 / (float)600, 0.1f, 100.0f);
glm::vec3 lightpos = glm::vec3(-0.2f, -1.0f, -0.3f);
std::vector<float> ScreenVertices = {
// vertex , uv
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f,-1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
};
};

View File

@ -0,0 +1,34 @@
#include "ScenePass.h"
void ScenePass::Render()
{
m_shader.use();
m_shader.setVec3("cameraPos", camera.Position);
glActiveTexture(GL_TEXTURE11);
m_skybox.Bind(); // Segmentation Fault HERE!!
glActiveTexture(GL_TEXTURE0);
m_shader.setInt("skybox",11);
m_shader.setMat4("model", model);
m_shader.setMat4("view", camera.GetViewMatrix());
m_shader.setMat4("projection", projection);
m_scene.Draw(m_shader);
m_skybox.Unbind();
}
void ScenePass::SetSkybox(Skybox& skybox)
{
m_skybox = skybox;
}

33
src/Renderer/ScenePass.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include "RenderPass.h"
#include "../Primitives/Skybox.h"
#include "../Primitives/shader.h"
#include "../Primitives/camera.h"
#include "../model.h"
class ScenePass : public RenderPass {
public:
void Render() override;
ScenePass(Skybox& skybox, Model& scene, Camera& camera, glm::mat4 projection , glm::mat4 model)
: RenderPass("RenderPass - Scene", "../Shaders/shader.vs", "../Shaders/shader.fs" ),
m_scene(scene), camera(camera), projection(projection), model(model), m_skybox(skybox)
{
}
~ScenePass() = default;
void SetSkybox(Skybox& skybox);
private:
Skybox& m_skybox;
Model& m_scene;
Camera& camera;
glm::mat4 projection;
glm::mat4 model;
};

View File

@ -0,0 +1,28 @@
#include "SkyboxPass.h"
SkyboxPass::SkyboxPass(Skybox& skybox, Camera& camera, glm::mat4& projection) : RenderPass("Render Pass - Skybox", "../Shaders/skybox.vs", "../Shaders/Cubemap.fs"),
skybox(skybox),
camera(camera),
projection(projection)
{
}
void SkyboxPass::Render()
{
glDepthMask(GL_FALSE);
m_shader.use();
m_shader.setMat4("projection", projection);
glm::mat4 centeredView = glm::mat4(glm::mat3(camera.GetViewMatrix()));
m_shader.setMat4("view", centeredView);
skybox.Bind();
glDrawArrays(GL_TRIANGLES, 0, 36);
skybox.Unbind();
glDepthMask(GL_TRUE);
}

20
src/Renderer/SkyboxPass.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include "RenderPass.h"
#include "../Primitives/Skybox.h"
#include "../Primitives/shader.h"
#include "../Primitives/camera.h"
class SkyboxPass : public RenderPass {
public:
void Render() override;
SkyboxPass( Skybox& skybox, Camera& camera, glm::mat4& projection);
~SkyboxPass() = default;
private:
Skybox& skybox;
Camera& camera;
glm::mat4& projection;
};