Architecture redesign

PART 1:
- Added a Renderer class
- Added a Application interface
- Added a RenderPass interface
- Added multiple RenderPass classes
- Added a Window class
- Moved Shaders into a Shader folder

The idea behind this redesign is to make more abstractions.
These abstraction are then supposedly going to make it easier
to focus on the next couple tutorials main elements
This commit is contained in:
2022-10-18 22:57:50 +02:00
parent 71c942d88e
commit 4355a12b9a
34 changed files with 656 additions and 386 deletions

View File

@ -1,399 +1,87 @@
#include <stdio.h>
#include <cmath>
#include <vector>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <vector>
#include <string>
#include "Window.h"
#include "Renderer.h"
#include "Skybox.h"
#include "shader.h"
#include "camera.h"
#include "model.h"
#include "FrameBuffer.hpp"
#include "RenderBuffer.hpp"
#include "Cubemap.h"
#include "Application.h"
// https://learnopengl.com/Advanced-OpenGL/Framebuffers
class LearnOpenGL : Application
{
public:
void Run () override{
// Create a window
Window window(800,600, "LearnOpenGL");
float deltaTime = 0.0f; // Time between current frame and last frame
float lastFrame = 0.0f; // Time of last frame
Camera camera(glm::vec3(0.0f,0.0f,8.0f));
Renderer renderer = Renderer(camera);
renderer.Setup();
stbi_set_flip_vertically_on_load(true);
Camera camera(glm::vec3(0.0f, 0.0f, 8.0f));
float lastX = 400, lastY = 300;
bool firstMouse = true;
// Load scene resources
Shader shader ("Shaders/shader.vs", "Shaders/shader.fs");
Shader outlineShader("Shaders/shader.vs","Shaders/outlineshader.fs");
Shader skyboxShader("Shaders/skybox.vs", "Shaders/Cubemap.fs");
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(-0.2f, -1.0f, -0.3f);
Model backpack("Models/backpack.obj");
int bullshit = 0;
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"
};
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,
Skybox skybox= Skybox ();
skybox.Bind();
skybox.loadCubeTextures(faces);
skybox.BuildVAO();
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
} ;
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while(!window.shouldClose())
{
//window.GetInput();
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"
renderer.Render();
window.SwapBuffers();
glfwPollEvents();
}
}
};
std::vector<float> skyboxVertices = {
// positions
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0,0, width, height);
}
/*
void processInput( GLFWwindow* window){
if(glfwGetKey(window,GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
const float CameraSpeed = 2.5f * deltaTime;
const float CameraSpeed = 2.5f * Renderer::deltaTime;
if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
Renderer::camera.ProcessKeyboard(FORWARD, Renderer::deltaTime);
if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
Renderer::camera.ProcessKeyboard(BACKWARD, Renderer::deltaTime);
if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
Renderer::camera.ProcessKeyboard(LEFT, Renderer::deltaTime);
if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT,deltaTime);
Renderer::camera.ProcessKeyboard(RIGHT,Renderer::deltaTime);
}
void mouse_callback(GLFWwindow* window, double xpos, double ypos){
if (firstMouse) // initially set to true
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
float xoffset = xpos - lastX;
float yoffset = lastY - ypos; // reversed since y-coordinates range from bottom to top
lastX = xpos;
lastY = ypos;
*/
camera.ProcessMouseMovement(xoffset,yoffset);
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
int main()
{
camera.ProcessMouseScroll(yoffset);
}
GLFWwindow* CreateWindowWithOpenGLContext()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// multisampling
glfwWindowHint(GLFW_SAMPLES, 4);
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if( window == NULL){
printf("Failed to create GLFW window!\n");
glfwTerminate();
return nullptr;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
printf("Failed to initialize GLAD!\n");
return nullptr;
}
glViewport(0,0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
return window;
}
void Skybox_pass (GLuint& SkyboxVAO, Shader& skyboxShader, Cubemap& skycubemap)
{
glDepthMask(GL_FALSE);
skyboxShader.use();
skyboxShader.setMat4("projection", projection);
glm::mat4 centeredView = glm::mat4(glm::mat3(camera.GetViewMatrix()));
skyboxShader.setMat4("view", centeredView);
glBindVertexArray(SkyboxVAO);
skycubemap.Bind();
glDrawArrays(GL_TRIANGLES, 0, 36);
glDepthMask(GL_TRUE);
}
void drawScene_pass(Shader& shader, Model& Object, Cubemap& skybox)
{
shader.use();
shader.setVec3("cameraPos", camera.Position);
glActiveTexture(GL_TEXTURE11);
skybox.Bind();
glActiveTexture(GL_TEXTURE0);
shader.setMat4("model", model);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
shader.setInt("skybox",11);
Object.Draw(shader);
}
void outline_pass( Shader& shader, Model& Object)
{
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
glDisable(GL_DEPTH_TEST);
shader.use();
shader.setMat4("model", model);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
shader.setVec3("outlineColor", glm::vec3(0.28, 0.10, 0.26));
model = glm::scale(model, glm::vec3(1.05f,1.05f, 1.05f));
shader.setMat4("model", model);
Object.Draw(shader);
glStencilFunc(GL_ALWAYS, 1, 0xff);
glStencilMask(0xFF);
}
void DrawToScreen( GLuint& VAO, GLuint& ScreenTexture, Shader& shader)
{
// draw to screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
shader.use();
shader.setInt("screenTexture",0);
glBindVertexArray(VAO);
glBindTexture(GL_TEXTURE_2D, ScreenTexture);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
int main() {
printf("Hello OpenGL!\n");
// Setup OpenGL Context
GLFWwindow* window = CreateWindowWithOpenGLContext();
if(window == nullptr)
return -1;
glEnable(GL_DEPTH_TEST);
stbi_set_flip_vertically_on_load(true);
// Load scene resources
Shader shader ("shader.vs", "shader.fs");
Shader outlineShader("shader.vs","outlineshader.fs");
Shader framebufferShader("Framebuffers.vs", "Framebuffers.fs" );
Shader skyboxShader("skybox.vs", "Cubemap.fs");
Model backpack("Models/backpack.obj");
// Framebuffer outline effect
FrameBuffer outlineFrameBuffer = FrameBuffer();
outlineFrameBuffer.Bind();
// Create a texture attachment (colour attachment)
Texture* depthTexture = CreateTexture(800,600);
// attach texture to the frame buffer as a colour attachment
outlineFrameBuffer.Attach(*depthTexture);
// Add depth buffer attachment
RenderBuffer outlineRenderBuffer = RenderBuffer();
outlineRenderBuffer.Bind();
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
outlineRenderBuffer.Unbind();
// attach depth buffer to our framebuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, outlineRenderBuffer.id);
outlineFrameBuffer.Unbind();
// Post processing
FrameBuffer framebuffer = FrameBuffer();
framebuffer.Bind();
Texture* ColourBuffer = CreateTexture(800,600);
framebuffer.Attach(*ColourBuffer);
RenderBuffer renderbufferObject = RenderBuffer();
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();
Cubemap skybox= Cubemap ();
skybox.Bind();
skybox.loadCubeTextures(faces);
// Create ScreenVAO
GLuint ScreenVAO, VBO;
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);
// Create SkyboxVAO
GLuint SkyboxVAO, SkyboxVBO;
glGenVertexArrays(1, &SkyboxVAO);
glBindVertexArray(SkyboxVAO);
glGenBuffers(1, &SkyboxVBO);
glBindBuffer(GL_ARRAY_BUFFER, SkyboxVBO);
glBufferData(GL_ARRAY_BUFFER, skyboxVertices.size() * sizeof(float), &skyboxVertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE, 3 * sizeof(float),(void*) 0);
glBindVertexArray(0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_MULTISAMPLE);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while(!glfwWindowShouldClose(window))
{
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
processInput(window);
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();
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Skybox_pass(SkyboxVAO, skyboxShader, skybox);
drawScene_pass(shader, backpack, skybox);
outline_pass(outlineShader, backpack);
DrawToScreen(ScreenVAO, ColourBuffer->id, framebufferShader);
// Reset stencil
glStencilMask(0xFF);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glEnable(GL_DEPTH_TEST);
glfwSwapBuffers(window);
glfwPollEvents();
LearnOpenGL().Run();
return 0;
}
delete ColourBuffer;
delete depthTexture;
glfwTerminate();
return 0;
}