moved low-level rendering details into a separate crate

- round 2
- no rollback, I promise
This commit is contained in:
Dmitry Stepanov
2024-09-19 19:15:44 +03:00
parent 1cee97a68a
commit 101c011871
28 changed files with 849 additions and 733 deletions
+1
View File
@@ -42,6 +42,7 @@
<sourceFolder url="file://$MODULE_DIR$/fyrox/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/project-manager/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/template-core/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/fyrox-graphics/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
<excludeFolder url="file://$MODULE_DIR$/examples/wasm/target" />
</content>
+1 -1
View File
@@ -16,7 +16,7 @@ members = [
"fyrox-dylib",
"fyrox",
"fyrox-impl"
, "project-manager"]
, "project-manager", "fyrox-graphics"]
resolver = "2"
[profile.dev]
+1
View File
@@ -49,6 +49,7 @@ use crate::{
},
Editor,
};
use fyrox::renderer::framework::GeometryBufferExt;
use std::{any::TypeId, cell::RefCell, rc::Rc};
struct EdgeDetectShader {
+1
View File
@@ -39,6 +39,7 @@ use crate::{
},
Editor,
};
use fyrox::renderer::framework::GeometryBufferExt;
use std::{any::TypeId, cell::RefCell, rc::Rc};
struct OverlayShader {
+22
View File
@@ -0,0 +1,22 @@
[package]
name = "fyrox-graphics"
version = "0.1.0"
edition = "2021"
[dependencies]
fyrox-core = { path = "../fyrox-core", version = "0.28.1", features = ["serde"] }
glow = "0.14.1"
serde = { version = "1", features = ["derive"] }
strum = "0.26.1"
strum_macros = "0.26.1"
winit = { version = "0.29.2", features = ["serde"] }
bytemuck = { version = "1.16.1", features = ["derive"] }
fxhash = "0.2.1"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
glutin = "0.31"
glutin-winit = "0.4.2"
raw-window-handle = "0.5.0"
[target.'cfg(target_arch = "wasm32")'.dependencies]
serde-wasm-bindgen = "0.6.3"
@@ -21,6 +21,7 @@
//! Contains all possible errors that may occur during rendering, initialization of
//! renderer structures, or GAPI.
use std::error::Error;
use std::ffi::NulError;
use std::fmt::{Display, Formatter};
@@ -166,3 +167,9 @@ impl From<String> for FrameworkError {
Self::Custom(v)
}
}
impl From<Box<dyn Error>> for FrameworkError {
fn from(e: Box<dyn Error>) -> Self {
Self::Custom(format!("{:?}", e))
}
}
@@ -18,21 +18,17 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::DrawParameters;
use crate::{
core::{color::Color, math::Rect},
renderer::framework::{
error::FrameworkError,
geometry_buffer::{DrawCallStatistics, GeometryBuffer},
gpu_program::{GpuProgram, GpuProgramBinding},
gpu_texture::{CubeMapFace, GpuTexture, GpuTextureKind, PixelElementKind},
state::PipelineState,
ColorMask, ElementRange,
},
error::FrameworkError,
geometry_buffer::{DrawCallStatistics, GeometryBuffer},
gpu_program::{GpuProgram, GpuProgramBinding},
gpu_texture::{CubeMapFace, GpuTexture, GpuTextureKind, PixelElementKind},
state::PipelineState,
ColorMask, DrawParameters, ElementRange,
};
use glow::HasContext;
use std::rc::Weak;
use std::{cell::RefCell, rc::Rc};
use std::{cell::RefCell, rc::Rc, rc::Weak};
#[derive(Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Eq)]
pub enum AttachmentKind {
@@ -20,11 +20,9 @@
use crate::{
core::{array_as_u8_slice, math::TriangleDefinition},
renderer::framework::{error::FrameworkError, state::PipelineState, ElementKind, ElementRange},
scene::mesh::{
buffer::{VertexAttributeDataType, VertexBuffer},
surface::SurfaceData,
},
error::FrameworkError,
state::PipelineState,
ElementKind, ElementRange,
};
use glow::HasContext;
use std::{cell::Cell, marker::PhantomData, mem::size_of, rc::Weak};
@@ -277,22 +275,6 @@ impl<'a> GeometryBufferBinding<'a> {
}
impl GeometryBuffer {
pub fn from_surface_data(
data: &SurfaceData,
kind: GeometryBufferKind,
state: &PipelineState,
) -> Result<Self, FrameworkError> {
let geometry_buffer = GeometryBufferBuilder::new(ElementKind::Triangle)
.with_buffer_builder(BufferBuilder::from_vertex_buffer(&data.vertex_buffer, kind))
.build(state)?;
geometry_buffer
.bind(state)
.set_triangles(data.geometry_buffer.triangles_ref());
Ok(geometry_buffer)
}
pub fn set_buffer_data<T: bytemuck::Pod>(
&mut self,
state: &PipelineState,
@@ -359,11 +341,11 @@ impl Drop for GeometryBuffer {
}
pub struct BufferBuilder {
element_size: usize,
kind: GeometryBufferKind,
attributes: Vec<AttributeDefinition>,
data: *const u8,
data_size: usize,
pub element_size: usize,
pub kind: GeometryBufferKind,
pub attributes: Vec<AttributeDefinition>,
pub data: *const u8,
pub data_size: usize,
}
impl BufferBuilder {
@@ -383,43 +365,6 @@ impl BufferBuilder {
}
}
pub fn from_vertex_buffer(buffer: &VertexBuffer, kind: GeometryBufferKind) -> Self {
Self {
element_size: buffer.vertex_size() as usize,
kind,
attributes: buffer
.layout()
.iter()
.map(|a| AttributeDefinition {
location: a.shader_location as u32,
kind: match (a.data_type, a.size) {
(VertexAttributeDataType::F32, 1) => AttributeKind::Float,
(VertexAttributeDataType::F32, 2) => AttributeKind::Float2,
(VertexAttributeDataType::F32, 3) => AttributeKind::Float3,
(VertexAttributeDataType::F32, 4) => AttributeKind::Float4,
(VertexAttributeDataType::U32, 1) => AttributeKind::UnsignedInt,
(VertexAttributeDataType::U32, 2) => AttributeKind::UnsignedInt2,
(VertexAttributeDataType::U32, 3) => AttributeKind::UnsignedInt3,
(VertexAttributeDataType::U32, 4) => AttributeKind::UnsignedInt4,
(VertexAttributeDataType::U16, 1) => AttributeKind::UnsignedShort,
(VertexAttributeDataType::U16, 2) => AttributeKind::UnsignedShort2,
(VertexAttributeDataType::U16, 3) => AttributeKind::UnsignedShort3,
(VertexAttributeDataType::U16, 4) => AttributeKind::UnsignedShort4,
(VertexAttributeDataType::U8, 1) => AttributeKind::UnsignedByte,
(VertexAttributeDataType::U8, 2) => AttributeKind::UnsignedByte2,
(VertexAttributeDataType::U8, 3) => AttributeKind::UnsignedByte3,
(VertexAttributeDataType::U8, 4) => AttributeKind::UnsignedByte4,
_ => unreachable!(),
},
normalized: a.normalized,
divisor: a.divisor as u32,
})
.collect(),
data: buffer.raw_data().as_ptr(),
data_size: buffer.raw_data().len(),
}
}
pub fn with_attribute(mut self, attribute: AttributeDefinition) -> Self {
self.attributes.push(attribute);
self
@@ -18,7 +18,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::state::GlKind;
use crate::{
core::{
algebra::{Matrix2, Matrix3, Matrix4, Vector2, Vector3, Vector4},
@@ -26,12 +25,18 @@ use crate::{
log::{Log, MessageKind},
sstorage::ImmutableString,
},
renderer::framework::{error::FrameworkError, gpu_texture::GpuTexture, state::PipelineState},
error::FrameworkError,
gpu_texture::GpuTexture,
state::{GlKind, PipelineState},
};
use fxhash::FxHashMap;
use glow::HasContext;
use std::rc::Weak;
use std::{cell::RefCell, marker::PhantomData, ops::Deref, rc::Rc};
use std::{
cell::RefCell,
marker::PhantomData,
ops::Deref,
rc::{Rc, Weak},
};
pub struct GpuProgram {
state: Weak<PipelineState>,
@@ -39,8 +44,7 @@ pub struct GpuProgram {
// Force compiler to not implement Send and Sync, because OpenGL is not thread-safe.
thread_mark: PhantomData<*const u8>,
uniform_locations: RefCell<FxHashMap<ImmutableString, Option<UniformLocation>>>,
pub(crate) built_in_uniform_locations:
[Option<UniformLocation>; BuiltInUniform::Count as usize],
pub built_in_uniform_locations: [Option<UniformLocation>; BuiltInUniform::Count as usize],
}
#[repr(usize)]
@@ -146,7 +150,7 @@ fn prepare_source_code(code: &str, gl_kind: GlKind) -> String {
pub struct GpuProgramBinding<'a, 'b> {
pub state: &'a PipelineState,
active_sampler: u32,
pub(crate) program: &'b GpuProgram,
pub program: &'b GpuProgram,
}
impl<'a, 'b> GpuProgramBinding<'a, 'b> {
@@ -18,14 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::{
core::color::Color,
renderer::framework::{error::FrameworkError, state::PipelineState},
resource::texture::{
TextureKind, TextureMagnificationFilter, TextureMinificationFilter, TexturePixelKind,
TextureWrapMode,
},
};
use crate::{core::color::Color, error::FrameworkError, state::PipelineState};
use bytemuck::Pod;
use glow::{HasContext, PixelPackData, COMPRESSED_RED_RGTC1, COMPRESSED_RG_RGTC2};
use std::marker::PhantomData;
@@ -51,33 +44,6 @@ pub enum GpuTextureKind {
},
}
impl From<TextureKind> for GpuTextureKind {
fn from(v: TextureKind) -> Self {
match v {
TextureKind::Line { length } => GpuTextureKind::Line {
length: length as usize,
},
TextureKind::Rectangle { width, height } => GpuTextureKind::Rectangle {
width: width as usize,
height: height as usize,
},
TextureKind::Cube { width, height } => GpuTextureKind::Cube {
width: width as usize,
height: height as usize,
},
TextureKind::Volume {
width,
height,
depth,
} => GpuTextureKind::Volume {
width: width as usize,
height: height as usize,
depth: depth as usize,
},
}
}
}
impl GpuTextureKind {
fn gl_texture_target(&self) -> u32 {
match self {
@@ -128,38 +94,6 @@ pub enum PixelKind {
RGB10A2,
}
impl From<TexturePixelKind> for PixelKind {
fn from(texture_kind: TexturePixelKind) -> Self {
match texture_kind {
TexturePixelKind::R8 => Self::R8,
TexturePixelKind::RGB8 => Self::RGB8,
TexturePixelKind::RGBA8 => Self::RGBA8,
TexturePixelKind::RG8 => Self::RG8,
TexturePixelKind::R16 => Self::R16,
TexturePixelKind::RG16 => Self::RG16,
TexturePixelKind::BGR8 => Self::BGR8,
TexturePixelKind::BGRA8 => Self::BGRA8,
TexturePixelKind::RGB16 => Self::RGB16,
TexturePixelKind::RGBA16 => Self::RGBA16,
TexturePixelKind::RGB16F => Self::RGB16F,
TexturePixelKind::DXT1RGB => Self::DXT1RGB,
TexturePixelKind::DXT1RGBA => Self::DXT1RGBA,
TexturePixelKind::DXT3RGBA => Self::DXT3RGBA,
TexturePixelKind::DXT5RGBA => Self::DXT5RGBA,
TexturePixelKind::R8RGTC => Self::R8RGTC,
TexturePixelKind::RG8RGTC => Self::RG8RGTC,
TexturePixelKind::RGB32F => Self::RGB32F,
TexturePixelKind::RGBA32F => Self::RGBA32F,
TexturePixelKind::Luminance8 => Self::L8,
TexturePixelKind::LuminanceAlpha8 => Self::LA8,
TexturePixelKind::Luminance16 => Self::L16,
TexturePixelKind::LuminanceAlpha16 => Self::LA16,
TexturePixelKind::R32F => Self::R32F,
TexturePixelKind::R16F => Self::R16F,
}
}
}
pub enum PixelElementKind {
Float,
NormalizedUnsignedInteger,
@@ -549,15 +483,6 @@ impl MagnificationFilter {
}
}
impl From<TextureMagnificationFilter> for MagnificationFilter {
fn from(v: TextureMagnificationFilter) -> Self {
match v {
TextureMagnificationFilter::Nearest => Self::Nearest,
TextureMagnificationFilter::Linear => Self::Linear,
}
}
}
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Hash, Debug)]
#[repr(u32)]
pub enum MinificationFilter {
@@ -569,18 +494,6 @@ pub enum MinificationFilter {
LinearMipMapLinear = glow::LINEAR_MIPMAP_LINEAR,
}
impl From<TextureMinificationFilter> for MinificationFilter {
fn from(v: TextureMinificationFilter) -> Self {
match v {
TextureMinificationFilter::Nearest => Self::Nearest,
TextureMinificationFilter::NearestMipMapNearest => Self::NearestMipMapNearest,
TextureMinificationFilter::NearestMipMapLinear => Self::NearestMipMapLinear,
TextureMinificationFilter::Linear => Self::Linear,
TextureMinificationFilter::LinearMipMapNearest => Self::LinearMipMapNearest,
TextureMinificationFilter::LinearMipMapLinear => Self::LinearMipMapLinear,
}
}
}
impl MinificationFilter {
pub fn into_gl_value(self) -> i32 {
self as i32
@@ -603,18 +516,6 @@ impl WrapMode {
}
}
impl From<TextureWrapMode> for WrapMode {
fn from(v: TextureWrapMode) -> Self {
match v {
TextureWrapMode::Repeat => WrapMode::Repeat,
TextureWrapMode::ClampToEdge => WrapMode::ClampToEdge,
TextureWrapMode::ClampToBorder => WrapMode::ClampToBorder,
TextureWrapMode::MirroredRepeat => WrapMode::MirroredRepeat,
TextureWrapMode::MirrorClampToEdge => WrapMode::MirrorClampToEdge,
}
}
}
#[derive(Copy, Clone)]
#[repr(u32)]
pub enum Coordinate {
+468
View File
@@ -0,0 +1,468 @@
// 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.
pub use fyrox_core as core;
use crate::core::{reflect::prelude::*, type_traits::prelude::*, visitor::prelude::*};
use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, EnumString, VariantNames};
pub mod error;
pub mod framebuffer;
pub mod geometry_buffer;
pub mod gpu_program;
pub mod gpu_texture;
pub mod pixel_buffer;
pub mod query;
pub mod state;
pub mod stats;
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Hash,
Debug,
Deserialize,
Visit,
Eq,
Reflect,
AsRefStr,
EnumString,
VariantNames,
TypeUuidProvider,
)]
#[type_uuid(id = "47aff01a-7daa-427c-874c-87464a7ffe28")]
pub enum PolygonFillMode {
Point,
Line,
Fill,
}
impl Default for PolygonFillMode {
fn default() -> Self {
Self::Fill
}
}
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Eq,
Ord,
Hash,
Visit,
Serialize,
Deserialize,
Debug,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum CompareFunc {
/// Never passes.
Never,
/// Passes if the incoming value is less than the stored value.
Less,
/// Passes if the incoming value is equal to the stored value.
Equal,
/// Passes if the incoming value is less than or equal to the stored value.
LessOrEqual,
/// Passes if the incoming value is greater than the stored value.
Greater,
/// Passes if the incoming value is not equal to the stored value.
NotEqual,
/// Passes if the incoming value is greater than or equal to the stored value.
GreaterOrEqual,
/// Always passes.
Always,
}
impl Default for CompareFunc {
fn default() -> Self {
Self::LessOrEqual
}
}
#[derive(
Copy,
Clone,
Hash,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
Visit,
Debug,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum BlendFactor {
Zero,
One,
SrcColor,
OneMinusSrcColor,
DstColor,
OneMinusDstColor,
SrcAlpha,
OneMinusSrcAlpha,
DstAlpha,
OneMinusDstAlpha,
ConstantColor,
OneMinusConstantColor,
ConstantAlpha,
OneMinusConstantAlpha,
SrcAlphaSaturate,
Src1Color,
OneMinusSrc1Color,
Src1Alpha,
OneMinusSrc1Alpha,
}
impl Default for BlendFactor {
fn default() -> Self {
Self::Zero
}
}
#[derive(
Copy, Clone, Hash, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize, Visit, Debug, Reflect,
)]
pub enum BlendMode {
Add,
Subtract,
ReverseSubtract,
Min,
Max,
}
impl Default for BlendMode {
fn default() -> Self {
Self::Add
}
}
#[derive(
Copy,
Clone,
Default,
PartialOrd,
PartialEq,
Ord,
Eq,
Hash,
Serialize,
Deserialize,
Visit,
Debug,
Reflect,
)]
pub struct BlendEquation {
pub rgb: BlendMode,
pub alpha: BlendMode,
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Serialize, Deserialize, Visit, Debug, Reflect,
)]
pub struct BlendFunc {
pub sfactor: BlendFactor,
pub dfactor: BlendFactor,
pub alpha_sfactor: BlendFactor,
pub alpha_dfactor: BlendFactor,
}
impl BlendFunc {
pub fn new(sfactor: BlendFactor, dfactor: BlendFactor) -> Self {
Self {
sfactor,
dfactor,
alpha_sfactor: sfactor,
alpha_dfactor: dfactor,
}
}
pub fn new_separate(
sfactor: BlendFactor,
dfactor: BlendFactor,
alpha_sfactor: BlendFactor,
alpha_dfactor: BlendFactor,
) -> Self {
Self {
sfactor,
dfactor,
alpha_sfactor,
alpha_dfactor,
}
}
}
impl Default for BlendFunc {
fn default() -> Self {
Self {
sfactor: BlendFactor::One,
dfactor: BlendFactor::Zero,
alpha_sfactor: BlendFactor::One,
alpha_dfactor: BlendFactor::Zero,
}
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub struct ColorMask {
pub red: bool,
pub green: bool,
pub blue: bool,
pub alpha: bool,
}
impl Default for ColorMask {
fn default() -> Self {
Self {
red: true,
green: true,
blue: true,
alpha: true,
}
}
}
impl ColorMask {
pub fn all(value: bool) -> Self {
Self {
red: value,
green: value,
blue: value,
alpha: value,
}
}
}
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Hash,
Debug,
Deserialize,
Visit,
Eq,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum PolygonFace {
Front,
Back,
FrontAndBack,
}
impl Default for PolygonFace {
fn default() -> Self {
Self::FrontAndBack
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub struct StencilFunc {
pub func: CompareFunc,
pub ref_value: u32,
pub mask: u32,
}
impl Default for StencilFunc {
fn default() -> Self {
Self {
func: CompareFunc::Always,
ref_value: 0,
mask: 0xFFFF_FFFF,
}
}
}
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Hash,
Debug,
Serialize,
Deserialize,
Visit,
Eq,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum StencilAction {
/// Keeps the current value.
Keep,
/// Sets the stencil buffer value to 0.
Zero,
/// Sets the stencil buffer value to ref value.
Replace,
/// Increments the current stencil buffer value.
/// Clamps to the maximum representable unsigned value.
Incr,
/// Increments the current stencil buffer value.
/// Wraps stencil buffer value to zero when incrementing the maximum representable
/// unsigned value.
IncrWrap,
/// Decrements the current stencil buffer value.
/// Clamps to 0.
Decr,
/// Decrements the current stencil buffer value.
/// Wraps stencil buffer value to the maximum representable unsigned value when
/// decrementing a stencil buffer value of zero.
DecrWrap,
/// Bitwise inverts the current stencil buffer value.
Invert,
}
impl Default for StencilAction {
fn default() -> Self {
Self::Keep
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub struct StencilOp {
pub fail: StencilAction,
pub zfail: StencilAction,
pub zpass: StencilAction,
pub write_mask: u32,
}
impl Default for StencilOp {
fn default() -> Self {
Self {
fail: Default::default(),
zfail: Default::default(),
zpass: Default::default(),
write_mask: 0xFFFF_FFFF,
}
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub enum CullFace {
Back,
Front,
}
impl Default for CullFace {
fn default() -> Self {
Self::Back
}
}
#[derive(Serialize, Deserialize, Default, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
pub struct BlendParameters {
pub func: BlendFunc,
pub equation: BlendEquation,
}
#[derive(Serialize, Deserialize, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
pub struct DrawParameters {
pub cull_face: Option<CullFace>,
pub color_write: ColorMask,
pub depth_write: bool,
pub stencil_test: Option<StencilFunc>,
pub depth_test: bool,
pub blend: Option<BlendParameters>,
pub stencil_op: StencilOp,
}
impl Default for DrawParameters {
fn default() -> Self {
Self {
cull_face: Some(CullFace::Back),
color_write: Default::default(),
depth_write: true,
stencil_test: None,
depth_test: true,
blend: None,
stencil_op: Default::default(),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ElementRange {
Full,
Specific { offset: usize, count: usize },
}
impl Default for ElementRange {
fn default() -> Self {
Self::Full
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ElementKind {
Triangle,
Line,
Point,
}
impl ElementKind {
fn index_per_element(self) -> usize {
match self {
ElementKind::Triangle => 3,
ElementKind::Line => 2,
ElementKind::Point => 1,
}
}
}
@@ -20,12 +20,10 @@
use crate::{
core::{algebra::Vector2, array_as_u8_slice_mut, math::Rect},
renderer::framework::{
error::FrameworkError,
framebuffer::FrameBuffer,
gpu_texture::{image_2d_size_bytes, GpuTextureKind},
state::PipelineState,
},
error::FrameworkError,
framebuffer::FrameBuffer,
gpu_texture::{image_2d_size_bytes, GpuTextureKind},
state::PipelineState,
};
use bytemuck::Pod;
use glow::{HasContext, PixelPackData};
@@ -1,4 +1,4 @@
use crate::renderer::framework::{error::FrameworkError, state::PipelineState};
use crate::{error::FrameworkError, state::PipelineState};
use glow::HasContext;
use std::{cell::Cell, rc::Weak};
@@ -18,17 +18,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::{BlendFactor, BlendMode, StencilAction};
use crate::{
core::{color::Color, log::Log, math::Rect},
engine::{error::EngineError, GraphicsContextParams},
renderer::{
framework::{
error::FrameworkError, BlendEquation, BlendFunc, ColorMask, CompareFunc, CullFace,
DrawParameters, PolygonFace, PolygonFillMode, StencilFunc, StencilOp,
},
PipelineStatistics,
},
error::FrameworkError,
stats::PipelineStatistics,
BlendEquation, BlendFactor, BlendFunc, BlendMode, ColorMask, CompareFunc, CullFace,
DrawParameters, PolygonFace, PolygonFillMode, StencilAction, StencilFunc, StencilOp,
};
use glow::{Framebuffer, HasContext};
#[cfg(not(target_arch = "wasm32"))]
@@ -305,10 +300,11 @@ struct TextureUnitsStorage {
impl PipelineState {
pub fn new(
#[allow(unused_variables)] params: &GraphicsContextParams,
#[allow(unused_variables)] vsync: bool,
#[allow(unused_variables)] msaa_sample_count: Option<u8>,
window_target: &EventLoopWindowTarget<()>,
window_builder: WindowBuilder,
) -> Result<(Window, SharedPipelineState), EngineError> {
) -> Result<(Window, SharedPipelineState), FrameworkError> {
#[cfg(not(target_arch = "wasm32"))]
let (window, gl_context, gl_surface, mut context, gl_kind) = {
let mut template = ConfigTemplateBuilder::new()
@@ -316,7 +312,7 @@ impl PipelineState {
.with_stencil_size(8)
.with_depth_size(24);
if let Some(sample_count) = params.msaa_sample_count {
if let Some(sample_count) = msaa_sample_count {
template = template.with_multisampling(sample_count);
}
@@ -370,7 +366,7 @@ impl PipelineState {
let gl_context = non_current_gl_context.make_current(&gl_surface)?;
if params.vsync {
if vsync {
Log::verify(gl_surface.set_swap_interval(
&gl_context,
SwapInterval::Wait(NonZeroU32::new(1).unwrap()),
@@ -391,12 +387,12 @@ impl PipelineState {
#[cfg(target_arch = "wasm32")]
let (window, mut context, gl_kind) = {
use crate::{
core::wasm_bindgen::JsCast,
use crate::core::wasm_bindgen::JsCast;
use serde::{Deserialize, Serialize};
use winit::{
dpi::{LogicalSize, PhysicalSize},
platform::web::WindowExtWebSys,
};
use serde::{Deserialize, Serialize};
let inner_size = window_builder.window_attributes().inner_size;
let window = window_builder.build(window_target).unwrap();
+121
View File
@@ -0,0 +1,121 @@
// 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::DrawCallStatistics;
use std::fmt::{Display, Formatter};
/// Graphics pipeline statistics.
#[derive(Debug, Default, Copy, Clone)]
pub struct PipelineStatistics {
/// Total amount of texture that was bound to the pipeline during the rendering.
pub texture_binding_changes: usize,
/// Total amount of VBOs was bound to the pipeline during the rendering.
pub vbo_binding_changes: usize,
/// Total amount of VAOs was bound to the pipeline during the rendering.
pub vao_binding_changes: usize,
/// Total amount of blending state changed in the pipeline during the rendering.
pub blend_state_changes: usize,
/// Total amount of frame buffers was used during the rendering.
pub framebuffer_binding_changes: usize,
/// Total amount of programs was used in the pipeline during the rendering.
pub program_binding_changes: usize,
}
impl std::ops::AddAssign for PipelineStatistics {
fn add_assign(&mut self, rhs: Self) {
self.texture_binding_changes += rhs.texture_binding_changes;
self.vbo_binding_changes += rhs.vbo_binding_changes;
self.vao_binding_changes += rhs.vao_binding_changes;
self.blend_state_changes += rhs.blend_state_changes;
self.framebuffer_binding_changes += rhs.framebuffer_binding_changes;
self.program_binding_changes += rhs.program_binding_changes;
}
}
impl std::ops::Sub for PipelineStatistics {
type Output = PipelineStatistics;
fn sub(self, rhs: Self) -> Self::Output {
Self {
texture_binding_changes: self.texture_binding_changes - rhs.texture_binding_changes,
vbo_binding_changes: self.vbo_binding_changes - rhs.vbo_binding_changes,
vao_binding_changes: self.vao_binding_changes - rhs.vao_binding_changes,
blend_state_changes: self.blend_state_changes - rhs.blend_state_changes,
framebuffer_binding_changes: self.framebuffer_binding_changes
- rhs.framebuffer_binding_changes,
program_binding_changes: self.program_binding_changes - rhs.program_binding_changes,
}
}
}
impl Display for PipelineStatistics {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Pipeline state changes:\n\
\tTextures: {},\n\
\tVBO: {},\n\
\tVAO: {},\n\
\tFBO: {},\n\
\tShaders: {},\n\
\tBlend: {}",
self.texture_binding_changes,
self.vbo_binding_changes,
self.vao_binding_changes,
self.framebuffer_binding_changes,
self.program_binding_changes,
self.blend_state_changes
)
}
}
/// GPU statistics for single frame.
#[derive(Debug, Copy, Clone, Default)]
pub struct RenderPassStatistics {
/// Amount of draw calls per frame - lower the better.
pub draw_calls: usize,
/// Amount of triangles per frame.
pub triangles_rendered: usize,
}
impl Display for RenderPassStatistics {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Draw Calls: {}\n\
Triangles Rendered: {}",
self.draw_calls, self.triangles_rendered
)
}
}
impl std::ops::AddAssign for RenderPassStatistics {
fn add_assign(&mut self, rhs: Self) {
self.draw_calls += rhs.draw_calls;
self.triangles_rendered += rhs.triangles_rendered;
}
}
impl std::ops::AddAssign<DrawCallStatistics> for RenderPassStatistics {
fn add_assign(&mut self, rhs: DrawCallStatistics) {
self.draw_calls += 1;
self.triangles_rendered += rhs.triangles;
}
}
+4 -4
View File
@@ -22,6 +22,7 @@ fyrox-ui = { path = "../fyrox-ui", version = "0.25.1" }
fyrox-resource = { path = "../fyrox-resource", version = "0.12.0" }
fyrox-animation = { path = "../fyrox-animation", version = "0.2.0" }
fyrox-graph = { path = "../fyrox-graph", version = "0.1.0" }
fyrox-graphics = { path = "../fyrox-graphics", version = "0.1.0" }
rapier2d = { version = "0.20", features = ["debug-render"] }
rapier3d = { version = "0.20", features = ["debug-render"] }
image = { version = "0.25.1", default-features = false, features = ["gif", "jpeg", "png", "tga", "tiff", "bmp"] }
@@ -32,7 +33,7 @@ ddsfile = "0.5.0"
rayon = "1.5.1"
tbc = "0.3.0"
bitflags = "2.2.1"
glow = "0.13.1"
glow = "0.14.1"
walkdir = "2.3.2"
ron = "0.8.0"
fxhash = "0.2.1"
@@ -47,7 +48,7 @@ uvgen = "0.1.0"
lightmap = "0.1.1"
libloading = "0.8.1"
gltf = { version = "1.4.0", optional = true, default-features = false, features = ["names", "utils"] }
bytemuck = { version = "1.16.1", features = ["derive"]}
bytemuck = { version = "1.16.1", features = ["derive"] }
# These dependencies isn't actually used by the engine, but it is needed to prevent cargo from rebuilding
# the engine lib on different packages.
hashbrown = { version = "0.14.3", features = ["raw"] }
@@ -63,8 +64,7 @@ glutin = "0.31"
glutin-winit = "0.4.2"
raw-window-handle = "0.5.0"
[target.'cfg(target_arch = "wasm32")'.dependencies]
serde-wasm-bindgen = "0.6.3"
[target.'cfg(target_os = "android")'.dependencies]
winit = { version = "0.29.2", features = ["android-native-activity"] }
+1
View File
@@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
renderer::{
cache::{TemporaryCache, TimeToLive},
+163 -422
View File
@@ -18,450 +18,191 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#![allow(missing_docs)] // TODO
//! Rendering framework.
use crate::core::{reflect::prelude::*, type_traits::prelude::*, visitor::prelude::*};
use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, EnumString, VariantNames};
use crate::{
resource::texture::{
TextureKind, TextureMagnificationFilter, TextureMinificationFilter, TexturePixelKind,
TextureWrapMode,
},
scene::mesh::{
buffer::{VertexAttributeDataType, VertexBuffer},
surface::SurfaceData,
},
};
pub use fyrox_graphics::*;
use fyrox_graphics::{
error::FrameworkError,
geometry_buffer::{
AttributeDefinition, AttributeKind, BufferBuilder, GeometryBuffer, GeometryBufferBuilder,
GeometryBufferKind,
},
gpu_texture::{GpuTextureKind, MagnificationFilter, MinificationFilter, PixelKind, WrapMode},
state::PipelineState,
};
pub mod error;
pub mod framebuffer;
pub mod geometry_buffer;
pub mod gpu_program;
pub mod gpu_texture;
pub mod pixel_buffer;
pub mod query;
pub mod state;
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Hash,
Debug,
Deserialize,
Visit,
Eq,
Reflect,
AsRefStr,
EnumString,
VariantNames,
TypeUuidProvider,
)]
#[type_uuid(id = "47aff01a-7daa-427c-874c-87464a7ffe28")]
pub enum PolygonFillMode {
Point,
Line,
Fill,
}
impl Default for PolygonFillMode {
fn default() -> Self {
Self::Fill
impl From<TextureKind> for GpuTextureKind {
fn from(v: TextureKind) -> Self {
match v {
TextureKind::Line { length } => GpuTextureKind::Line {
length: length as usize,
},
TextureKind::Rectangle { width, height } => GpuTextureKind::Rectangle {
width: width as usize,
height: height as usize,
},
TextureKind::Cube { width, height } => GpuTextureKind::Cube {
width: width as usize,
height: height as usize,
},
TextureKind::Volume {
width,
height,
depth,
} => GpuTextureKind::Volume {
width: width as usize,
height: height as usize,
depth: depth as usize,
},
}
}
}
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Eq,
Ord,
Hash,
Visit,
Serialize,
Deserialize,
Debug,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum CompareFunc {
/// Never passes.
Never,
/// Passes if the incoming value is less than the stored value.
Less,
/// Passes if the incoming value is equal to the stored value.
Equal,
/// Passes if the incoming value is less than or equal to the stored value.
LessOrEqual,
/// Passes if the incoming value is greater than the stored value.
Greater,
/// Passes if the incoming value is not equal to the stored value.
NotEqual,
/// Passes if the incoming value is greater than or equal to the stored value.
GreaterOrEqual,
/// Always passes.
Always,
}
impl Default for CompareFunc {
fn default() -> Self {
Self::LessOrEqual
impl From<TexturePixelKind> for PixelKind {
fn from(texture_kind: TexturePixelKind) -> Self {
match texture_kind {
TexturePixelKind::R8 => Self::R8,
TexturePixelKind::RGB8 => Self::RGB8,
TexturePixelKind::RGBA8 => Self::RGBA8,
TexturePixelKind::RG8 => Self::RG8,
TexturePixelKind::R16 => Self::R16,
TexturePixelKind::RG16 => Self::RG16,
TexturePixelKind::BGR8 => Self::BGR8,
TexturePixelKind::BGRA8 => Self::BGRA8,
TexturePixelKind::RGB16 => Self::RGB16,
TexturePixelKind::RGBA16 => Self::RGBA16,
TexturePixelKind::RGB16F => Self::RGB16F,
TexturePixelKind::DXT1RGB => Self::DXT1RGB,
TexturePixelKind::DXT1RGBA => Self::DXT1RGBA,
TexturePixelKind::DXT3RGBA => Self::DXT3RGBA,
TexturePixelKind::DXT5RGBA => Self::DXT5RGBA,
TexturePixelKind::R8RGTC => Self::R8RGTC,
TexturePixelKind::RG8RGTC => Self::RG8RGTC,
TexturePixelKind::RGB32F => Self::RGB32F,
TexturePixelKind::RGBA32F => Self::RGBA32F,
TexturePixelKind::Luminance8 => Self::L8,
TexturePixelKind::LuminanceAlpha8 => Self::LA8,
TexturePixelKind::Luminance16 => Self::L16,
TexturePixelKind::LuminanceAlpha16 => Self::LA16,
TexturePixelKind::R32F => Self::R32F,
TexturePixelKind::R16F => Self::R16F,
}
}
}
#[derive(
Copy,
Clone,
Hash,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
Visit,
Debug,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum BlendFactor {
Zero,
One,
SrcColor,
OneMinusSrcColor,
DstColor,
OneMinusDstColor,
SrcAlpha,
OneMinusSrcAlpha,
DstAlpha,
OneMinusDstAlpha,
ConstantColor,
OneMinusConstantColor,
ConstantAlpha,
OneMinusConstantAlpha,
SrcAlphaSaturate,
Src1Color,
OneMinusSrc1Color,
Src1Alpha,
OneMinusSrc1Alpha,
}
impl Default for BlendFactor {
fn default() -> Self {
Self::Zero
impl From<TextureMagnificationFilter> for MagnificationFilter {
fn from(v: TextureMagnificationFilter) -> Self {
match v {
TextureMagnificationFilter::Nearest => Self::Nearest,
TextureMagnificationFilter::Linear => Self::Linear,
}
}
}
#[derive(
Copy, Clone, Hash, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize, Visit, Debug, Reflect,
)]
pub enum BlendMode {
Add,
Subtract,
ReverseSubtract,
Min,
Max,
}
impl Default for BlendMode {
fn default() -> Self {
Self::Add
impl From<TextureMinificationFilter> for MinificationFilter {
fn from(v: TextureMinificationFilter) -> Self {
match v {
TextureMinificationFilter::Nearest => Self::Nearest,
TextureMinificationFilter::NearestMipMapNearest => Self::NearestMipMapNearest,
TextureMinificationFilter::NearestMipMapLinear => Self::NearestMipMapLinear,
TextureMinificationFilter::Linear => Self::Linear,
TextureMinificationFilter::LinearMipMapNearest => Self::LinearMipMapNearest,
TextureMinificationFilter::LinearMipMapLinear => Self::LinearMipMapLinear,
}
}
}
#[derive(
Copy,
Clone,
Default,
PartialOrd,
PartialEq,
Ord,
Eq,
Hash,
Serialize,
Deserialize,
Visit,
Debug,
Reflect,
)]
pub struct BlendEquation {
pub rgb: BlendMode,
pub alpha: BlendMode,
impl From<TextureWrapMode> for WrapMode {
fn from(v: TextureWrapMode) -> Self {
match v {
TextureWrapMode::Repeat => WrapMode::Repeat,
TextureWrapMode::ClampToEdge => WrapMode::ClampToEdge,
TextureWrapMode::ClampToBorder => WrapMode::ClampToBorder,
TextureWrapMode::MirroredRepeat => WrapMode::MirroredRepeat,
TextureWrapMode::MirrorClampToEdge => WrapMode::MirrorClampToEdge,
}
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Serialize, Deserialize, Visit, Debug, Reflect,
)]
pub struct BlendFunc {
pub sfactor: BlendFactor,
pub dfactor: BlendFactor,
pub alpha_sfactor: BlendFactor,
pub alpha_dfactor: BlendFactor,
/// Extension trait for [`BufferBuilder`].
pub trait BufferBuilderExt {
/// Creates [`BufferBuilder`] from a [`VertexBuffer`].
fn from_vertex_buffer(buffer: &VertexBuffer, kind: GeometryBufferKind) -> Self;
}
impl BlendFunc {
pub fn new(sfactor: BlendFactor, dfactor: BlendFactor) -> Self {
impl BufferBuilderExt for BufferBuilder {
fn from_vertex_buffer(buffer: &VertexBuffer, kind: GeometryBufferKind) -> Self {
Self {
sfactor,
dfactor,
alpha_sfactor: sfactor,
alpha_dfactor: dfactor,
}
}
pub fn new_separate(
sfactor: BlendFactor,
dfactor: BlendFactor,
alpha_sfactor: BlendFactor,
alpha_dfactor: BlendFactor,
) -> Self {
Self {
sfactor,
dfactor,
alpha_sfactor,
alpha_dfactor,
element_size: buffer.vertex_size() as usize,
kind,
attributes: buffer
.layout()
.iter()
.map(|a| AttributeDefinition {
location: a.shader_location as u32,
kind: match (a.data_type, a.size) {
(VertexAttributeDataType::F32, 1) => AttributeKind::Float,
(VertexAttributeDataType::F32, 2) => AttributeKind::Float2,
(VertexAttributeDataType::F32, 3) => AttributeKind::Float3,
(VertexAttributeDataType::F32, 4) => AttributeKind::Float4,
(VertexAttributeDataType::U32, 1) => AttributeKind::UnsignedInt,
(VertexAttributeDataType::U32, 2) => AttributeKind::UnsignedInt2,
(VertexAttributeDataType::U32, 3) => AttributeKind::UnsignedInt3,
(VertexAttributeDataType::U32, 4) => AttributeKind::UnsignedInt4,
(VertexAttributeDataType::U16, 1) => AttributeKind::UnsignedShort,
(VertexAttributeDataType::U16, 2) => AttributeKind::UnsignedShort2,
(VertexAttributeDataType::U16, 3) => AttributeKind::UnsignedShort3,
(VertexAttributeDataType::U16, 4) => AttributeKind::UnsignedShort4,
(VertexAttributeDataType::U8, 1) => AttributeKind::UnsignedByte,
(VertexAttributeDataType::U8, 2) => AttributeKind::UnsignedByte2,
(VertexAttributeDataType::U8, 3) => AttributeKind::UnsignedByte3,
(VertexAttributeDataType::U8, 4) => AttributeKind::UnsignedByte4,
_ => unreachable!(),
},
normalized: a.normalized,
divisor: a.divisor as u32,
})
.collect(),
data: buffer.raw_data().as_ptr(),
data_size: buffer.raw_data().len(),
}
}
}
impl Default for BlendFunc {
fn default() -> Self {
Self {
sfactor: BlendFactor::One,
dfactor: BlendFactor::Zero,
alpha_sfactor: BlendFactor::One,
alpha_dfactor: BlendFactor::Zero,
}
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub struct ColorMask {
pub red: bool,
pub green: bool,
pub blue: bool,
pub alpha: bool,
}
impl Default for ColorMask {
fn default() -> Self {
Self {
red: true,
green: true,
blue: true,
alpha: true,
}
}
}
impl ColorMask {
pub fn all(value: bool) -> Self {
Self {
red: value,
green: value,
blue: value,
alpha: value,
}
}
}
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Hash,
Debug,
Deserialize,
Visit,
Eq,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum PolygonFace {
Front,
Back,
FrontAndBack,
}
impl Default for PolygonFace {
fn default() -> Self {
Self::FrontAndBack
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub struct StencilFunc {
pub func: CompareFunc,
pub ref_value: u32,
pub mask: u32,
}
impl Default for StencilFunc {
fn default() -> Self {
Self {
func: CompareFunc::Always,
ref_value: 0,
mask: 0xFFFF_FFFF,
}
}
}
#[derive(
Copy,
Clone,
PartialOrd,
PartialEq,
Hash,
Debug,
Serialize,
Deserialize,
Visit,
Eq,
Reflect,
AsRefStr,
EnumString,
VariantNames,
)]
pub enum StencilAction {
/// Keeps the current value.
Keep,
/// Sets the stencil buffer value to 0.
Zero,
/// Sets the stencil buffer value to ref value.
Replace,
/// Increments the current stencil buffer value.
/// Clamps to the maximum representable unsigned value.
Incr,
/// Increments the current stencil buffer value.
/// Wraps stencil buffer value to zero when incrementing the maximum representable
/// unsigned value.
IncrWrap,
/// Decrements the current stencil buffer value.
/// Clamps to 0.
Decr,
/// Decrements the current stencil buffer value.
/// Wraps stencil buffer value to the maximum representable unsigned value when
/// decrementing a stencil buffer value of zero.
DecrWrap,
/// Bitwise inverts the current stencil buffer value.
Invert,
}
impl Default for StencilAction {
fn default() -> Self {
Self::Keep
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub struct StencilOp {
pub fail: StencilAction,
pub zfail: StencilAction,
pub zpass: StencilAction,
pub write_mask: u32,
}
impl Default for StencilOp {
fn default() -> Self {
Self {
fail: Default::default(),
zfail: Default::default(),
zpass: Default::default(),
write_mask: 0xFFFF_FFFF,
}
}
}
#[derive(
Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
)]
pub enum CullFace {
Back,
Front,
}
impl Default for CullFace {
fn default() -> Self {
Self::Back
}
}
#[derive(Serialize, Deserialize, Default, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
pub struct BlendParameters {
pub func: BlendFunc,
pub equation: BlendEquation,
}
#[derive(Serialize, Deserialize, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
pub struct DrawParameters {
pub cull_face: Option<CullFace>,
pub color_write: ColorMask,
pub depth_write: bool,
pub stencil_test: Option<StencilFunc>,
pub depth_test: bool,
pub blend: Option<BlendParameters>,
pub stencil_op: StencilOp,
}
impl Default for DrawParameters {
fn default() -> Self {
Self {
cull_face: Some(CullFace::Back),
color_write: Default::default(),
depth_write: true,
stencil_test: None,
depth_test: true,
blend: None,
stencil_op: Default::default(),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ElementRange {
Full,
Specific { offset: usize, count: usize },
}
impl Default for ElementRange {
fn default() -> Self {
Self::Full
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ElementKind {
Triangle,
Line,
Point,
}
impl ElementKind {
fn index_per_element(self) -> usize {
match self {
ElementKind::Triangle => 3,
ElementKind::Line => 2,
ElementKind::Point => 1,
}
/// Extension trait for [`GeometryBuffer`].
pub trait GeometryBufferExt: Sized {
/// Creates [`GeometryBuffer`] from [`SurfaceData`].
fn from_surface_data(
data: &SurfaceData,
kind: GeometryBufferKind,
state: &PipelineState,
) -> Result<Self, FrameworkError>;
}
impl GeometryBufferExt for GeometryBuffer {
fn from_surface_data(
data: &SurfaceData,
kind: GeometryBufferKind,
state: &PipelineState,
) -> Result<Self, FrameworkError> {
let geometry_buffer = GeometryBufferBuilder::new(ElementKind::Triangle)
.with_buffer_builder(BufferBuilder::from_vertex_buffer(&data.vertex_buffer, kind))
.build(state)?;
geometry_buffer
.bind(state)
.set_triangles(data.geometry_buffer.triangles_ref());
Ok(geometry_buffer)
}
}
+1
View File
@@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
core::{
algebra::{Matrix4, Vector2, Vector3},
+1
View File
@@ -29,6 +29,7 @@
//! Every alpha channel is used for layer blending for terrains. This is inefficient, but for
//! now I don't know better solution.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
core::{
algebra::{Matrix4, Vector2},
+1
View File
@@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
core::{
algebra::{Matrix4, Point3, UnitQuaternion, Vector2, Vector3},
+1
View File
@@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
core::{
algebra::{Isometry3, Matrix4, Point3, Translation, Vector3},
+7 -3
View File
@@ -29,8 +29,6 @@
#![warn(missing_docs)]
#![deny(unsafe_code)]
// Framework is 100% unsafe internally due to FFI calls.
#[allow(unsafe_code)]
pub mod framework;
pub mod bundle;
@@ -54,6 +52,7 @@ mod skybox_shader;
mod ssao;
mod stats;
use crate::renderer::framework::GeometryBufferExt;
use crate::{
asset::{event::ResourceEvent, manager::ResourceManager},
core::{
@@ -942,7 +941,12 @@ impl Renderer {
.event_broadcaster
.add(shader_event_sender);
let (window, state) = PipelineState::new(params, window_target, window_builder)?;
let (window, state) = PipelineState::new(
params.vsync,
params.msaa_sample_count,
window_target,
window_builder,
)?;
let frame_size = (window.inner_size().width, window.inner_size().height);
+1
View File
@@ -23,6 +23,7 @@
mod grid;
mod optimizer;
use crate::renderer::framework::GeometryBufferExt;
use crate::renderer::occlusion::grid::{GridCache, Visibility};
use crate::{
core::{
+1
View File
@@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
core::{math::Rect, sstorage::ImmutableString},
renderer::{
+1
View File
@@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::renderer::framework::GeometryBufferExt;
use crate::{
core::{
algebra::{Matrix3, Matrix4, Vector2, Vector3},
+1 -99
View File
@@ -20,74 +20,10 @@
use crate::renderer::framework::geometry_buffer::DrawCallStatistics;
use fyrox_core::instant;
pub use fyrox_graphics::stats::*;
use std::fmt::{Display, Formatter};
use std::ops::AddAssign;
/// Graphics pipeline statistics.
#[derive(Debug, Default, Copy, Clone)]
pub struct PipelineStatistics {
/// Total amount of texture that was bound to the pipeline during the rendering.
pub texture_binding_changes: usize,
/// Total amount of VBOs was bound to the pipeline during the rendering.
pub vbo_binding_changes: usize,
/// Total amount of VAOs was bound to the pipeline during the rendering.
pub vao_binding_changes: usize,
/// Total amount of blending state changed in the pipeline during the rendering.
pub blend_state_changes: usize,
/// Total amount of frame buffers was used during the rendering.
pub framebuffer_binding_changes: usize,
/// Total amount of programs was used in the pipeline during the rendering.
pub program_binding_changes: usize,
}
impl std::ops::AddAssign for PipelineStatistics {
fn add_assign(&mut self, rhs: Self) {
self.texture_binding_changes += rhs.texture_binding_changes;
self.vbo_binding_changes += rhs.vbo_binding_changes;
self.vao_binding_changes += rhs.vao_binding_changes;
self.blend_state_changes += rhs.blend_state_changes;
self.framebuffer_binding_changes += rhs.framebuffer_binding_changes;
self.program_binding_changes += rhs.program_binding_changes;
}
}
impl std::ops::Sub for PipelineStatistics {
type Output = PipelineStatistics;
fn sub(self, rhs: Self) -> Self::Output {
Self {
texture_binding_changes: self.texture_binding_changes - rhs.texture_binding_changes,
vbo_binding_changes: self.vbo_binding_changes - rhs.vbo_binding_changes,
vao_binding_changes: self.vao_binding_changes - rhs.vao_binding_changes,
blend_state_changes: self.blend_state_changes - rhs.blend_state_changes,
framebuffer_binding_changes: self.framebuffer_binding_changes
- rhs.framebuffer_binding_changes,
program_binding_changes: self.program_binding_changes - rhs.program_binding_changes,
}
}
}
impl Display for PipelineStatistics {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Pipeline state changes:\n\
\tTextures: {},\n\
\tVBO: {},\n\
\tVAO: {},\n\
\tFBO: {},\n\
\tShaders: {},\n\
\tBlend: {}",
self.texture_binding_changes,
self.vbo_binding_changes,
self.vao_binding_changes,
self.framebuffer_binding_changes,
self.program_binding_changes,
self.blend_state_changes
)
}
}
/// Lighting statistics.
#[derive(Debug, Copy, Clone, Default)]
pub struct LightingStatistics {
@@ -247,40 +183,6 @@ impl Display for Statistics {
}
}
/// GPU statistics for single frame.
#[derive(Debug, Copy, Clone, Default)]
pub struct RenderPassStatistics {
/// Amount of draw calls per frame - lower the better.
pub draw_calls: usize,
/// Amount of triangles per frame.
pub triangles_rendered: usize,
}
impl Display for RenderPassStatistics {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Draw Calls: {}\n\
Triangles Rendered: {}",
self.draw_calls, self.triangles_rendered
)
}
}
impl std::ops::AddAssign for RenderPassStatistics {
fn add_assign(&mut self, rhs: Self) {
self.draw_calls += rhs.draw_calls;
self.triangles_rendered += rhs.triangles_rendered;
}
}
impl std::ops::AddAssign<DrawCallStatistics> for RenderPassStatistics {
fn add_assign(&mut self, rhs: DrawCallStatistics) {
self.draw_calls += 1;
self.triangles_rendered += rhs.triangles;
}
}
impl std::ops::AddAssign<RenderPassStatistics> for Statistics {
fn add_assign(&mut self, rhs: RenderPassStatistics) {
self.geometry += rhs;