From 4f2d5050e6c40beb788adf2b2e25afc437141e9b Mon Sep 17 00:00:00 2001 From: Dmitry Stepanov Date: Tue, 8 Oct 2024 23:38:57 +0300 Subject: [PATCH] isolated opengl-specific code of geometrybuffer --- editor/src/highlight.rs | 6 +- editor/src/overlay.rs | 6 +- fyrox-graphics/src/framebuffer.rs | 4 +- fyrox-graphics/src/geometry_buffer.rs | 152 ++------------- fyrox-graphics/src/gl/framebuffer.rs | 13 +- fyrox-graphics/src/gl/geometry_buffer.rs | 182 ++++++++++++++++++ fyrox-graphics/src/gl/mod.rs | 1 + fyrox-graphics/src/gl/server.rs | 9 + fyrox-graphics/src/server.rs | 5 + fyrox-impl/src/renderer/bloom/blur.rs | 2 +- fyrox-impl/src/renderer/bloom/mod.rs | 2 +- fyrox-impl/src/renderer/cache/geometry.rs | 9 +- fyrox-impl/src/renderer/debug_renderer.rs | 8 +- fyrox-impl/src/renderer/framework/mod.rs | 11 +- fyrox-impl/src/renderer/fxaa.rs | 6 +- fyrox-impl/src/renderer/gbuffer/mod.rs | 8 +- fyrox-impl/src/renderer/hdr/mod.rs | 10 +- fyrox-impl/src/renderer/light/mod.rs | 34 ++-- fyrox-impl/src/renderer/light_volume.rs | 14 +- fyrox-impl/src/renderer/mod.rs | 16 +- fyrox-impl/src/renderer/occlusion/mod.rs | 8 +- .../src/renderer/occlusion/optimizer.rs | 2 +- fyrox-impl/src/renderer/ssao/blur.rs | 6 +- fyrox-impl/src/renderer/ssao/mod.rs | 6 +- fyrox-impl/src/renderer/ui_renderer.rs | 17 +- 25 files changed, 310 insertions(+), 227 deletions(-) create mode 100644 fyrox-graphics/src/gl/geometry_buffer.rs diff --git a/editor/src/highlight.rs b/editor/src/highlight.rs index 43b4254df..49a849740 100644 --- a/editor/src/highlight.rs +++ b/editor/src/highlight.rs @@ -130,7 +130,7 @@ void main() pub struct HighlightRenderPass { framebuffer: Box, - quad: GeometryBuffer, + quad: Box, edge_detect_shader: EdgeDetectShader, pub scene_handle: Handle, pub nodes_to_highlight: FxHashSet>, @@ -193,7 +193,7 @@ impl HighlightRenderPass { pub fn new_raw(server: &GlGraphicsServer, width: usize, height: usize) -> Self { Self { framebuffer: Self::create_frame_buffer(server, width, height), - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_unit_xy_quad(), BufferUsage::StaticDraw, server, @@ -315,7 +315,7 @@ impl SceneRenderPass for HighlightRenderPass { let shader = &self.edge_detect_shader; let frame_texture = self.framebuffer.color_attachments()[0].texture.clone(); ctx.framebuffer.draw( - &self.quad, + &*self.quad, ctx.viewport, &*shader.program, &DrawParameters { diff --git a/editor/src/overlay.rs b/editor/src/overlay.rs index 005b3b434..47d3768a3 100644 --- a/editor/src/overlay.rs +++ b/editor/src/overlay.rs @@ -67,7 +67,7 @@ impl OverlayShader { } pub struct OverlayRenderPass { - quad: GeometryBuffer, + quad: Box, shader: OverlayShader, sound_icon: TextureResource, light_icon: TextureResource, @@ -77,7 +77,7 @@ pub struct OverlayRenderPass { impl OverlayRenderPass { pub fn new(server: &GlGraphicsServer) -> Rc> { Rc::new(RefCell::new(Self { - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_collapsed_xy_quad(), BufferUsage::StaticDraw, server, @@ -136,7 +136,7 @@ impl SceneRenderPass for OverlayRenderPass { let world_matrix = Matrix4::new_translation(&position); ctx.framebuffer.draw( - &self.quad, + &*self.quad, ctx.viewport, &*shader.program, &DrawParameters { diff --git a/fyrox-graphics/src/framebuffer.rs b/fyrox-graphics/src/framebuffer.rs index 59581f0e3..08309c354 100644 --- a/fyrox-graphics/src/framebuffer.rs +++ b/fyrox-graphics/src/framebuffer.rs @@ -95,7 +95,7 @@ pub trait FrameBuffer: Any { ); fn draw( &mut self, - geometry: &GeometryBuffer, + geometry: &dyn GeometryBuffer, viewport: Rect, program: &dyn GpuProgram, params: &DrawParameters, @@ -105,7 +105,7 @@ pub trait FrameBuffer: Any { fn draw_instances( &mut self, count: usize, - geometry: &GeometryBuffer, + geometry: &dyn GeometryBuffer, viewport: Rect, program: &dyn GpuProgram, params: &DrawParameters, diff --git a/fyrox-graphics/src/geometry_buffer.rs b/fyrox-graphics/src/geometry_buffer.rs index 2b3fa0732..8a03eb01b 100644 --- a/fyrox-graphics/src/geometry_buffer.rs +++ b/fyrox-graphics/src/geometry_buffer.rs @@ -19,26 +19,13 @@ // SOFTWARE. use crate::{ - buffer::{Buffer, BufferKind, BufferUsage}, + buffer::BufferUsage, core::{array_as_u8_slice, math::TriangleDefinition}, - error::FrameworkError, - gl::{buffer::GlBuffer, server::GlGraphicsServer, ToGlConstant}, ElementKind, }; use bytemuck::Pod; -use glow::HasContext; -use std::{cell::Cell, marker::PhantomData, mem::size_of, rc::Weak}; - -pub struct GeometryBuffer { - pub state: Weak, - pub vertex_array_object: glow::VertexArray, - pub buffers: Vec, - pub element_buffer: GlBuffer, - pub element_count: Cell, - pub element_kind: ElementKind, - // Force compiler to not implement Send and Sync, because OpenGL is not thread-safe. - thread_mark: PhantomData<*const u8>, -} +use std::any::Any; +use std::mem::size_of; #[derive(Copy, Clone)] #[allow(dead_code)] @@ -66,15 +53,6 @@ impl AttributeKind { AttributeKind::UnsignedInt => size_of::(), } } - - fn gl_type(self) -> u32 { - match self { - AttributeKind::Float => glow::FLOAT, - AttributeKind::UnsignedByte => glow::UNSIGNED_BYTE, - AttributeKind::UnsignedShort => glow::UNSIGNED_SHORT, - AttributeKind::UnsignedInt => glow::UNSIGNED_INT, - } - } } #[derive(Debug, Copy, Clone, Default)] @@ -107,121 +85,17 @@ pub struct GeometryBufferDescriptor<'a> { pub buffers: &'a [VertexBufferDescriptor<'a>], } -impl GeometryBuffer { - pub fn new( - server: &GlGraphicsServer, - desc: GeometryBufferDescriptor, - ) -> Result { - let vao = unsafe { server.gl.create_vertex_array()? }; - - server.set_vertex_array_object(Some(vao)); - - let element_buffer = GlBuffer::new(server, 0, BufferKind::Index, BufferUsage::StaticDraw)?; - - let mut buffers = Vec::new(); - for buffer in desc.buffers { - unsafe { - let data_size = buffer.data.bytes.map(|bytes| bytes.len()).unwrap_or(0); - - let native_buffer = - GlBuffer::new(server, data_size, BufferKind::Vertex, buffer.usage)?; - - if let Some(data) = buffer.data.bytes { - native_buffer.write_data(data)?; - } - - let target = native_buffer.kind.into_gl(); - server.gl.bind_buffer(target, Some(native_buffer.id)); - - let mut offset = 0usize; - for definition in buffer.attributes { - server.gl.vertex_attrib_pointer_f32( - definition.location, - definition.component_count as i32, - definition.kind.gl_type(), - definition.normalized, - buffer.data.element_size as i32, - offset as i32, - ); - server - .gl - .vertex_attrib_divisor(definition.location, definition.divisor); - server.gl.enable_vertex_attrib_array(definition.location); - - offset += definition.kind.size() * definition.component_count; - - if offset > buffer.data.element_size { - return Err(FrameworkError::InvalidAttributeDescriptor); - } - } - - buffers.push(native_buffer); - } - } - - server.set_vertex_array_object(None); - - Ok(GeometryBuffer { - state: server.weak(), - vertex_array_object: vao, - buffers, - element_buffer, - element_count: Cell::new(0), - element_kind: desc.element_kind, - thread_mark: PhantomData, - }) - } - - pub fn set_buffer_data(&mut self, buffer: usize, data: &[T]) { - self.state - .upgrade() - .unwrap() - .set_vertex_array_object(Some(self.vertex_array_object)); - self.buffers[buffer] - .write_data(array_as_u8_slice(data)) - .unwrap(); - } - - pub fn element_count(&self) -> usize { - self.element_count.get() - } - - pub fn set_triangles(&self, triangles: &[TriangleDefinition]) { - assert_eq!(self.element_kind, ElementKind::Triangle); - self.element_count.set(triangles.len()); - self.set_elements(array_as_u8_slice(triangles)); - } - - pub fn set_lines(&self, lines: &[[u32; 2]]) { - assert_eq!(self.element_kind, ElementKind::Line); - self.element_count.set(lines.len()); - self.set_elements(array_as_u8_slice(lines)); - } - - fn set_elements(&self, data: &[u8]) { - self.state - .upgrade() - .unwrap() - .set_vertex_array_object(Some(self.vertex_array_object)); - self.element_buffer.write_data(data).unwrap() - } - - pub fn mode(&self) -> u32 { - match self.element_kind { - ElementKind::Triangle => glow::TRIANGLES, - ElementKind::Line => glow::LINES, - ElementKind::Point => glow::POINTS, - } - } +pub trait GeometryBuffer { + fn as_any(&self) -> &dyn Any; + fn as_any_mut(&mut self) -> &mut dyn Any; + fn set_buffer_data(&self, buffer: usize, data: &[u8]); + fn element_count(&self) -> usize; + fn set_triangles(&self, triangles: &[TriangleDefinition]); + fn set_lines(&self, lines: &[[u32; 2]]); } -impl Drop for GeometryBuffer { - fn drop(&mut self) { - if let Some(state) = self.state.upgrade() { - unsafe { - self.buffers.clear(); - state.gl.delete_vertex_array(self.vertex_array_object); - } - } +impl dyn GeometryBuffer { + pub fn set_buffer_data_of_type(&mut self, buffer: usize, data: &[T]) { + self.set_buffer_data(buffer, array_as_u8_slice(data)) } } diff --git a/fyrox-graphics/src/gl/framebuffer.rs b/fyrox-graphics/src/gl/framebuffer.rs index badbc957d..7733345bf 100644 --- a/fyrox-graphics/src/gl/framebuffer.rs +++ b/fyrox-graphics/src/gl/framebuffer.rs @@ -19,6 +19,7 @@ // SOFTWARE. use crate::framebuffer::BufferDataUsage; +use crate::gl::geometry_buffer::GlGeometryBuffer; use crate::{ buffer::{Buffer, BufferKind}, core::{color::Color, math::Rect}, @@ -307,7 +308,7 @@ impl FrameBuffer for GlFrameBuffer { fn draw( &mut self, - geometry: &GeometryBuffer, + geometry: &dyn GeometryBuffer, viewport: Rect, program: &dyn GpuProgram, params: &DrawParameters, @@ -315,6 +316,10 @@ impl FrameBuffer for GlFrameBuffer { element_range: ElementRange, ) -> Result { let server = self.state.upgrade().unwrap(); + let geometry = geometry + .as_any() + .downcast_ref::() + .unwrap(); pre_draw(self.id(), &server, viewport, program, params, resources); @@ -357,13 +362,17 @@ impl FrameBuffer for GlFrameBuffer { fn draw_instances( &mut self, count: usize, - geometry: &GeometryBuffer, + geometry: &dyn GeometryBuffer, viewport: Rect, program: &dyn GpuProgram, params: &DrawParameters, resources: &[ResourceBindGroup], ) -> DrawCallStatistics { let server = self.state.upgrade().unwrap(); + let geometry = geometry + .as_any() + .downcast_ref::() + .unwrap(); pre_draw(self.id(), &server, viewport, program, params, resources); diff --git a/fyrox-graphics/src/gl/geometry_buffer.rs b/fyrox-graphics/src/gl/geometry_buffer.rs new file mode 100644 index 000000000..b4411e3df --- /dev/null +++ b/fyrox-graphics/src/gl/geometry_buffer.rs @@ -0,0 +1,182 @@ +// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +use crate::geometry_buffer::{AttributeKind, GeometryBuffer, GeometryBufferDescriptor}; +use crate::{ + buffer::{Buffer, BufferKind, BufferUsage}, + core::{array_as_u8_slice, math::TriangleDefinition}, + error::FrameworkError, + gl::{buffer::GlBuffer, server::GlGraphicsServer, ToGlConstant}, + ElementKind, +}; +use glow::HasContext; +use std::any::Any; +use std::{cell::Cell, marker::PhantomData, rc::Weak}; + +impl AttributeKind { + fn gl_type(self) -> u32 { + match self { + AttributeKind::Float => glow::FLOAT, + AttributeKind::UnsignedByte => glow::UNSIGNED_BYTE, + AttributeKind::UnsignedShort => glow::UNSIGNED_SHORT, + AttributeKind::UnsignedInt => glow::UNSIGNED_INT, + } + } +} + +pub struct GlGeometryBuffer { + pub state: Weak, + pub vertex_array_object: glow::VertexArray, + pub buffers: Vec, + pub element_buffer: GlBuffer, + pub element_count: Cell, + pub element_kind: ElementKind, + // Force compiler to not implement Send and Sync, because OpenGL is not thread-safe. + thread_mark: PhantomData<*const u8>, +} + +impl GlGeometryBuffer { + pub fn new( + server: &GlGraphicsServer, + desc: GeometryBufferDescriptor, + ) -> Result { + let vao = unsafe { server.gl.create_vertex_array()? }; + + server.set_vertex_array_object(Some(vao)); + + let element_buffer = GlBuffer::new(server, 0, BufferKind::Index, BufferUsage::StaticDraw)?; + + let mut buffers = Vec::new(); + for buffer in desc.buffers { + unsafe { + let data_size = buffer.data.bytes.map(|bytes| bytes.len()).unwrap_or(0); + + let native_buffer = + GlBuffer::new(server, data_size, BufferKind::Vertex, buffer.usage)?; + + if let Some(data) = buffer.data.bytes { + native_buffer.write_data(data)?; + } + + let target = native_buffer.kind.into_gl(); + server.gl.bind_buffer(target, Some(native_buffer.id)); + + let mut offset = 0usize; + for definition in buffer.attributes { + server.gl.vertex_attrib_pointer_f32( + definition.location, + definition.component_count as i32, + definition.kind.gl_type(), + definition.normalized, + buffer.data.element_size as i32, + offset as i32, + ); + server + .gl + .vertex_attrib_divisor(definition.location, definition.divisor); + server.gl.enable_vertex_attrib_array(definition.location); + + offset += definition.kind.size() * definition.component_count; + + if offset > buffer.data.element_size { + return Err(FrameworkError::InvalidAttributeDescriptor); + } + } + + buffers.push(native_buffer); + } + } + + server.set_vertex_array_object(None); + + Ok(GlGeometryBuffer { + state: server.weak(), + vertex_array_object: vao, + buffers, + element_buffer, + element_count: Cell::new(0), + element_kind: desc.element_kind, + thread_mark: PhantomData, + }) + } + + fn set_elements(&self, data: &[u8]) { + self.state + .upgrade() + .unwrap() + .set_vertex_array_object(Some(self.vertex_array_object)); + self.element_buffer.write_data(data).unwrap() + } + + pub fn mode(&self) -> u32 { + match self.element_kind { + ElementKind::Triangle => glow::TRIANGLES, + ElementKind::Line => glow::LINES, + ElementKind::Point => glow::POINTS, + } + } +} + +impl GeometryBuffer for GlGeometryBuffer { + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn set_buffer_data(&self, buffer: usize, data: &[u8]) { + self.state + .upgrade() + .unwrap() + .set_vertex_array_object(Some(self.vertex_array_object)); + self.buffers[buffer] + .write_data(array_as_u8_slice(data)) + .unwrap(); + } + + fn element_count(&self) -> usize { + self.element_count.get() + } + + fn set_triangles(&self, triangles: &[TriangleDefinition]) { + assert_eq!(self.element_kind, ElementKind::Triangle); + self.element_count.set(triangles.len()); + self.set_elements(array_as_u8_slice(triangles)); + } + + fn set_lines(&self, lines: &[[u32; 2]]) { + assert_eq!(self.element_kind, ElementKind::Line); + self.element_count.set(lines.len()); + self.set_elements(array_as_u8_slice(lines)); + } +} + +impl Drop for GlGeometryBuffer { + fn drop(&mut self) { + if let Some(state) = self.state.upgrade() { + unsafe { + self.buffers.clear(); + state.gl.delete_vertex_array(self.vertex_array_object); + } + } + } +} diff --git a/fyrox-graphics/src/gl/mod.rs b/fyrox-graphics/src/gl/mod.rs index 3590b692a..654b2b06d 100644 --- a/fyrox-graphics/src/gl/mod.rs +++ b/fyrox-graphics/src/gl/mod.rs @@ -25,6 +25,7 @@ pub mod query; pub mod read_buffer; pub mod server; pub mod texture; +pub mod geometry_buffer; pub trait ToGlConstant { fn into_gl(self) -> u32; diff --git a/fyrox-graphics/src/gl/server.rs b/fyrox-graphics/src/gl/server.rs index 239ade3e0..bef2b593e 100644 --- a/fyrox-graphics/src/gl/server.rs +++ b/fyrox-graphics/src/gl/server.rs @@ -18,6 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +use crate::geometry_buffer::{GeometryBuffer, GeometryBufferDescriptor}; +use crate::gl::geometry_buffer::GlGeometryBuffer; use crate::gl::program::GlProgram; use crate::gl::read_buffer::GlAsyncReadBuffer; use crate::gl::ToGlConstant; @@ -1145,6 +1147,13 @@ impl GraphicsServer for GlGraphicsServer { )?)) } + fn create_geometry_buffer( + &self, + desc: GeometryBufferDescriptor, + ) -> Result, FrameworkError> { + Ok(Box::new(GlGeometryBuffer::new(self, desc)?)) + } + fn as_any(&self) -> &dyn Any { self } diff --git a/fyrox-graphics/src/server.rs b/fyrox-graphics/src/server.rs index 75779fd4a..c97fa4c53 100644 --- a/fyrox-graphics/src/server.rs +++ b/fyrox-graphics/src/server.rs @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +use crate::geometry_buffer::{GeometryBuffer, GeometryBufferDescriptor}; use crate::{ buffer::{Buffer, BufferKind, BufferUsage}, error::FrameworkError, @@ -97,6 +98,10 @@ pub trait GraphicsServer: Any { pixel_size: usize, pixel_count: usize, ) -> Result, FrameworkError>; + fn create_geometry_buffer( + &self, + desc: GeometryBufferDescriptor, + ) -> Result, FrameworkError>; fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; fn weak(self: Rc) -> Weak; diff --git a/fyrox-impl/src/renderer/bloom/blur.rs b/fyrox-impl/src/renderer/bloom/blur.rs index 2377c7223..8bb624d18 100644 --- a/fyrox-impl/src/renderer/bloom/blur.rs +++ b/fyrox-impl/src/renderer/bloom/blur.rs @@ -134,7 +134,7 @@ impl GaussianBlur { pub(crate) fn render( &mut self, server: &dyn GraphicsServer, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, input: Rc>, uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { diff --git a/fyrox-impl/src/renderer/bloom/mod.rs b/fyrox-impl/src/renderer/bloom/mod.rs index 467aaaa96..bef93feb6 100644 --- a/fyrox-impl/src/renderer/bloom/mod.rs +++ b/fyrox-impl/src/renderer/bloom/mod.rs @@ -126,7 +126,7 @@ impl BloomRenderer { pub(crate) fn render( &mut self, server: &dyn GraphicsServer, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, hdr_scene_frame: Rc>, uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { diff --git a/fyrox-impl/src/renderer/cache/geometry.rs b/fyrox-impl/src/renderer/cache/geometry.rs index e7c6b190e..0f5cc02e4 100644 --- a/fyrox-impl/src/renderer/cache/geometry.rs +++ b/fyrox-impl/src/renderer/cache/geometry.rs @@ -32,7 +32,7 @@ use fyrox_core::log::Log; use fyrox_graphics::buffer::BufferUsage; struct SurfaceRenderData { - buffer: GeometryBuffer, + buffer: Box, vertex_modifications_count: u64, triangles_modifications_count: u64, layout_hash: u64, @@ -47,7 +47,8 @@ fn create_geometry_buffer( data: &SurfaceData, server: &GlGraphicsServer, ) -> Result { - let geometry_buffer = GeometryBuffer::from_surface_data(data, BufferUsage::StaticDraw, server)?; + let geometry_buffer = + ::from_surface_data(data, BufferUsage::StaticDraw, server)?; Ok(SurfaceRenderData { buffer: geometry_buffer, @@ -63,7 +64,7 @@ impl GeometryCache { server: &GlGraphicsServer, data: &SurfaceResource, time_to_live: TimeToLive, - ) -> Option<&'a mut GeometryBuffer> { + ) -> Option<&'a dyn GeometryBuffer> { let data = data.data_ref(); match self @@ -97,7 +98,7 @@ impl GeometryCache { data.geometry_buffer.modifications_count(); } } - Some(&mut entry.buffer) + Some(&*entry.buffer) } Err(err) => { Log::err(err.to_string()); diff --git a/fyrox-impl/src/renderer/debug_renderer.rs b/fyrox-impl/src/renderer/debug_renderer.rs index c2c4a17f3..9923be931 100644 --- a/fyrox-impl/src/renderer/debug_renderer.rs +++ b/fyrox-impl/src/renderer/debug_renderer.rs @@ -61,7 +61,7 @@ struct Vertex { /// See module docs. pub struct DebugRenderer { - geometry: GeometryBuffer, + geometry: Box, vertices: Vec, line_indices: Vec<[u32; 2]>, shader: DebugShader, @@ -128,7 +128,7 @@ impl DebugRenderer { }; Ok(Self { - geometry: GeometryBuffer::new(server, desc)?, + geometry: server.create_geometry_buffer(desc)?, shader: DebugShader::new(server)?, vertices: Default::default(), line_indices: Default::default(), @@ -154,7 +154,7 @@ impl DebugRenderer { self.line_indices.push([i, i + 1]); i += 2; } - self.geometry.set_buffer_data(0, &self.vertices); + self.geometry.set_buffer_data_of_type(0, &self.vertices); self.geometry.set_lines(&self.line_indices); } @@ -174,7 +174,7 @@ impl DebugRenderer { )?; statistics += framebuffer.draw( - &self.geometry, + &*self.geometry, viewport, &*self.shader.program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/framework/mod.rs b/fyrox-impl/src/renderer/framework/mod.rs index 9e9360859..914d2d207 100644 --- a/fyrox-impl/src/renderer/framework/mod.rs +++ b/fyrox-impl/src/renderer/framework/mod.rs @@ -39,6 +39,7 @@ use crate::{ }, scene::mesh::{buffer::VertexAttributeDataType, surface::SurfaceData}, }; +use fyrox_graphics::server::GraphicsServer; pub use fyrox_graphics::*; impl From for GpuTextureKind { @@ -135,21 +136,21 @@ impl From for WrapMode { } /// Extension trait for [`GeometryBuffer`]. -pub trait GeometryBufferExt: Sized { +pub trait GeometryBufferExt { /// Creates [`GeometryBuffer`] from [`SurfaceData`]. fn from_surface_data( data: &SurfaceData, usage: BufferUsage, server: &GlGraphicsServer, - ) -> Result; + ) -> Result, FrameworkError>; } -impl GeometryBufferExt for GeometryBuffer { +impl GeometryBufferExt for dyn GeometryBuffer { fn from_surface_data( data: &SurfaceData, usage: BufferUsage, server: &GlGraphicsServer, - ) -> Result { + ) -> Result, FrameworkError> { let attributes = data .vertex_buffer .layout() @@ -180,7 +181,7 @@ impl GeometryBufferExt for GeometryBuffer { }], }; - let geometry_buffer = GeometryBuffer::new(server, geometry_buffer_desc)?; + let geometry_buffer = server.create_geometry_buffer(geometry_buffer_desc)?; geometry_buffer.set_triangles(data.geometry_buffer.triangles_ref()); diff --git a/fyrox-impl/src/renderer/fxaa.rs b/fyrox-impl/src/renderer/fxaa.rs index c7c594657..9fd535e69 100644 --- a/fyrox-impl/src/renderer/fxaa.rs +++ b/fyrox-impl/src/renderer/fxaa.rs @@ -67,14 +67,14 @@ impl FxaaShader { pub struct FxaaRenderer { shader: FxaaShader, - quad: GeometryBuffer, + quad: Box, } impl FxaaRenderer { pub fn new(server: &GlGraphicsServer) -> Result { Ok(Self { shader: FxaaShader::new(server)?, - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_unit_xy_quad(), BufferUsage::StaticDraw, server, @@ -106,7 +106,7 @@ impl FxaaRenderer { )); statistics += frame_buffer.draw( - &self.quad, + &*self.quad, viewport, &*self.shader.program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/gbuffer/mod.rs b/fyrox-impl/src/renderer/gbuffer/mod.rs index 180e7ff68..992db9912 100644 --- a/fyrox-impl/src/renderer/gbuffer/mod.rs +++ b/fyrox-impl/src/renderer/gbuffer/mod.rs @@ -78,7 +78,7 @@ pub struct GBuffer { decal_framebuffer: Box, pub width: i32, pub height: i32, - cube: GeometryBuffer, + cube: Box, decal_shader: DecalShader, render_pass_name: ImmutableString, occlusion_tester: OcclusionTester, @@ -102,7 +102,7 @@ pub(crate) struct GBufferRenderContext<'a, 'b> { pub uniform_memory_allocator: &'a mut UniformMemoryAllocator, #[allow(dead_code)] pub screen_space_debug_renderer: &'a mut DebugRenderer, - pub unit_quad: &'a GeometryBuffer, + pub unit_quad: &'a dyn GeometryBuffer, } impl GBuffer { @@ -249,7 +249,7 @@ impl GBuffer { width: width as i32, height: height as i32, decal_shader: DecalShader::new(server)?, - cube: GeometryBuffer::from_surface_data( + cube: ::from_surface_data( &SurfaceData::make_cube(Matrix4::identity()), BufferUsage::StaticDraw, server, @@ -424,7 +424,7 @@ impl GBuffer { .clone(); statistics += self.decal_framebuffer.draw( - unit_cube, + &**unit_cube, viewport, program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/hdr/mod.rs b/fyrox-impl/src/renderer/hdr/mod.rs index e5cb9b2d6..2eda13ef5 100644 --- a/fyrox-impl/src/renderer/hdr/mod.rs +++ b/fyrox-impl/src/renderer/hdr/mod.rs @@ -166,7 +166,7 @@ impl HighDynamicRangeRenderer { &mut self, server: &dyn GraphicsServer, scene_frame: Rc>, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { self.frame_luminance.clear(); @@ -215,7 +215,7 @@ impl HighDynamicRangeRenderer { fn calculate_avg_frame_luminance( &mut self, server: &dyn GraphicsServer, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { let mut stats = RenderPassStatistics::default(); @@ -320,7 +320,7 @@ impl HighDynamicRangeRenderer { fn adaptation( &mut self, server: &dyn GraphicsServer, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, dt: f32, uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { @@ -373,7 +373,7 @@ impl HighDynamicRangeRenderer { bloom_texture: Rc>, ldr_framebuffer: &mut dyn FrameBuffer, viewport: Rect, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, exposure: Exposure, color_grading_lut: Option<&ColorGradingLut>, use_color_grading: bool, @@ -449,7 +449,7 @@ impl HighDynamicRangeRenderer { bloom_texture: Rc>, ldr_framebuffer: &mut dyn FrameBuffer, viewport: Rect, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, dt: f32, exposure: Exposure, color_grading_lut: Option<&ColorGradingLut>, diff --git a/fyrox-impl/src/renderer/light/mod.rs b/fyrox-impl/src/renderer/light/mod.rs index bced53851..ef3866963 100644 --- a/fyrox-impl/src/renderer/light/mod.rs +++ b/fyrox-impl/src/renderer/light/mod.rs @@ -78,10 +78,10 @@ pub struct DeferredLightRenderer { point_light_shader: PointLightShader, directional_light_shader: DirectionalLightShader, ambient_light_shader: AmbientLightShader, - quad: GeometryBuffer, - sphere: GeometryBuffer, - cone: GeometryBuffer, - skybox: GeometryBuffer, + quad: Box, + sphere: Box, + cone: Box, + skybox: Box, flat_shader: FlatShader, skybox_shader: SkyboxShader, spot_shadow_map_renderer: SpotShadowMapRenderer, @@ -162,12 +162,12 @@ impl DeferredLightRenderer { point_light_shader: PointLightShader::new(server)?, directional_light_shader: DirectionalLightShader::new(server)?, ambient_light_shader: AmbientLightShader::new(server)?, - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_unit_xy_quad(), BufferUsage::StaticDraw, server, )?, - skybox: GeometryBuffer::from_surface_data( + skybox: ::from_surface_data( &SurfaceData::new( VertexBuffer::new(vertices.len(), vertices).unwrap(), TriangleBuffer::new(vec![ @@ -188,12 +188,12 @@ impl DeferredLightRenderer { BufferUsage::StaticDraw, server, )?, - sphere: GeometryBuffer::from_surface_data( + sphere: ::from_surface_data( &SurfaceData::make_sphere(6, 6, 1.0, &Matrix4::identity()), BufferUsage::StaticDraw, server, )?, - cone: GeometryBuffer::from_surface_data( + cone: ::from_surface_data( &SurfaceData::make_cone( 16, 0.5, @@ -347,7 +347,7 @@ impl DeferredLightRenderer { { let shader = &self.skybox_shader; pass_stats += frame_buffer.draw( - &self.skybox, + &*self.skybox, viewport, &*shader.program, &DrawParameters { @@ -391,7 +391,7 @@ impl DeferredLightRenderer { let ao_map = self.ssao_renderer.ao_map(); pass_stats += frame_buffer.draw( - &self.quad, + &*self.quad, viewport, &*self.ambient_light_shader.program, &DrawParameters { @@ -550,7 +550,7 @@ impl DeferredLightRenderer { )?; pass_stats += frame_buffer.draw( - bounding_shape, + &**bounding_shape, viewport, &*self.flat_shader.program, &DrawParameters { @@ -580,7 +580,7 @@ impl DeferredLightRenderer { )?; pass_stats += frame_buffer.draw( - bounding_shape, + &**bounding_shape, viewport, &*self.flat_shader.program, &DrawParameters { @@ -625,7 +625,7 @@ impl DeferredLightRenderer { visibility_cache.begin_query(server, camera_global_position, light_handle)?; frame_buffer.draw( - &self.quad, + &*self.quad, viewport, &*self.flat_shader.program, &DrawParameters { @@ -811,7 +811,7 @@ impl DeferredLightRenderer { )?; frame_buffer.draw( - quad, + &**quad, viewport, &*shader.program, &draw_params, @@ -866,7 +866,7 @@ impl DeferredLightRenderer { )?; frame_buffer.draw( - quad, + &**quad, viewport, &*shader.program, &draw_params, @@ -935,7 +935,7 @@ impl DeferredLightRenderer { )?; frame_buffer.draw( - quad, + &**quad, viewport, &*shader.program, &DrawParameters { @@ -1000,7 +1000,7 @@ impl DeferredLightRenderer { light, light_handle, gbuffer, - &self.quad, + &*self.quad, camera.view_matrix(), inv_projection, view_projection, diff --git a/fyrox-impl/src/renderer/light_volume.rs b/fyrox-impl/src/renderer/light_volume.rs index 1edf9f2ab..677d45348 100644 --- a/fyrox-impl/src/renderer/light_volume.rs +++ b/fyrox-impl/src/renderer/light_volume.rs @@ -97,8 +97,8 @@ pub struct LightVolumeRenderer { spot_light_shader: SpotLightShader, point_light_shader: PointLightShader, flat_shader: FlatShader, - cone: GeometryBuffer, - sphere: GeometryBuffer, + cone: Box, + sphere: Box, } impl LightVolumeRenderer { @@ -107,7 +107,7 @@ impl LightVolumeRenderer { spot_light_shader: SpotLightShader::new(server)?, point_light_shader: PointLightShader::new(server)?, flat_shader: FlatShader::new(server)?, - cone: GeometryBuffer::from_surface_data( + cone: ::from_surface_data( &SurfaceData::make_cone( 16, 1.0, @@ -117,7 +117,7 @@ impl LightVolumeRenderer { BufferUsage::StaticDraw, server, )?, - sphere: GeometryBuffer::from_surface_data( + sphere: ::from_surface_data( &SurfaceData::make_sphere(8, 8, 1.0, &Matrix4::identity()), BufferUsage::StaticDraw, server, @@ -132,7 +132,7 @@ impl LightVolumeRenderer { light: &Node, light_handle: Handle, gbuffer: &mut GBuffer, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, view: Matrix4, inv_proj: Matrix4, view_proj: Matrix4, @@ -191,7 +191,7 @@ impl LightVolumeRenderer { frame_buffer.clear(viewport, None, None, Some(0)); stats += frame_buffer.draw( - &self.cone, + &*self.cone, viewport, &*self.flat_shader.program, &DrawParameters { @@ -295,7 +295,7 @@ impl LightVolumeRenderer { uniform_buffer_cache.write(server, StaticUniformBuffer::<256>::new().with(&mvp))?; stats += frame_buffer.draw( - &self.sphere, + &*self.sphere, viewport, &*self.flat_shader.program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/mod.rs b/fyrox-impl/src/renderer/mod.rs index 141408847..751b80376 100644 --- a/fyrox-impl/src/renderer/mod.rs +++ b/fyrox-impl/src/renderer/mod.rs @@ -670,7 +670,7 @@ pub struct Renderer { /// User interface renderer. pub ui_renderer: UiRenderer, statistics: Statistics, - quad: GeometryBuffer, + quad: Box, frame_size: (u32, u32), quality_settings: QualitySettings, /// Debug renderer instance can be used for debugging purposes @@ -878,7 +878,7 @@ fn blit_pixels( texture: Rc>, shader: &FlatShader, viewport: Rect, - quad: &GeometryBuffer, + quad: &dyn GeometryBuffer, ) -> Result { let matrix = Matrix4::new_orthographic( 0.0, @@ -1068,7 +1068,7 @@ impl Renderer { 1, Some(&[0u8, 0u8, 0u8, 0u8]), )?, - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_unit_xy_quad(), BufferUsage::StaticDraw, &server, @@ -1462,7 +1462,7 @@ impl Renderer { bone_matrices_stub_uniform_buffer: &*self.bone_matrices_stub_uniform_buffer, uniform_memory_allocator: &mut self.uniform_memory_allocator, screen_space_debug_renderer: &mut self.screen_space_debug_renderer, - unit_quad: &self.quad, + unit_quad: &*self.quad, })?; server.set_polygon_fill_mode(PolygonFace::FrontAndBack, PolygonFillMode::Fill); @@ -1570,7 +1570,7 @@ impl Renderer { // Prepare glow map. scene_associated_data.statistics += scene_associated_data.bloom_renderer.render( &**server, - quad, + &**quad, scene_associated_data.hdr_scene_frame_texture(), &mut self.uniform_buffer_cache, )?; @@ -1582,7 +1582,7 @@ impl Renderer { scene_associated_data.bloom_renderer.result(), &mut *scene_associated_data.ldr_scene_framebuffer, viewport, - quad, + &**quad, dt, camera.exposure(), camera.color_grading_lut_ref(), @@ -1610,7 +1610,7 @@ impl Renderer { temp_frame_texture, &self.flat_shader, viewport, - quad, + &**quad, )?; } @@ -1670,7 +1670,7 @@ impl Renderer { scene_associated_data.ldr_scene_frame_texture(), &self.flat_shader, window_viewport, - quad, + &**quad, )?; } diff --git a/fyrox-impl/src/renderer/occlusion/mod.rs b/fyrox-impl/src/renderer/occlusion/mod.rs index 960d0adce..ad330e2a1 100644 --- a/fyrox-impl/src/renderer/occlusion/mod.rs +++ b/fyrox-impl/src/renderer/occlusion/mod.rs @@ -96,7 +96,7 @@ pub struct OcclusionTester { tile_size: usize, w_tiles: usize, h_tiles: usize, - cube: GeometryBuffer, + cube: Box, visibility_buffer_optimizer: VisibilityBufferOptimizer, matrix_storage: MatrixStorage, objects_to_test: Vec>, @@ -238,7 +238,7 @@ impl OcclusionTester { w_tiles, tile_buffer, h_tiles, - cube: GeometryBuffer::from_surface_data( + cube: ::from_surface_data( &SurfaceData::make_cube(Matrix4::identity()), BufferUsage::StaticDraw, server, @@ -415,7 +415,7 @@ impl OcclusionTester { server: &GlGraphicsServer, graph: &Graph, debug_renderer: Option<&mut DebugRenderer>, - unit_quad: &GeometryBuffer, + unit_quad: &dyn GeometryBuffer, objects_to_test: impl Iterator>, prev_framebuffer: &dyn FrameBuffer, observer_position: Vector3, @@ -454,7 +454,7 @@ impl OcclusionTester { let shader = &self.shader; self.framebuffer.draw_instances( self.objects_to_test.len(), - &self.cube, + &*self.cube, viewport, &*self.shader.program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/occlusion/optimizer.rs b/fyrox-impl/src/renderer/occlusion/optimizer.rs index 560581ac1..d4c259e50 100644 --- a/fyrox-impl/src/renderer/occlusion/optimizer.rs +++ b/fyrox-impl/src/renderer/occlusion/optimizer.rs @@ -118,7 +118,7 @@ impl VisibilityBufferOptimizer { &mut self, server: &GlGraphicsServer, visibility_buffer: &Rc>, - unit_quad: &GeometryBuffer, + unit_quad: &dyn GeometryBuffer, tile_size: i32, uniform_buffer_cache: &mut UniformBufferCache, ) -> Result<(), FrameworkError> { diff --git a/fyrox-impl/src/renderer/ssao/blur.rs b/fyrox-impl/src/renderer/ssao/blur.rs index 8a002649c..f53d24cef 100644 --- a/fyrox-impl/src/renderer/ssao/blur.rs +++ b/fyrox-impl/src/renderer/ssao/blur.rs @@ -69,7 +69,7 @@ impl Shader { pub struct Blur { shader: Shader, framebuffer: Box, - quad: GeometryBuffer, + quad: Box, width: usize, height: usize, } @@ -108,7 +108,7 @@ impl Blur { texture: frame, }], )?, - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_unit_xy_quad(), BufferUsage::StaticDraw, server, @@ -132,7 +132,7 @@ impl Blur { let shader = &self.shader; self.framebuffer.draw( - &self.quad, + &*self.quad, viewport, &*shader.program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/ssao/mod.rs b/fyrox-impl/src/renderer/ssao/mod.rs index 1fb518a3b..a73ef19c9 100644 --- a/fyrox-impl/src/renderer/ssao/mod.rs +++ b/fyrox-impl/src/renderer/ssao/mod.rs @@ -87,7 +87,7 @@ pub struct ScreenSpaceAmbientOcclusionRenderer { blur: Blur, shader: Shader, framebuffer: Box, - quad: GeometryBuffer, + quad: Box, width: i32, height: i32, noise: Rc>, @@ -127,7 +127,7 @@ impl ScreenSpaceAmbientOcclusionRenderer { texture: occlusion, }], )?, - quad: GeometryBuffer::from_surface_data( + quad: ::from_surface_data( &SurfaceData::make_unit_xy_quad(), BufferUsage::StaticDraw, server, @@ -246,7 +246,7 @@ impl ScreenSpaceAmbientOcclusionRenderer { )?; stats += self.framebuffer.draw( - &self.quad, + &*self.quad, viewport, &*self.shader.program, &DrawParameters { diff --git a/fyrox-impl/src/renderer/ui_renderer.rs b/fyrox-impl/src/renderer/ui_renderer.rs index d55bd173b..1a71020cf 100644 --- a/fyrox-impl/src/renderer/ui_renderer.rs +++ b/fyrox-impl/src/renderer/ui_renderer.rs @@ -79,8 +79,8 @@ impl UiShader { /// User interface renderer allows you to render drawing context in specified render target. pub struct UiRenderer { shader: UiShader, - geometry_buffer: GeometryBuffer, - clipping_geometry_buffer: GeometryBuffer, + geometry_buffer: Box, + clipping_geometry_buffer: Box, } /// A set of parameters to render a specified user interface drawing context. @@ -159,8 +159,9 @@ impl UiRenderer { }; Ok(Self { - geometry_buffer: GeometryBuffer::new(server, geometry_buffer_desc)?, - clipping_geometry_buffer: GeometryBuffer::new(server, clipping_geometry_buffer_desc)?, + geometry_buffer: server.create_geometry_buffer(geometry_buffer_desc)?, + clipping_geometry_buffer: server + .create_geometry_buffer(clipping_geometry_buffer_desc)?, shader: UiShader::new(server)?, }) } @@ -186,7 +187,7 @@ impl UiRenderer { let mut statistics = RenderPassStatistics::default(); self.geometry_buffer - .set_buffer_data(0, drawing_context.get_vertices()); + .set_buffer_data_of_type(0, drawing_context.get_vertices()); self.geometry_buffer .set_triangles(drawing_context.get_triangles()); @@ -219,7 +220,7 @@ impl UiRenderer { frame_buffer.clear(viewport, None, None, Some(0)); self.clipping_geometry_buffer - .set_buffer_data(0, &clipping_geometry.vertex_buffer); + .set_buffer_data_of_type(0, &clipping_geometry.vertex_buffer); self.clipping_geometry_buffer .set_triangles(&clipping_geometry.triangle_buffer); @@ -228,7 +229,7 @@ impl UiRenderer { // Draw statistics += frame_buffer.draw( - &self.clipping_geometry_buffer, + &*self.clipping_geometry_buffer, viewport, &*flat_shader.program, &DrawParameters { @@ -395,7 +396,7 @@ impl UiRenderer { let shader = &self.shader; statistics += frame_buffer.draw( - &self.geometry_buffer, + &*self.geometry_buffer, viewport, &*self.shader.program, ¶ms,