Struct shades::ShaderBuilder [−][src]
A shader builder.
This opaque type is the representation of a shader stage in Rust. It contains constants, uniforms, inputs, outputs and
functions declarations. Such a type is used to build a shader stage and is fully built when the main
function is
present in its code. See ShaderBuilder::main_fun
for further details.
Implementations
impl ShaderBuilder
[src]
pub fn new_vertex_shader(
f: impl FnOnce(Self, VertexShaderEnv) -> Shader
) -> Shader
[src]
f: impl FnOnce(Self, VertexShaderEnv) -> Shader
) -> Shader
Create a new vertex shader.
This method creates a Shader
that can be used as vertex shader. This is enforced by the fact only this
method authorized to build a vertex Shader
by using the VertexShaderEnv
argument passed to the input
closure.
That closure takes as first argument a mutable reference on a ShaderBuilder
and a VertexShaderEnv
as
second argument. The VertexShaderEnv
allows you to access to vertex attributes found in any invocation of
a vertex shader. Those are expressions (read-only) and variables (read-write) valid only in vertex shaders.
Return
This method returns the fully built Shader
, which cannot be mutated anymore once it has been built,
and can be passed to various writers
to generate actual code for target shading languages.
Examples
use shades::{Scope, ShaderBuilder, V3, inputs, vec4}; let vertex_shader = ShaderBuilder::new_vertex_shader(|mut s, vertex| { inputs!(s, position: V3<f32>); s.main_fun(|s: &mut Scope<()>| { s.set(vertex.position, vec4!(position, 1.)); }) });
pub fn new_tess_ctrl_shader(
f: impl FnOnce(Self, TessCtrlShaderEnv) -> Shader
) -> Shader
[src]
f: impl FnOnce(Self, TessCtrlShaderEnv) -> Shader
) -> Shader
Create a new tessellation control shader.
This method creates a Shader
that can be used as tessellation control shader. This is enforced by the
fact only this method authorized to build a tessellation control Shader
by using the TessCtrlShaderEnv
argument passed to the input closure.
That closure takes as first argument a mutable reference on a ShaderBuilder
and a TessCtrlShaderEnv
as
second argument. The TessCtrlShaderEnv
allows you to access to tessellation control attributes found in any
invocation of a tessellation control shader. Those are expressions (read-only) and variables (read-write) valid
only in tessellation control shaders.
Return
This method returns the fully built Shader
, which cannot be mutated anymore once it has been built,
and can be passed to various writers
to generate actual code for target shading languages.
Examples
use shades::{Scope, ShaderBuilder, V3, vec4}; let tess_ctrl_shader = ShaderBuilder::new_tess_ctrl_shader(|mut s, patch| { s.main_fun(|s: &mut Scope<()>| { s.set(patch.tess_level_outer.at(0), 0.1); }) });
pub fn new_tess_eval_shader(
f: impl FnOnce(Self, TessEvalShaderEnv) -> Shader
) -> Shader
[src]
f: impl FnOnce(Self, TessEvalShaderEnv) -> Shader
) -> Shader
Create a new tessellation evaluation shader.
This method creates a Shader
that can be used as tessellation evaluation shader. This is enforced by the
fact only this method authorized to build a tessellation evaluation Shader
by using the TessEvalShaderEnv
argument passed to the input closure.
That closure takes as first argument a mutable reference on a ShaderBuilder
and a TessEvalShaderEnv
as
second argument. The TessEvalShaderEnv
allows you to access to tessellation evaluation attributes found in
any invocation of a tessellation evaluation shader. Those are expressions (read-only) and variables (read-write)
valid only in tessellation evaluation shaders.
Return
This method returns the fully built Shader
, which cannot be mutated anymore once it has been built,
and can be passed to various writers
to generate actual code for target shading languages.
Examples
use shades::{Scope, ShaderBuilder, V3, inputs, vec4}; let tess_eval_shader = ShaderBuilder::new_tess_eval_shader(|mut s, patch| { inputs!(s, position: V3<f32>); s.main_fun(|s: &mut Scope<()>| { s.set(patch.position, vec4!(position, 1.)); }) });
pub fn new_geometry_shader(
f: impl FnOnce(Self, GeometryShaderEnv) -> Shader
) -> Shader
[src]
f: impl FnOnce(Self, GeometryShaderEnv) -> Shader
) -> Shader
Create a new geometry shader.
This method creates a Shader
that can be used as geometry shader. This is enforced by the fact only this
method authorized to build a geometry Shader
by using the GeometryShaderEnv
argument passed to the input
closure.
That closure takes as first argument a mutable reference on a ShaderBuilder
and a GeometryShaderEnv
as
second argument. The GeometryShaderEnv
allows you to access to geometry attributes found in any invocation of
a geometry shader. Those are expressions (read-only) and variables (read-write) valid only in geometry shaders.
Return
This method returns the fully built Shader
, which cannot be mutated anymore once it has been built,
and can be passed to various writers
to generate actual code for target shading languages.
Examples
use shades::{LoopScope, Scope, ShaderBuilder, V3, vec4}; let geo_shader = ShaderBuilder::new_geometry_shader(|mut s, vertex| { s.main_fun(|s: &mut Scope<()>| { s.loop_for(0, |i| i.lt(3), |i| i + 1, |s: &mut LoopScope<()>, i| { s.set(vertex.position, vertex.input.at(i).position()); }); }) });
pub fn new_fragment_shader(
f: impl FnOnce(Self, FragmentShaderEnv) -> Shader
) -> Shader
[src]
f: impl FnOnce(Self, FragmentShaderEnv) -> Shader
) -> Shader
Create a new fragment shader.
This method creates a Shader
that can be used as fragment shader. This is enforced by the fact only this
method authorized to build a ShaderBuilder
by using the FragmentShaderEnv
argument passed to the input
closure.
That closure takes as first argument a mutable reference on a ShaderBuilder
and a FragmentShaderEnv
as
second argument. The FragmentShaderEnv
allows you to access to fragment attributes found in any invocation of
a fragment shader. Those are expressions (read-only) and variables (read-write) valid only in fragment shaders.
Return
This method returns the fully built Shader
, which cannot be mutated anymore once it has been built,
and can be passed to various writers
to generate actual code for target shading languages.
Examples
use shades::{Geometry as _, Scope, ShaderBuilder, V4, outputs, vec4}; let geo_shader = ShaderBuilder::new_fragment_shader(|mut s, fragment| { outputs!(s, color: V4<f32>); s.main_fun(|s: &mut Scope<()>| { s.set(color, fragment.frag_coord.normalize()); }) });
pub fn fun<F, R, A>(&mut self, f: F) -> FunHandle<R, A> where
F: ToFun<R, A>,
[src]
F: ToFun<R, A>,
Create a new function in the shader and get its handle for future use.
This method requires to pass a closure encoding the argument(s) and return type of the function to create. The
closure’s body encodes the body of the function to create. The number of arguments will directly impact the
number of arguments the created function will have. The return type can be ()
if the function doesn’t
return anything or Expr<T>
if it does return something.
The first argument of the closure is a mutable reference on a Scope
. Its type parameter must be set to the
return type. The scope allows you to add instructions to the function body of the generated function. As in
vanilla Rust, the last expression in a function is assumed as return value, if the function returns a value.
However, unlike Rust, if your function returns something, it cannot return
it: it has to use the
expression-as-last-instruction syntax. It means that even if you don’t use the Scope
within the last
expression of your function body, the returned expression will still be part of the function as special returned
expression:
use shades::{Expr, Scope}; let f = s.fun(|s: &mut Scope<Expr<f32>>, a: Expr<f32>| a + 1.);
However, as mentioned above, you cannot return
the last expression (leave
), as this is not accepted by the
EDSL:
use shades::{Expr, Scope}; let f = s.fun(|s: &mut Scope<Expr<f32>>, a: Expr<f32>| { s.leave(a + 1.); });
Please refer to the Scope
documentation for a complete list of the instructions you can record.
Caveats
On a last note, you can still use the return
keyword from Rust, but it is highly discouraged, as returning with
return
cannot be captured by the EDSL. It means that you will not get the shader code you expect.
use shades::{Expr, Scope}; let f = s.fun(|s: &mut Scope<Expr<f32>>, a: Expr<f32>| { return a + 1.; });
An example of a broken shader is when you use the Rust return
keyword inside a conditional statement or looping
statement:
use shades::{CanEscape as _, EscapeScope, Expr, Scope}; // don’t do this. let f = s.fun(|s: &mut Scope<Expr<f32>>, a: Expr<f32>| { s.when(a.lt(10.), |s: &mut EscapeScope<Expr<f32>>| { // /!\ problem here /!\ return; }); a + 1. });
This snippet will create a GLSL function testing whether its a
argument is less than 10.
and if it’s the case,
does nothing inside of it (the return
is not captured by the EDSL).
Return
This method returns a function handle, FunHandle<R, A>
, where R
is the return type and A
the argument
list of the function. This handle can be used in various positions in the EDSL but the most interesting place is
in Expr<T>
and Var<T>
, when calling the function to, respectively, combine it with other expressions or
assign it to a variable.
Nightly-only: call syntax
On the current version of stable rustc
(1.49), it is not possible to use a FunHandle<R, A>
as you would use
a normal Rust function: you have to use the FunHandle::call
method, which is not really elegant nor ergonomic.
To fix this problem, enable the fun-call
feature gate.
Examples
use shades::{Exponential as _, Expr, Scope, ShaderBuilder, lit}; let shader = ShaderBuilder::new_vertex_shader(|mut s, vertex| { // create a function taking a floating-point number and returning its square let square = s.fun(|s: &mut Scope<Expr<f32>>, a: Expr<f32>| { a.pow(2.) }); // `square` can now be used to square floats! s.main_fun(|s: &mut Scope<()>| { // if you use the nightly compiler let nine = s.var(square(lit!(3.))); // if you’d rather use stable let nine = s.var(square.call(lit!(3.))); }) });
pub fn main_fun<F, R>(self, f: F) -> Shader where
F: ToFun<R, ()>,
[src]
F: ToFun<R, ()>,
Declare the main
function of the shader stage.
This method is very similar to ShaderBuilder::fun
in the sense it declares a function. However, it declares the special
main
entry-point of a shader stage, which doesn’t have have argument and returns nothing, and is the only
way to finalize the building of a Shader
.
The input closure must take a single argument: a mutable reference on a Scope<()>
, as the main
function
cannot return anything.
Return
The fully built Shader
, which cannot be altered anymore.
Examples
use shades::{Scope, ShaderBuilder}; let shader = ShaderBuilder::new_vertex_shader(|s, vertex| { s.main_fun(|s: &mut Scope<()>| { // … }) });
pub fn constant<T>(&mut self, expr: impl Into<Expr<T>>) -> Expr<T> where
T: ToType,
[src]
T: ToType,
Declare a new constant, shared between all functions and constants that come next.
The input argument is any object that can be transformed Into
an Expr<T>
. At this level in the
shader, pretty much nothing but literals and other constants are accepted here.
Return
An Expr<T>
representing the constant passed as input.
Examples
// don’t do this. let illum_coefficient: Expr<f32> = s.constant(10.);
pub unsafe fn input<T>(&mut self, name: &str) -> Var<T> where
T: ToType,
[src]
T: ToType,
Declare a new input, shared between all functions and constants that come next.
TODO
pub unsafe fn output<T>(&mut self, name: &str) -> Var<T> where
T: ToType,
[src]
T: ToType,
TODO
pub unsafe fn uniform<T>(&mut self, name: &str) -> Var<T> where
T: ToType,
[src]
T: ToType,
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for ShaderBuilder
[src]
impl Send for ShaderBuilder
[src]
impl Sync for ShaderBuilder
[src]
impl Unpin for ShaderBuilder
[src]
impl UnwindSafe for ShaderBuilder
[src]
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,