gl: move quad drawing into filterchain
This commit is contained in:
parent
9265113e9a
commit
7b2721aa19
|
@ -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.
|
self.draw_quad.bind_vao();
|
||||||
gl::BindVertexArray(self.filter_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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue