Clarifying fyrox-graphics

This commit is contained in:
b-guild
2025-08-24 12:46:19 -07:00
parent 6983933dc2
commit c14a52a6e7
4 changed files with 269 additions and 20 deletions
+166 -17
View File
@@ -167,50 +167,122 @@ impl ToGlConstant for CullFace {
}
}
/// Indicator of whether we are using the embedded version of OpenGL.
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum GlKind {
/// The full Open Graphics Library, without restrictions for embedded systems.
OpenGL,
/// OpenGL for Embedded Systems is a subset of OpenGL designed for systems such as smartphones, tablet computers, and PDAs.
OpenGLES,
}
/// A representation of the state of the GL context. OpenGL keeps track of various flags and values internally,
/// and this struct remembers those settings. This makes it possible to check if a setting is actually being changed
/// when a new value is supplied, so we can avoid calling OpenGL functions unnecessarily.
///
/// For example: we can call [`GlGraphicsServer::set_clear_color`] multiple times with the same color, and it will not
/// result in repeated calls to the underlying `glClearColor` function because `GlGraphicsServer` will store the color
/// in its `InnerState` and avoid calling `glClearColor` when it would be redundant.
pub(crate) struct InnerState {
/// True if blending is currently enabled in the GL context due to a blending function being set in the [`DrawParameters`].
/// Protects `glEnable(GL_BLEND)` and `glDisable(GL_BLEND)`.
blend: bool,
/// True if depth testing is currently enabled in the GL contex due to a depth test function being set in [`DrawParameters`].
/// Protects `glEnable(GL_DEPTH_TEST)` and `glDisable(GL_DEPTH_TEST)`.
depth_test: bool,
/// True if depth mask is currently enabled in the GL context.
/// Protects `glDepthMask`.
depth_write: bool,
/// The depth test function currently set in the context, only to be used if `depth_test` is true.
/// Protects `glDepthFunc`.
depth_func: CompareFunc,
/// A mask that defines which colors will be stored in a frame buffer during rendering operation.
/// By default, all colors are stored (every field is set to `true`).
/// Protects `glColorMask`.
color_write: ColorMask,
/// True if stencil testing is currently enabled in the GL contex due to a stencil function being set in [`DrawParameters`].
/// Protects `glEnable(GL_STENCIL_TEST)` and `glDisable(GL_STENCIL_TEST)`.
stencil_test: bool,
/// Which side of the geometry is OpenGL set to cull?
/// Protects `glCullFace`.
cull_face: CullFace,
/// True if culling is enabled, with `cull_face` determining whether to cull the front or the back.
/// Protects `glEnable(GL_CULL_FACE)` and `glDisable(GL_CULL_FACE)`.
culling: bool,
stencil_mask: u32,
/// The color that GL will use when clearing color buffers.
/// Protects `glClearColor`.
clear_color: Color,
/// The stencil value that GL will use when clearing the stencil buffer.
/// Protects `glClearStencil`.
clear_stencil: i32,
/// The depth value that GL will use when clearing the depth buffer.
/// Protects `glClearDepth`.
clear_depth: f32,
/// True if OpenGL is limiting rendering to a specific rectangle.
/// The size and position of the rectangle is not stored in `InnerState`, but it is changed in
/// OpenGL by calling [`GlGraphicsServer::set_scissor_box`].
/// Protects `glEnable(GL_SCISSOR_TEST)` and `glDisable(GL_SCISSOR_TEST)`.
scissor_test: bool,
polygon_face: PolygonFace,
polygon_fill_mode: PolygonFillMode,
/// The fill mode for the front of polygons.
/// Protects `glPolygonMode`.
front_fill_mode: PolygonFillMode,
/// The fill mode for the back of polygons.
/// Protects `glPolygonMode`.
back_fill_mode: PolygonFillMode,
/// The identifier for the currently bound frame buffer for writing. Frame buffers in OpenGL are identified by numbers.
/// If there is a currently bound frame buffer for writing, then this will be that frame buffer's number.
/// Otherwise, this will be None.
/// Protects `glBindFramebuffer`.
write_framebuffer: Option<glow::Framebuffer>,
/// The identifier for the currently bound frame buffer for reading. Frame buffers in OpenGL are identified by numbers.
/// If there is a currently bound frame buffer for reading, then this will be that frame buffer's number.
/// Otherwise, this will be None.
/// Protects `glBindFramebuffer`.
read_framebuffer: Option<glow::Framebuffer>,
/// Protects `glViewport`.
viewport: Rect<i32>,
/// Protects `glBlendFuncSeparate`.
blend_func: BlendFunc,
/// Protects `glBlendEquationSeparate`.
blend_equation: BlendEquation,
/// Protects `glUseProgram`.
program: Option<glow::Program>,
/// Protects `glBindTexture` and `glActiveTexture`.
texture_units_storage: TextureUnitsStorage,
/// Similar to `depth_func`, this controls how the stencil buffer will determine which fragments to draw.
/// Protects `glStencilFunc`.
stencil_func: StencilFunc,
/// A set of actions that will be performed with the stencil buffer during various testing stages.
/// `stencil_mask` can limit which bits of the stencil buffer are affected.
/// Protects `glStencilOp` and `glStencilMask`.
stencil_op: StencilOp,
/// Protects `glBindVertexArray`.
vao: Option<glow::VertexArray>,
/// Counts of various rendering operations.
frame_statistics: PipelineStatistics,
/// Indicator of whether we are using the embedded version of OpenGL.
gl_kind: GlKind,
/// A pool of available query identifiers for use by [`GlQuery`].
/// Each time a `GlQuery` is created, it checks this list for unused query identifies and pops off
/// the last one to use, or it creates a new query if the list is empty. When `GlQuery` is dropped,
/// it returns its query identifier to this list.
///
/// Each query corresponds to some count that is recorded during rendering, such as the number of
/// sambles that pass the depth check or the number of primitives that are generated.
/// The only query types that are supported by Fyrox are given in `QueryKind` in the fyrox-graphics crate.
///
/// Once the rendering commands have been sent, we may use the query identifier to wait until the
/// rendering is finished the desired number is available.
pub(crate) queries: Vec<glow::Query>,
#[cfg(not(target_arch = "wasm32"))]
@@ -234,13 +306,12 @@ impl InnerState {
stencil_test: false,
cull_face: CullFace::Back,
culling: false,
stencil_mask: 0xFFFF_FFFF,
clear_color: Color::from_rgba(0, 0, 0, 0),
clear_stencil: 0,
clear_depth: 1.0,
scissor_test: false,
polygon_face: Default::default(),
polygon_fill_mode: Default::default(),
front_fill_mode: PolygonFillMode::default(),
back_fill_mode: PolygonFillMode::default(),
read_framebuffer: None,
write_framebuffer: None,
blend_func: Default::default(),
@@ -335,6 +406,10 @@ impl InnerState {
}
}
/// Bind the texture with the given identifier to the given target in the given unit.
/// Target numbers can be found using [`ToGlConstant::into_gl`] on `GpuTextureKind` from the `fyrox-graphics` crate.
/// The given unit will be activated if it is not already active.
/// If a texture is already bound in the unit, it will be unbound.
pub(crate) fn set_texture(
&mut self,
unit_index: u32,
@@ -428,17 +503,32 @@ impl InnerState {
}
}
/// A frame buffer can be bound for reading, writing, or both.
pub enum FrameBufferBindingPoint {
Read,
Write,
ReadWrite,
}
/// `GlGraphicsServer` implements the [`GraphicsServer`] trait using the `glow` crate.
/// `glow` is "GL on Whatever: a set of bindings to run GL anywhere (Open GL, OpenGL ES, and WebGL) and avoid target-specific code."
pub struct GlGraphicsServer {
/// `glow::Context` provides access to the current rendering state.
/// It creates buffers, creates textures, compiles shaders, accepts geometry data,
/// and broadly provides access too all sorts of rendering services.
pub gl: glow::Context,
/// Controls whether objects the `glow::Context::object_label` method should be used
/// to assign labels to rendering objects. These labels can help with debugging.
pub named_objects: Cell<bool>,
/// A representation of the state of the GL context. OpenGL keeps track of various flags and values internally,
/// and this struct remembers those settings. This makes it possible to check if a setting is actually being changed
/// when a new value is supplied, so we can avoid calling OpenGL functions unnecessarily.
pub(crate) state: RefCell<InnerState>,
/// Contains information about used memory per each category of GPU resource.
pub(crate) memory_usage: RefCell<ServerMemoryUsage>,
/// A weak reference to the `Rc` that contains this server.
/// This is needed in order to convert a borrow of this server into an `Rc` reference of
/// this server, for implementing [`GlGraphicsServer::weak`] and [`GraphicsServer::weak`].
this: RefCell<Option<Weak<GlGraphicsServer>>>,
}
@@ -448,12 +538,20 @@ struct TextureBinding {
texture: Option<glow::Texture>,
}
/// A record of which texture is bound to each target.
/// There is one binding for each of the texture targets
/// defined by `GpuTextureKind` in the `fyrox-graphics` crate.
/// It is forbidden to have multiple targets bound at once in any unit,
/// and [`GlGraphicsServer::set_texture`] enforces this by automatically unbinding other targets.
#[derive(Copy, Clone)]
struct TextureUnit {
bindings: [TextureBinding; 4],
}
impl Default for TextureUnit {
/// Initialize the array of texture bindings with the valid target
/// values that can be produced by [`ToGlConstant::into_gl`] on `GpuTextureKind`
/// in the `fyrox-graphics` crate.
fn default() -> Self {
Self {
bindings: [
@@ -478,9 +576,12 @@ impl Default for TextureUnit {
}
}
/// A record of every texture binding in every unit and the currently active unit.
#[derive(Default)]
struct TextureUnitsStorage {
/// The currently active texture unit, as set by `glActiveTexture`.
active_unit: u32,
/// The textures that are bound to each target in each texture unit.
units: [TextureUnit; 32],
}
@@ -769,14 +870,17 @@ impl GlGraphicsServer {
Ok((window, shared))
}
/// A weak reference to the `Rc` where the server is stored.
pub fn weak(&self) -> Weak<Self> {
self.this.borrow().as_ref().unwrap().clone()
}
/// Determine if we are using the embedded version of OpenGL.
pub fn gl_kind(&self) -> GlKind {
self.state.borrow().gl_kind
}
/// Find the number of a texture unit where no texture is bound, if possible.
pub fn free_texture_unit(&self) -> Option<u32> {
let state = self.state.borrow();
for (index, unit) in state.texture_units_storage.units.iter().enumerate() {
@@ -791,12 +895,14 @@ impl GlGraphicsServer {
None
}
/// `glDeleteFramebuffers`
pub(crate) fn delete_framebuffer(&self, framebuffer: Option<glow::Framebuffer>) {
self.state
.borrow_mut()
.delete_framebuffer(framebuffer, &self.gl)
}
/// `glBindFramebuffer`
pub(crate) fn set_framebuffer(
&self,
binding_point: FrameBufferBindingPoint,
@@ -807,6 +913,7 @@ impl GlGraphicsServer {
.set_framebuffer(binding_point, framebuffer, &self.gl)
}
/// `glViewport`
pub(crate) fn set_viewport(&self, viewport: Rect<i32>) {
let mut state = self.state.borrow_mut();
if state.viewport != viewport {
@@ -823,6 +930,7 @@ impl GlGraphicsServer {
}
}
/// 'glEnable(GL_BLEND)` or `glDisable(GL_BLEND)`
pub(crate) fn set_blend(&self, blend: bool) {
let mut state = self.state.borrow_mut();
if state.blend != blend {
@@ -840,6 +948,7 @@ impl GlGraphicsServer {
}
}
/// `glEnable(GL_DEPTH_TEST)` or `glDisable(GL_DEPTH_TEST)`.
pub(crate) fn set_depth_test(&self, depth_test: bool) {
let mut state = self.state.borrow_mut();
if state.depth_test != depth_test {
@@ -855,6 +964,7 @@ impl GlGraphicsServer {
}
}
/// `glDepthMask`
pub(crate) fn set_depth_write(&self, depth_write: bool) {
let mut state = self.state.borrow_mut();
if state.depth_write != depth_write {
@@ -866,6 +976,7 @@ impl GlGraphicsServer {
}
}
/// `glColorMask`
pub(crate) fn set_color_write(&self, color_write: ColorMask) {
let mut state = self.state.borrow_mut();
if state.color_write != color_write {
@@ -882,6 +993,7 @@ impl GlGraphicsServer {
}
}
/// `glEnable(GL_STENCIL_TEST)` or `glDisable(GL_STENCIL_TEST)`.
pub(crate) fn set_stencil_test(&self, stencil_test: bool) {
let mut state = self.state.borrow_mut();
if state.stencil_test != stencil_test {
@@ -897,6 +1009,7 @@ impl GlGraphicsServer {
}
}
/// `glCullFace`
pub(crate) fn set_cull_face(&self, cull_face: CullFace) {
let mut state = self.state.borrow_mut();
if state.cull_face != cull_face {
@@ -906,6 +1019,7 @@ impl GlGraphicsServer {
}
}
/// `glEnable(GL_CULL_FACE)` or `glDisable(GL_CULL_FACE)`.
pub(crate) fn set_culling(&self, culling: bool) {
let mut state = self.state.borrow_mut();
if state.culling != culling {
@@ -921,10 +1035,11 @@ impl GlGraphicsServer {
}
}
/// `glStencilMask`
pub(crate) fn set_stencil_mask(&self, stencil_mask: u32) {
let mut state = self.state.borrow_mut();
if state.stencil_mask != stencil_mask {
state.stencil_mask = stencil_mask;
if state.stencil_op.write_mask != stencil_mask {
state.stencil_op.write_mask = stencil_mask;
unsafe {
self.gl.stencil_mask(stencil_mask);
@@ -932,6 +1047,7 @@ impl GlGraphicsServer {
}
}
/// `glClearColor`. Set the color used when clearing a color buffer.
pub(crate) fn set_clear_color(&self, color: Color) {
let mut state = self.state.borrow_mut();
if state.clear_color != color {
@@ -944,6 +1060,7 @@ impl GlGraphicsServer {
}
}
/// `glClearDepth`. Set the depth used when clearing a depth buffer.
pub(crate) fn set_clear_depth(&self, depth: f32) {
let mut state = self.state.borrow_mut();
if (state.clear_depth - depth).abs() > f32::EPSILON {
@@ -955,6 +1072,7 @@ impl GlGraphicsServer {
}
}
/// `glClearStencil`. Set the value used when clearing a stencil buffer.
pub(crate) fn set_clear_stencil(&self, stencil: i32) {
let mut state = self.state.borrow_mut();
if state.clear_stencil != stencil {
@@ -966,6 +1084,7 @@ impl GlGraphicsServer {
}
}
/// `glBlendFuncSeparate`
pub(crate) fn set_blend_func(&self, func: BlendFunc) {
let mut state = self.state.borrow_mut();
if state.blend_func != func {
@@ -982,6 +1101,7 @@ impl GlGraphicsServer {
}
}
/// `glBlendEquationSeparate`
pub(crate) fn set_blend_equation(&self, equation: BlendEquation) {
let mut state = self.state.borrow_mut();
if state.blend_equation != equation {
@@ -996,6 +1116,7 @@ impl GlGraphicsServer {
}
}
/// `glDepthFunc`
pub(crate) fn set_depth_func(&self, depth_func: CompareFunc) {
let mut state = self.state.borrow_mut();
if state.depth_func != depth_func {
@@ -1007,24 +1128,32 @@ impl GlGraphicsServer {
}
}
/// `glDeleteProgram`
pub fn delete_program(&self, program: glow::Program) {
self.state.borrow_mut().delete_program(program, &self.gl);
}
/// `glUseProgram`
pub(crate) fn set_program(&self, program: Option<glow::Program>) {
self.state.borrow_mut().set_program(program, &self.gl)
}
/// `glDeleteTextures`
pub(crate) fn delete_texture(&self, texture: glow::Texture) {
self.state.borrow_mut().delete_texture(texture, &self.gl)
}
/// Bind the texture with the given identifier to the given target in the given unit.
/// Target numbers can be found using [`ToGlConstant::into_gl`] on `GpuTextureKind` from the `fyrox-graphics` crate.
/// The given unit will be activated if it is not already active.
/// If a texture is already bound in the unit, it will be unbound.
pub(crate) fn set_texture(&self, unit_index: u32, target: u32, texture: Option<glow::Texture>) {
self.state
.borrow_mut()
.set_texture(unit_index, target, texture, &self.gl)
}
/// `glStencilFunc`
pub(crate) fn set_stencil_func(&self, func: StencilFunc) {
let mut state = self.state.borrow_mut();
if state.stencil_func != func {
@@ -1040,9 +1169,11 @@ impl GlGraphicsServer {
}
}
/// `glStencilOp`
pub(crate) fn set_stencil_op(&self, op: StencilOp) {
let mut state = self.state.borrow_mut();
if state.stencil_op != op {
let new_mask = op.write_mask;
if !state.stencil_op.eq_actions(&op) {
state.stencil_op = op;
unsafe {
@@ -1051,24 +1182,31 @@ impl GlGraphicsServer {
state.stencil_op.zfail.into_gl(),
state.stencil_op.zpass.into_gl(),
);
}
}
if state.stencil_op.write_mask != new_mask {
state.stencil_op.write_mask = new_mask;
unsafe {
self.gl.stencil_mask(state.stencil_op.write_mask);
}
}
}
/// `glDeleteVertexArrays`
pub(crate) fn delete_vertex_array_object(&self, vao: glow::VertexArray) {
self.state
.borrow_mut()
.delete_vertex_array_object(vao, &self.gl);
}
/// `glBindVertexArray`
pub(crate) fn set_vertex_array_object(&self, vao: Option<glow::VertexArray>) {
self.state
.borrow_mut()
.set_vertex_array_object(vao, &self.gl);
}
/// `glEnable(GL_SCISSOR_TEST)` or `glDisable(GL_SCISSOR_TEST)`.
pub(crate) fn set_scissor_test(&self, scissor_test: bool) {
let mut state = self.state.borrow_mut();
if state.scissor_test != scissor_test {
@@ -1084,6 +1222,7 @@ impl GlGraphicsServer {
}
}
/// `glScissor`
pub(crate) fn set_scissor_box(&self, scissor_box: &ScissorBox) {
unsafe {
self.gl.scissor(
@@ -1095,6 +1234,7 @@ impl GlGraphicsServer {
}
}
/// Call the necessary GL functions to set the given parameters.
pub(crate) fn apply_draw_parameters(&self, draw_params: &DrawParameters) {
let DrawParameters {
cull_face,
@@ -1320,16 +1460,25 @@ impl GraphicsServer for GlGraphicsServer {
}
fn set_polygon_fill_mode(&self, polygon_face: PolygonFace, polygon_fill_mode: PolygonFillMode) {
let (set_front, set_back) = match polygon_face {
PolygonFace::Front => (true, false),
PolygonFace::Back => (false, true),
PolygonFace::FrontAndBack => (true, true),
};
let mut state = self.state.borrow_mut();
if state.polygon_fill_mode != polygon_fill_mode || state.polygon_face != polygon_face {
state.polygon_fill_mode = polygon_fill_mode;
state.polygon_face = polygon_face;
if (set_front && state.front_fill_mode != polygon_fill_mode)
|| (set_back && state.back_fill_mode != polygon_fill_mode)
{
if set_front {
state.front_fill_mode = polygon_fill_mode;
}
if set_back {
state.back_fill_mode = polygon_fill_mode;
}
unsafe {
self.gl.polygon_mode(
state.polygon_face.into_gl(),
state.polygon_fill_mode.into_gl(),
)
self.gl
.polygon_mode(polygon_face.into_gl(), polygon_fill_mode.into_gl())
}
}
}
+85
View File
@@ -18,6 +18,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//! A GPU program is a collection of shaders that are linked together so that they
//! can run on the GPU to control how rendering is performed.
use crate::{
core::{
algebra::{Matrix2, Matrix3, Matrix4, Vector2, Vector3, Vector4},
@@ -33,15 +36,30 @@ use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, EnumString, VariantNames};
define_as_any_trait!(GpuProgramAsAny => GpuProgramTrait);
/// A trait for whatever objects a graphics server is using to represent programs.
/// There are no methods because all interactions with programs are done through the server,
/// such as with [`crate::server::GraphicsServer::create_program`]
/// and [`crate::framebuffer::GpuFrameBufferTrait::draw`].
pub trait GpuProgramTrait: GpuProgramAsAny {}
define_shared_wrapper!(GpuProgram<dyn GpuProgramTrait>);
/// A shader can be either a fragment shader that produces pixels or
/// a vertex shader that controls where triangles are drawn on the screen.
pub enum ShaderKind {
/// A vertex shader takes vertices in world coordinates and mathematically
/// transforms them into screen coordinates for rendering. The vertex shader
/// runs before the fragment shader and creates the input to the fragment shader.
Vertex,
/// The fragment shader determines whether a pixel should be drawn and what color it should be.
/// It uses the data produced by the vertex shader after it has been interpolated by the GPU
/// for the particular pixel under consideration.
Fragment,
}
define_as_any_trait!(GpuShaderAsAny => GpuShaderTrait);
/// A trait for whatever objects a graphics server is using to represent shaders.
/// There are no methods because all interactions with programs are done through the server,
/// such as with [`crate::server::GraphicsServer::create_shader`].
pub trait GpuShaderTrait: GpuShaderAsAny {}
define_shared_wrapper!(GpuShader<dyn GpuShaderTrait>);
@@ -89,16 +107,38 @@ pub enum SamplerFallback {
Volume,
}
/// A sampler represents how the data of a texture is accessed, and different kinds of samplers
/// are intended for different kinds of textures.
#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Clone, Copy, Visit, Eq, Reflect)]
pub enum SamplerKind {
/// A sampler for a 1D linear texture, a series of values that are indexed by a single coordinate
/// and where each component of the value is a float.
Sampler1D,
/// A sampler for the usual 2D image texture, a flat area of values that are indexed by a pair of coordinates (x, y)
/// and where each component of the value is a float.
#[default]
Sampler2D,
/// A sampler for a 3D texture, a volume of floats that are indexed by three coordinates (x, y, z)
/// and where each component of the value is a float.
Sampler3D,
/// A sampler for six square 2D images where each image represents one face of a cube.
/// It is indexed by a three coordinate direction from the center of the cube (x, y, z) where the magnitude of the coordinates do not matter.
/// The sampler follows the direction of the coordinates until it finds a place on one of the six faces of the cube.
/// Each component of the resulting value is a float.
SamplerCube,
/// A sampler for a 1D linear texture, a series of values that are indexed by a single coordinate
/// and where each component of the value is an unsigned integer.
USampler1D,
/// A sampler for the usual 2D image texture, a flat area of unsigned integers that are indexed by a pair of coordinates (x, y)
/// and where each component of the value is an unsigned integer.
USampler2D,
/// A sampler for a 3D texture, a volume of unsigned integers that are indexed by three coordinates (x, y, z)
/// and where each component of the value is an unsigned integer.
USampler3D,
/// A sampler for six square 2D images where each image represents one face of a cube.
/// It is indexed by a three coordinate direction from the center of the cube (x, y, z) where the magnitude of the coordinates do not matter.
/// The sampler follows the direction of the coordinates until it finds a place on one of the six faces of the cube.
/// Each component of the resulting value is an unsigned integer.
USamplerCube,
}
@@ -125,19 +165,26 @@ pub enum ShaderResourceKind {
/// missing by very specific value in the fallback texture.
fallback: SamplerFallback,
},
/// A list of properties with names and values that represents a uniform struct within the shader
/// and the default values for each field of the struct.
PropertyGroup(Vec<ShaderProperty>),
}
/// A data type and default value for a uniform within a shader.
/// When a material supplies an actual value, it is done using a `MaterialProperty` value
/// from the `fyrox-material` crate.
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Reflect, Visit)]
pub enum ShaderPropertyKind {
/// Real number.
Float {
/// Default value
#[serde(default)]
value: f32,
},
/// Real number array.
FloatArray {
/// Default value
value: Vec<f32>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -145,12 +192,14 @@ pub enum ShaderPropertyKind {
/// Integer number.
Int {
/// Default value
#[serde(default)]
value: i32,
},
/// Integer number array.
IntArray {
/// Default value
value: Vec<i32>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -158,12 +207,14 @@ pub enum ShaderPropertyKind {
/// Natural number.
UInt {
/// Default value
#[serde(default)]
value: u32,
},
/// Natural number array.
UIntArray {
/// Default value
value: Vec<u32>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -171,18 +222,21 @@ pub enum ShaderPropertyKind {
/// Boolean value.
Bool {
/// Default value
#[serde(default)]
value: bool,
},
/// Two-dimensional vector.
Vector2 {
/// Default value
#[serde(default)]
value: Vector2<f32>,
},
/// Two-dimensional vector array.
Vector2Array {
/// Default value
value: Vec<Vector2<f32>>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -190,12 +244,14 @@ pub enum ShaderPropertyKind {
/// Three-dimensional vector.
Vector3 {
/// Default value
#[serde(default)]
value: Vector3<f32>,
},
/// Three-dimensional vector array.
Vector3Array {
/// Default value
value: Vec<Vector3<f32>>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -203,12 +259,14 @@ pub enum ShaderPropertyKind {
/// Four-dimensional vector.
Vector4 {
/// Default value
#[serde(default)]
value: Vector4<f32>,
},
/// Four-dimensional vector array.
Vector4Array {
/// Default value
value: Vec<Vector4<f32>>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -216,12 +274,14 @@ pub enum ShaderPropertyKind {
/// 2x2 Matrix.
Matrix2 {
/// Default value
#[serde(default)]
value: Matrix2<f32>,
},
/// 2x2 Matrix array.
Matrix2Array {
/// Default value
value: Vec<Matrix2<f32>>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -229,12 +289,14 @@ pub enum ShaderPropertyKind {
/// 3x3 Matrix.
Matrix3 {
/// Default value
#[serde(default)]
value: Matrix3<f32>,
},
/// 3x3 Matrix array.
Matrix3Array {
/// Default value
value: Vec<Matrix3<f32>>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -242,12 +304,14 @@ pub enum ShaderPropertyKind {
/// 4x4 Matrix.
Matrix4 {
/// Default value
#[serde(default)]
value: Matrix4<f32>,
},
/// 4x4 Matrix array.
Matrix4Array {
/// Default value
value: Vec<Matrix4<f32>>,
/// `max_len` defines the maximum number of elements in the shader.
max_len: usize,
@@ -277,13 +341,17 @@ fn default_color_component() -> u8 {
255
}
/// A uniform value that is supplied to a shader by a material.
#[derive(Serialize, Deserialize, Debug, PartialEq, Reflect, Visit, Clone, Default)]
pub struct ShaderProperty {
/// The name of the value in the shader and when editing the value in the material.
pub name: ImmutableString,
/// The property's data type and default value.
pub kind: ShaderPropertyKind,
}
impl ShaderProperty {
/// Create a property with the given name and value.
pub fn new(name: impl Into<ImmutableString>, kind: ShaderPropertyKind) -> Self {
Self {
name: name.into(),
@@ -291,6 +359,7 @@ impl ShaderProperty {
}
}
/// Create a property with the 2x2 identity matrix as its value.
pub fn new_matrix2(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -300,6 +369,7 @@ impl ShaderProperty {
)
}
/// Create a property with the 3x3 identity matrix as its value.
pub fn new_matrix3(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -309,6 +379,7 @@ impl ShaderProperty {
)
}
/// Create a property with the 4x4 identity matrix as its value.
pub fn new_matrix4(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -318,6 +389,7 @@ impl ShaderProperty {
)
}
/// Create a property with the vector (0,0) as its value.
pub fn new_vector2(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -327,6 +399,7 @@ impl ShaderProperty {
)
}
/// Create a property with the vector (0,0,0) as its value.
pub fn new_vector3(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -336,6 +409,7 @@ impl ShaderProperty {
)
}
/// Create a property with the vector (0,0,0,0) as its value.
pub fn new_vector4(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -345,18 +419,22 @@ impl ShaderProperty {
)
}
/// Create a property with the float 0.0 as its value.
pub fn new_float(name: impl Into<ImmutableString>) -> Self {
Self::new(name, ShaderPropertyKind::Float { value: 0.0 })
}
/// Create a property with false as its value.
pub fn new_bool(name: impl Into<ImmutableString>) -> Self {
Self::new(name, ShaderPropertyKind::Bool { value: false })
}
/// Create a property with the integer 0 as its value.
pub fn new_int(name: impl Into<ImmutableString>) -> Self {
Self::new(name, ShaderPropertyKind::Int { value: 0 })
}
/// Create a property with white as its value.
pub fn new_color(name: impl Into<ImmutableString>) -> Self {
Self::new(
name,
@@ -369,6 +447,7 @@ impl ShaderProperty {
)
}
/// Create a property with an empty list of 4x4 matrices and the given maximum length for the list.
pub fn new_mat4_f32_array(name: impl Into<ImmutableString>, max_len: usize) -> Self {
Self::new(
name,
@@ -379,6 +458,7 @@ impl ShaderProperty {
)
}
/// Create a property with an empty list of floats and the given maximum length for the list.
pub fn new_f32_array(name: impl Into<ImmutableString>, max_len: usize) -> Self {
Self::new(
name,
@@ -389,6 +469,7 @@ impl ShaderProperty {
)
}
/// Create a property with an empty list of vectors and the given maximum length for the list.
pub fn new_vec4_f32_array(name: impl Into<ImmutableString>, max_len: usize) -> Self {
Self::new(
name,
@@ -399,6 +480,7 @@ impl ShaderProperty {
)
}
/// Create a property with an empty list of vectors and the given maximum length for the list.
pub fn new_vec3_f32_array(name: impl Into<ImmutableString>, max_len: usize) -> Self {
Self::new(
name,
@@ -409,6 +491,7 @@ impl ShaderProperty {
)
}
/// Create a property with an empty list of vectors and the given maximum length for the list.
pub fn new_vec2_f32_array(name: impl Into<ImmutableString>, max_len: usize) -> Self {
Self::new(
name,
@@ -439,6 +522,8 @@ pub struct ShaderResourceDefinition {
pub name: ImmutableString,
/// A kind of resource.
pub kind: ShaderResourceKind,
/// Binding points for active uniform blocks are assigned using `glUniformBlockBinding`.
/// Each of a program's active uniform blocks has a corresponding uniform buffer binding point.
pub binding: usize,
}
+14 -2
View File
@@ -18,6 +18,11 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//! This crate is an abstraction layer for graphical services like OpenGL.
//! See the [`server::GraphicsServer`] trait for the rendering features that are available through
//! this abstraction layer.
//! The `fyrox-graphics-gl` crate provides an OpenGL implementation of `GraphicsServer`.
#![allow(clippy::too_many_arguments)]
pub use fyrox_core as core;
@@ -442,11 +447,18 @@ pub struct StencilOp {
pub zfail: StencilAction,
/// An action that happens when the depth test has passed.
pub zpass: StencilAction,
/// A mask that is used to filter out some bits (using `AND` logical operation) from the source
/// value before writing it to the stencil buffer.
/// Specifies a bit mask to enable and disable writing of individual bits in the stencil planes. Initially, the mask is all 1's,
/// which means that all bits of the stencil buffer may be written by the stencil operations specified in `stencil_op`.
/// 0 bits protect the corresponding bits of the stencil from changing.
pub write_mask: u32,
}
impl StencilOp {
pub fn eq_actions(&self, other: &StencilOp) -> bool {
self.fail == other.fail && self.zfail == other.zfail && self.zpass == other.zpass
}
}
impl Default for StencilOp {
fn default() -> Self {
Self {
+4 -1
View File
@@ -186,7 +186,10 @@ pub trait GraphicsServer: GraphicsServerAsAny {
/// Returns current capabilities of the graphics server. See [`ServerCapabilities`] for more info.
fn capabilities(&self) -> ServerCapabilities;
/// Sets current polygon fill mode. See [`PolygonFace`] and [`PolygonFillMode`] docs for more info.
/// Sets current polygon fill mode for front faces, back faces, or both.
/// The mode of front faces is controlled separately from the mode of back faces,
/// and `polygon_face` determines which mode is set by this method.
/// See [`PolygonFace`] and [`PolygonFillMode`] docs for more info.
fn set_polygon_fill_mode(&self, polygon_face: PolygonFace, polygon_fill_mode: PolygonFillMode);
/// Generates mipmaps for the given texture. Graphics server implementation can pick any desired