gl: move quad drawing into filterchain

This commit is contained in:
chyyran 2022-11-28 18:34:37 -05:00
parent 9265113e9a
commit 7b2721aa19
5 changed files with 67 additions and 53 deletions

View file

@ -29,7 +29,7 @@ use crate::texture::Texture;
pub struct FilterChain { pub struct FilterChain {
passes: Box<[FilterPass]>, passes: Box<[FilterPass]>,
common: FilterCommon, common: FilterCommon,
filter_vao: GLuint, pub(crate) draw_quad: DrawQuad,
output_framebuffers: Box<[Framebuffer]>, output_framebuffers: Box<[Framebuffer]>,
feedback_framebuffers: Box<[Framebuffer]>, feedback_framebuffers: Box<[Framebuffer]>,
history_framebuffers: VecDeque<Framebuffer>, history_framebuffers: VecDeque<Framebuffer>,
@ -43,7 +43,6 @@ pub struct FilterCommon {
pub output_textures: Box<[Texture]>, pub output_textures: Box<[Texture]>,
pub feedback_textures: Box<[Texture]>, pub feedback_textures: Box<[Texture]>,
pub history_textures: Box<[Texture]>, pub history_textures: Box<[Texture]>,
pub(crate) draw_quad: DrawQuad,
} }
pub struct FilterMutable { pub struct FilterMutable {
@ -174,20 +173,15 @@ impl FilterChain {
let (history_framebuffers, history_textures) = let (history_framebuffers, history_textures) =
FilterChain::init_history(&filters, default_filter, default_wrap); FilterChain::init_history(&filters, default_filter, default_wrap);
// create VBO objects // create vertex objects
let draw_quad = DrawQuad::new(); let draw_quad = DrawQuad::new();
let mut filter_vao = 0;
unsafe {
gl::GenVertexArrays(1, &mut filter_vao);
}
Ok(FilterChain { Ok(FilterChain {
passes: filters, passes: filters,
output_framebuffers: output_framebuffers.into_boxed_slice(), output_framebuffers: output_framebuffers.into_boxed_slice(),
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(), feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
history_framebuffers, history_framebuffers,
filter_vao, draw_quad,
common: FilterCommon { common: FilterCommon {
config: FilterMutable { config: FilterMutable {
passes_enabled: preset.shader_count as usize, passes_enabled: preset.shader_count as usize,
@ -199,7 +193,6 @@ impl FilterChain {
output_textures: output_textures.into_boxed_slice(), output_textures: output_textures.into_boxed_slice(),
feedback_textures: feedback_textures.into_boxed_slice(), feedback_textures: feedback_textures.into_boxed_slice(),
history_textures, history_textures,
draw_quad,
}, },
}) })
} }
@ -279,6 +272,11 @@ impl FilterChain {
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> { fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> {
let mut luts = FxHashMap::default(); let mut luts = FxHashMap::default();
let pixel_unpack = unsafe {
let mut binding = 0;
gl::GetIntegerv(gl::PIXEL_UNPACK_BUFFER_BINDING, &mut binding);
binding
};
for (index, texture) in textures.iter().enumerate() { for (index, texture) in textures.iter().enumerate() {
let image = Image::load(&texture.path)?; let image = Image::load(&texture.path)?;
@ -338,6 +336,10 @@ impl FilterChain {
}, },
); );
} }
unsafe {
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, pixel_unpack as GLuint);
};
Ok(luts) Ok(luts)
} }
@ -593,11 +595,9 @@ impl FilterChain {
return Ok(()); return Ok(());
} }
unsafe {
// do not need to rebind FBO 0 here since first `draw` will // do not need to rebind FBO 0 here since first `draw` will
// bind automatically. // bind automatically.
gl::BindVertexArray(self.filter_vao); self.draw_quad.bind_vao();
}
let filter = passes[0].config.filter; let filter = passes[0].config.filter;
let wrap_mode = passes[0].config.wrap_mode; let wrap_mode = passes[0].config.wrap_mode;
@ -710,10 +710,7 @@ impl FilterChain {
self.push_history(input)?; self.push_history(input)?;
// pass.draw should return framebuffer bound to 0. self.draw_quad.unbind_vao();
unsafe {
gl::BindVertexArray(0);
}
Ok(()) Ok(())
} }

View file

@ -204,36 +204,7 @@ impl FilterPass {
gl::Disable(gl::BLEND); gl::Disable(gl::BLEND);
gl::Disable(gl::DEPTH_TEST); gl::Disable(gl::DEPTH_TEST);
gl::EnableVertexAttribArray(0);
gl::EnableVertexAttribArray(1);
gl::BindBuffer(gl::ARRAY_BUFFER, parent.draw_quad.vbo);
// the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo,
// and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers.
// that are inexpressible in Rust
gl::VertexAttribPointer(
0,
2,
gl::FLOAT,
gl::FALSE,
(4 * std::mem::size_of::<f32>()) as GLsizei,
std::ptr::invalid(0),
);
gl::VertexAttribPointer(
1,
2,
gl::FLOAT,
gl::FALSE,
(4 * std::mem::size_of::<f32>()) as GLsizei,
std::ptr::invalid(2 * std::mem::size_of::<f32>()),
);
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4); gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
gl::DisableVertexAttribArray(0);
gl::DisableVertexAttribArray(1);
gl::Disable(gl::FRAMEBUFFER_SRGB); gl::Disable(gl::FRAMEBUFFER_SRGB);
gl::BindFramebuffer(gl::FRAMEBUFFER, 0); gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
} }

View file

@ -171,6 +171,7 @@ impl Framebuffer {
self.image, self.image,
0, 0,
); );
gl::ReadBuffer(gl::COLOR_ATTACHMENT0);
gl::DrawBuffer(gl::COLOR_ATTACHMENT1); gl::DrawBuffer(gl::COLOR_ATTACHMENT1);
gl::BlitFramebuffer( gl::BlitFramebuffer(
0, 0,
@ -264,6 +265,7 @@ impl Framebuffer {
size.width as GLsizei, size.width as GLsizei,
size.height as GLsizei, size.height as GLsizei,
); );
gl::FramebufferTexture2D( gl::FramebufferTexture2D(
gl::FRAMEBUFFER, gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0, gl::COLOR_ATTACHMENT0,
@ -287,7 +289,7 @@ impl Framebuffer {
); );
gl::DeleteTextures(1, &self.image); gl::DeleteTextures(1, &self.image);
gl::GenTextures(1, &mut self.image); gl::GenTextures(1, &mut self.image);
gl::BindTexture(1, self.image); gl::BindTexture(gl::TEXTURE_2D, self.image);
self.levels = util::calc_miplevel(size); self.levels = util::calc_miplevel(size);
if self.levels > self.max_levels { if self.levels > self.max_levels {

View file

@ -31,7 +31,7 @@ mod tests {
fn triangle_gl() { fn triangle_gl() {
let (glfw, window, events, shader, vao) = hello_triangle::setup(); let (glfw, window, events, shader, vao) = hello_triangle::setup();
let mut filter = let mut filter =
FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp", None) FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp", None)
.unwrap(); .unwrap();
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter); hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
} }

View file

@ -1,4 +1,4 @@
use gl::types::{GLsizeiptr, GLuint}; use gl::types::{GLsizei, GLsizeiptr, GLuint};
#[rustfmt::skip] #[rustfmt::skip]
static QUAD_VBO_DATA: &[f32; 16] = &[ static QUAD_VBO_DATA: &[f32; 16] = &[
@ -9,12 +9,15 @@ static QUAD_VBO_DATA: &[f32; 16] = &[
]; ];
pub struct DrawQuad { pub struct DrawQuad {
pub vbo: GLuint, vbo: GLuint,
vao: GLuint,
} }
impl DrawQuad { impl DrawQuad {
pub fn new() -> DrawQuad { pub fn new() -> DrawQuad {
let mut vbo = 0; let mut vbo = 0;
let mut vao = 0;
unsafe { unsafe {
gl::GenBuffers(1, &mut vbo); gl::GenBuffers(1, &mut vbo);
gl::BindBuffer(gl::ARRAY_BUFFER, vbo); gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
@ -25,8 +28,49 @@ impl DrawQuad {
gl::STATIC_DRAW, gl::STATIC_DRAW,
); );
gl::BindBuffer(gl::ARRAY_BUFFER, 0); gl::BindBuffer(gl::ARRAY_BUFFER, 0);
gl::GenVertexArrays(1, &mut vao);
} }
DrawQuad { vbo }
DrawQuad { vbo, vao }
}
pub fn bind_vao(&self) {
unsafe {
gl::BindVertexArray(self.vao);
gl::EnableVertexAttribArray(0);
gl::EnableVertexAttribArray(1);
gl::BindBuffer(gl::ARRAY_BUFFER, self.vbo);
// the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo,
// and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers.
// that are inexpressible in Rust
gl::VertexAttribPointer(
0,
2,
gl::FLOAT,
gl::FALSE,
(4 * std::mem::size_of::<f32>()) as GLsizei,
std::ptr::invalid(0),
);
gl::VertexAttribPointer(
1,
2,
gl::FLOAT,
gl::FALSE,
(4 * std::mem::size_of::<f32>()) as GLsizei,
std::ptr::invalid(2 * std::mem::size_of::<f32>()),
);
}
}
pub fn unbind_vao(&self) {
unsafe {
gl::BindVertexArray(0);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
gl::DisableVertexAttribArray(0);
gl::DisableVertexAttribArray(1);
}
} }
} }