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

View file

@ -204,36 +204,7 @@ impl FilterPass {
gl::Disable(gl::BLEND);
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::BindBuffer(gl::ARRAY_BUFFER, 0);
gl::DisableVertexAttribArray(0);
gl::DisableVertexAttribArray(1);
gl::Disable(gl::FRAMEBUFFER_SRGB);
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
}

View file

@ -171,6 +171,7 @@ impl Framebuffer {
self.image,
0,
);
gl::ReadBuffer(gl::COLOR_ATTACHMENT0);
gl::DrawBuffer(gl::COLOR_ATTACHMENT1);
gl::BlitFramebuffer(
0,
@ -264,6 +265,7 @@ impl Framebuffer {
size.width as GLsizei,
size.height as GLsizei,
);
gl::FramebufferTexture2D(
gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0,
@ -287,7 +289,7 @@ impl Framebuffer {
);
gl::DeleteTextures(1, &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);
if self.levels > self.max_levels {

View file

@ -31,7 +31,7 @@ mod tests {
fn triangle_gl() {
let (glfw, window, events, shader, vao) = hello_triangle::setup();
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();
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]
static QUAD_VBO_DATA: &[f32; 16] = &[
@ -9,12 +9,15 @@ static QUAD_VBO_DATA: &[f32; 16] = &[
];
pub struct DrawQuad {
pub vbo: GLuint,
vbo: GLuint,
vao: GLuint,
}
impl DrawQuad {
pub fn new() -> DrawQuad {
let mut vbo = 0;
let mut vao = 0;
unsafe {
gl::GenBuffers(1, &mut vbo);
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
@ -25,8 +28,49 @@ impl DrawQuad {
gl::STATIC_DRAW,
);
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);
}
}
}