Now have anti-aliasing with framebuffers and can do post processing on it. Look at shaders/30-screen-bw.frag.glsl to see.
This commit is contained in:
parent
9ce217e0e2
commit
1830faf4c9
8 changed files with 67 additions and 161 deletions
|
|
@ -11,8 +11,8 @@
|
||||||
"geometry_path": ""
|
"geometry_path": ""
|
||||||
},
|
},
|
||||||
"screen_shader": {
|
"screen_shader": {
|
||||||
"vertex_path": "shaders/21-screen.vert.glsl",
|
"vertex_path": "shaders/30-screen.vert.glsl",
|
||||||
"frag_path": "shaders/21-screen.frag.glsl",
|
"frag_path": "shaders/30-screen.frag.glsl",
|
||||||
"geometry_path": ""
|
"geometry_path": ""
|
||||||
},
|
},
|
||||||
"skybox_shader": {
|
"skybox_shader": {
|
||||||
|
|
|
||||||
13
30-anti-aliasing/shaders/30-screen-bw.frag.glsl
Normal file
13
30-anti-aliasing/shaders/30-screen-bw.frag.glsl
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform sampler2D screenTexture;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 col = texture(screenTexture, TexCoords).rgb;
|
||||||
|
float grayscale = 0.2126 * col.r + 0.7152 * col.g + 0.0722 * col.b;
|
||||||
|
FragColor = vec4(vec3(grayscale), 1.0);
|
||||||
|
}
|
||||||
11
30-anti-aliasing/shaders/30-screen.frag.glsl
Normal file
11
30-anti-aliasing/shaders/30-screen.frag.glsl
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform sampler2D screenTexture;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = texture(screenTexture, TexCoords);
|
||||||
|
}
|
||||||
11
30-anti-aliasing/shaders/30-screen.vert.glsl
Normal file
11
30-anti-aliasing/shaders/30-screen.vert.glsl
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec2 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoords;
|
||||||
|
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
}
|
||||||
|
|
@ -3,15 +3,33 @@
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
void FrameBuffer::init() {
|
void FrameBuffer::init() {
|
||||||
// target_fb config
|
|
||||||
glGenFramebuffers(1, &target_fb);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target_fb);
|
|
||||||
|
|
||||||
// target_fb configuration
|
// target_fb configuration
|
||||||
// -------------------------
|
// -------------------------
|
||||||
glGenFramebuffers(1, &target_fb);
|
glGenFramebuffers(1, &target_fb);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target_fb);
|
glBindFramebuffer(GL_FRAMEBUFFER, target_fb);
|
||||||
|
|
||||||
|
// create the multisamples color attachment texture
|
||||||
|
glGenTextures(1, &texture_multi);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture_multi);
|
||||||
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture_multi, 0);
|
||||||
|
|
||||||
|
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
|
||||||
|
glGenRenderbuffers(1, &target_rbo);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, target_rbo);
|
||||||
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer.
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, target_rbo); // now actually attach it
|
||||||
|
// now that we actually created the target_fb and added all attachments we want to check if it is actually complete now
|
||||||
|
|
||||||
|
dbc::check(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame buffer not complete.");
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
// intermediate fbo here
|
||||||
|
glGenFramebuffers(1, &intermediate_fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, intermediate_fbo);
|
||||||
|
|
||||||
// create a color attachment texture
|
// create a color attachment texture
|
||||||
glGenTextures(1, &texture_buffer);
|
glGenTextures(1, &texture_buffer);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture_buffer);
|
glBindTexture(GL_TEXTURE_2D, texture_buffer);
|
||||||
|
|
@ -20,13 +38,6 @@ void FrameBuffer::init() {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_buffer, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_buffer, 0);
|
||||||
|
|
||||||
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
|
|
||||||
glGenRenderbuffers(1, &target_rbo);
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, target_rbo);
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer.
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, target_rbo); // now actually attach it
|
|
||||||
// now that we actually created the target_fb and added all attachments we want to check if it is actually complete now
|
|
||||||
|
|
||||||
dbc::check(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame buffer not complete.");
|
dbc::check(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame buffer not complete.");
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -42,18 +53,20 @@ void FrameBuffer::begin() {
|
||||||
|
|
||||||
void FrameBuffer::commit() {
|
void FrameBuffer::commit() {
|
||||||
// disable the frame buffer
|
// disable the frame buffer
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, target_fb);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_fbo);
|
||||||
|
glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::draw(Screen& screen) {
|
void FrameBuffer::draw(Screen& screen) {
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
// render the screen quad
|
|
||||||
screen.shader.use();
|
screen.shader.use();
|
||||||
glBindVertexArray(screen.target_VAO);
|
glBindVertexArray(screen.target_VAO);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture_buffer);
|
glBindTexture(GL_TEXTURE_2D, texture_buffer);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@
|
||||||
|
|
||||||
struct FrameBuffer {
|
struct FrameBuffer {
|
||||||
unsigned int target_fb = 0;
|
unsigned int target_fb = 0;
|
||||||
|
unsigned int intermediate_fbo = 0;
|
||||||
unsigned int target_rbo = 0;
|
unsigned int target_rbo = 0;
|
||||||
unsigned int texture_buffer = 0;
|
unsigned int texture_buffer = 0;
|
||||||
|
unsigned int texture_multi = 0;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void begin();
|
void begin();
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ Scene setup() {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
||||||
#include <glad/glad.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "shader.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// glfw: initialize and configure
|
|
||||||
// ------------------------------
|
|
||||||
glfwInit();
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// glfw window creation
|
|
||||||
// --------------------
|
|
||||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
|
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
std::cout << "Failed to create GLFW window" << std::endl;
|
|
||||||
glfwTerminate();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
|
|
||||||
// glad: load all OpenGL function pointers
|
|
||||||
// ---------------------------------------
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
|
||||||
{
|
|
||||||
std::cout << "Failed to initialize GLAD" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure global opengl state
|
|
||||||
// -----------------------------
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// build and compile shaders
|
|
||||||
// -------------------------
|
|
||||||
Shader shader({
|
|
||||||
.vertex_path="10.1.instancing.vs",
|
|
||||||
.frag_path="10.1.instancing.fs",
|
|
||||||
.geometry_path=""});
|
|
||||||
|
|
||||||
// generate a list of 100 quad locations/translation-vectors
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
glm::vec2 translations[100];
|
|
||||||
int index = 0;
|
|
||||||
float offset = 0.1f;
|
|
||||||
for (int y = -10; y < 10; y += 2)
|
|
||||||
{
|
|
||||||
for (int x = -10; x < 10; x += 2)
|
|
||||||
{
|
|
||||||
glm::vec2 translation;
|
|
||||||
translation.x = (float)x / 10.0f + offset;
|
|
||||||
translation.y = (float)y / 10.0f + offset;
|
|
||||||
translations[index++] = translation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// store instance data in an array buffer
|
|
||||||
// --------------------------------------
|
|
||||||
unsigned int instanceVBO;
|
|
||||||
glGenBuffers(1, &instanceVBO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 100, &translations[0], GL_STATIC_DRAW);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
// set up vertex data (and buffer(s)) and configure vertex attributes
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
float quadVertices[] = {
|
|
||||||
// positions // colors
|
|
||||||
-0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
|
|
||||||
0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
|
|
||||||
-0.05f, -0.05f, 0.0f, 0.0f, 1.0f,
|
|
||||||
|
|
||||||
-0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
|
|
||||||
0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.05f, 0.05f, 0.0f, 1.0f, 1.0f
|
|
||||||
};
|
|
||||||
unsigned int quadVAO, quadVBO;
|
|
||||||
glGenVertexArrays(1, &quadVAO);
|
|
||||||
glGenBuffers(1, &quadVBO);
|
|
||||||
glBindVertexArray(quadVAO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
|
|
||||||
// also set instance data
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); // this attribute comes from a different vertex buffer
|
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glVertexAttribDivisor(2, 1); // tell OpenGL this is an instanced vertex attribute.
|
|
||||||
|
|
||||||
|
|
||||||
// render loop
|
|
||||||
// -----------
|
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
|
||||||
// render
|
|
||||||
// ------
|
|
||||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
// draw 100 instanced quads
|
|
||||||
shader.use();
|
|
||||||
glBindVertexArray(quadVAO);
|
|
||||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100); // 100 triangles of 6 vertices each
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
|
||||||
// -------------------------------------------------------------------------------
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwPollEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional: de-allocate all resources once they've outlived their purpose:
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
glDeleteVertexArrays(1, &quadVAO);
|
|
||||||
glDeleteBuffers(1, &quadVBO);
|
|
||||||
|
|
||||||
glfwTerminate();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
|
||||||
{
|
|
||||||
// make sure the viewport matches the new window dimensions; note that width and
|
|
||||||
// height will be significantly larger than specified on retina displays.
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue