mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Clarifying fyrox-graphics
This commit is contained in:
+166
-17
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user