Framebuffer

This commit is contained in:
Piotr 2020-09-26 23:56:00 +02:00
parent a6ace9894a
commit 972b99a6a3
9 changed files with 197 additions and 31 deletions

View File

@ -0,0 +1,12 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
vec3 col = texture(screenTexture, TexCoords).rgb;
FragColor = vec4(col, 1.0);
}

View 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()
{
TexCoords = aTexCoords;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}

View File

@ -24,7 +24,7 @@ pub struct ExampleClient {
}
impl ExampleClient {
pub fn create() -> ExampleClient {
pub fn create(_window: &glfw::Window) -> ExampleClient {
let sky = unsafe { Sky::new() };
ExampleClient {
object_info_id: 0,

View File

@ -4,6 +4,7 @@ use crate::gaia::bg_info::BgInfo;
use crate::gaia::camera::*;
use crate::gaia::client::Client;
use crate::gaia::consts;
use crate::gaia::framebuffer::FramebufferSystem;
use cgmath::Point3;
use imgui_glfw_rs::glfw;
use imgui_glfw_rs::glfw::{Action, Context, Key};
@ -22,6 +23,7 @@ pub struct Engine {
pub client: Box<dyn Client>,
enable_debug_layer: bool,
assets_cache: AssetsCache,
framebuffer: FramebufferSystem,
}
impl Engine {
@ -54,10 +56,9 @@ impl Engine {
// render
// ------
unsafe {
gl::ClearColor(self.bg_info.r, self.bg_info.g, self.bg_info.b, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
self.framebuffer.clear();
self.client.draw();
self.framebuffer.draw();
}
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
@ -264,6 +265,10 @@ impl Default for Engine {
unsafe {
gl::Enable(gl::DEPTH_TEST);
}
let (scr_width, scr_height) = window.get_framebuffer_size();
let client = ExampleClient::create(&window);
let fb = unsafe { FramebufferSystem::generate(scr_width, scr_height) };
println!("{:?}", fb);
Engine {
bg_info: BgInfo::default(),
@ -273,12 +278,13 @@ impl Default for Engine {
glfw: glfw,
imgui: imgui,
imgui_glfw: imgui_glfw,
framebuffer: fb,
camera: Camera {
position: Point3::new(0.0, 0.0, 3.0),
..Camera::default()
},
enable_debug_layer: true,
client: Box::new(ExampleClient::create()),
client: Box::new(client),
assets_cache: AssetsCache::default(),
}
}

148
src/gaia/framebuffer.rs Normal file
View File

@ -0,0 +1,148 @@
use crate::gaia::shader::*;
use gl::types::*;
use std::mem;
use std::os::raw::c_void;
use std::ptr;
#[derive(Debug)]
pub struct FramebufferSystem {
pub shader: Shader,
pub framebuffer: u32,
pub texture_color_buffer: u32,
vao: u32,
vbo: u32,
}
impl Drop for FramebufferSystem {
fn drop(&mut self) {
unsafe {
gl::DeleteVertexArrays(1, &self.vao);
gl::DeleteBuffers(1, &self.vbo);
}
}
}
impl FramebufferSystem {
pub unsafe fn clear(&mut self) {
// bind to framebuffer and draw scene as we normally would to color texture
gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffer);
gl::Enable(gl::DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
// make sure we clear the framebuffer's content
gl::ClearColor(0.1, 0.1, 0.1, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
}
pub unsafe fn draw(&mut self) {
// now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
gl::Disable(gl::DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.
// clear all relevant buffers
gl::ClearColor(1.0, 0.0, 1.0, 1.0); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
gl::Clear(gl::COLOR_BUFFER_BIT);
self.shader.use_program();
gl::BindVertexArray(self.vao);
gl::BindTexture(gl::TEXTURE_2D, self.texture_color_buffer); // use the color attachment texture as the texture of the quad plane
gl::DrawArrays(gl::TRIANGLES, 0, 6);
}
pub unsafe fn generate(scr_width: i32, scr_height: i32) -> Self {
let screenShader = Shader::from_file(
"resources/shaders/framebuffers_screen.vs",
"resources/shaders/framebuffers_screen.fs",
);
let quadVertices: [f32; 24] = [
// vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// positions // texCoords
-1.0, 1.0, 0.0, 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0,
1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
];
// screen quad VAO
let (mut quad_vao, mut quad_vbo) = (0, 0);
gl::GenVertexArrays(1, &mut quad_vao);
gl::GenBuffers(1, &mut quad_vbo);
gl::BindVertexArray(quad_vao);
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vbo);
gl::BufferData(
gl::ARRAY_BUFFER,
(quadVertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
&quadVertices[0] as *const f32 as *const c_void,
gl::STATIC_DRAW,
);
gl::EnableVertexAttribArray(0);
let stride = 4 * mem::size_of::<GLfloat>() as GLsizei;
gl::VertexAttribPointer(0, 2, gl::FLOAT, gl::FALSE, stride, ptr::null());
gl::EnableVertexAttribArray(1);
gl::VertexAttribPointer(
1,
2,
gl::FLOAT,
gl::FALSE,
stride,
(2 * mem::size_of::<GLfloat>()) as *const c_void,
);
screenShader.use_program();
screenShader.setInt(c_str!("screenTexture"), 0);
// framebuffer configuration
// -------------------------
let mut framebuffer = 0;
gl::GenFramebuffers(1, &mut framebuffer);
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer);
// create a color attachment texture
let mut textureColorbuffer = 0;
gl::GenTextures(1, &mut textureColorbuffer);
gl::BindTexture(gl::TEXTURE_2D, textureColorbuffer);
gl::TexImage2D(
gl::TEXTURE_2D,
0,
gl::RGB as i32,
scr_width,
scr_height,
0,
gl::RGB,
gl::UNSIGNED_BYTE,
ptr::null(),
);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
gl::FramebufferTexture2D(
gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0,
gl::TEXTURE_2D,
textureColorbuffer,
0,
);
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
let mut rbo = 0;
gl::GenRenderbuffers(1, &mut rbo);
gl::BindRenderbuffer(gl::RENDERBUFFER, rbo);
gl::RenderbufferStorage(
gl::RENDERBUFFER,
gl::DEPTH24_STENCIL8,
scr_width,
scr_height,
); // use a single renderbuffer object for both a depth AND stencil buffer.
gl::FramebufferRenderbuffer(
gl::FRAMEBUFFER,
gl::DEPTH_STENCIL_ATTACHMENT,
gl::RENDERBUFFER,
rbo,
); // now actually attach it
// now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
if gl::CheckFramebufferStatus(gl::FRAMEBUFFER) != gl::FRAMEBUFFER_COMPLETE {
println!("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
}
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
FramebufferSystem {
texture_color_buffer: textureColorbuffer,
shader: screenShader,
vao: quad_vao,
vbo: quad_vbo,
framebuffer: framebuffer,
}
}
}

View File

@ -1,4 +1,4 @@
use cgmath::{vec3, Matrix4, Rad, Vector3};
use cgmath::Vector3;
use imgui_glfw_rs::imgui;
use imgui_inspect::InspectArgsDefault;
use imgui_inspect::InspectRenderDefault;
@ -22,27 +22,15 @@ impl InspectRenderDefault<Vector3<f32>> for CgmathVec3f32 {
_args: &InspectArgsDefault,
) -> bool {
use imgui::*;
let id_x = im_str!("x##{}", label);
let id_y = im_str!("y##{}", label);
let id_z = im_str!("z##{}", label);
let label_im = im_str!("##x,y,z{}", label);
ui.text(label);
let mut change = false;
for el in data.iter_mut() {
change |= ui
.input_float(&id_x, &mut el.x)
.step(0.01)
.step_fast(1.0)
.build();
change |= ui
.input_float(&id_y, &mut el.y)
.step(0.01)
.step_fast(1.0)
.build();
change |= ui
.input_float(&id_z, &mut el.z)
.step(0.01)
.step_fast(1.0)
.build();
let mut array: [f32; 3] = [el.x, el.y, el.z];
change |= ui.drag_float3(&label_im, &mut array).build();
el.x = array[0];
el.y = array[1];
el.z = array[2];
}
change
}

View File

@ -7,6 +7,7 @@ pub mod client;
pub mod components;
pub mod consts;
pub mod engine;
pub mod framebuffer;
pub mod imgui_helper;
pub mod light;
pub mod mesh;

View File

@ -12,6 +12,7 @@ use crate::gaia::consts;
use cgmath::prelude::*;
use cgmath::{Matrix, Matrix4, Vector3};
#[derive(Debug)]
pub struct Shader {
pub ID: u32,
}

View File

@ -1,4 +1,3 @@
use crate::gaia::camera::*;
use crate::gaia::shader::*;
use crate::gaia::utils::*;
use cgmath::Matrix4;
@ -56,12 +55,12 @@ impl Sky {
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
let faces = [
"resources/textures/skybox/right.jpg",
"resources/textures/skybox/left.jpg",
"resources/textures/skybox/top.jpg",
"resources/textures/skybox/bottom.jpg",
"resources/textures/skybox/back.jpg",
"resources/textures/skybox/front.jpg",
"resources/objects/skybox/right.jpg",
"resources/objects/skybox/left.jpg",
"resources/objects/skybox/top.jpg",
"resources/objects/skybox/bottom.jpg",
"resources/objects/skybox/back.jpg",
"resources/objects/skybox/front.jpg",
];
let cubemap_texture = load_cubemap(&faces);
shader.use_program();