///|
struct Shader(@ffi.Shader)
///|
pub(all) enum ShaderUniformData {
Float(Float)
Vec2(Vector2)
Vec3(Vector3)
Vec4(Vector4)
Int(Int)
IVec2((Int, Int))
IVec3((Int, Int, Int))
IVec4((Int, Int, Int, Int))
Sampler2D(Int)
}
///|
fn ShaderUniformData::to_bytes(self : ShaderUniformData) -> Bytes {
match self {
Float(v) => {
let buf = @buffer.new(size_hint=4)
buf.write_float_le(v)
buf.to_bytes()
}
Vec2(v) => v.to_bytes()
Vec3(v) => v.to_bytes()
Vec4(v) => v.to_bytes()
Int(v) | Sampler2D(v) => {
let buf = @buffer.new(size_hint=4)
buf.write_int_le(v)
buf.to_bytes()
}
IVec2((x, y)) => {
let buf = @buffer.new(size_hint=8)
buf.write_int_le(x)
buf.write_int_le(y)
buf.to_bytes()
}
IVec3((x, y, z)) => {
let buf = @buffer.new(size_hint=12)
buf.write_int_le(x)
buf.write_int_le(y)
buf.write_int_le(z)
buf.to_bytes()
}
IVec4((x, y, z, w)) => {
let buf = @buffer.new(size_hint=16)
buf.write_int_le(x)
buf.write_int_le(y)
buf.write_int_le(z)
buf.write_int_le(w)
buf.to_bytes()
}
}
}
///|
fn ShaderUniformData::uniform_type(self : ShaderUniformData) -> Int {
match self {
Float(_) => ShaderUniformFloat
Vec2(_) => ShaderUniformVec2
Vec3(_) => ShaderUniformVec3
Vec4(_) => ShaderUniformVec4
Int(_) => ShaderUniformInt
IVec2(_) => ShaderUniformIvec2
IVec3(_) => ShaderUniformIvec3
IVec4(_) => ShaderUniformIvec4
Sampler2D(_) => ShaderUniformSampler2d
}
}
///|
pub(all) enum ShaderUniformDataV {
Float(Array[Float])
Vec2(Array[Vector2])
Vec3(Array[Vector3])
Vec4(Array[Vector4])
Int(Array[Int])
IVec2(Array[(Int, Int)])
IVec3(Array[(Int, Int, Int)])
IVec4(Array[(Int, Int, Int, Int)])
Sampler2D(Array[Int])
}
///|
fn ShaderUniformDataV::to_bytes(self : ShaderUniformDataV) -> Bytes {
let buf = @buffer.new(size_hint=self.count() * self.elem_size())
match self {
Float(vs) => for v in vs { buf.write_float_le(v) }
Vec2(vs) =>
for v in vs {
buf.write_float_le(v.x)
buf.write_float_le(v.y)
}
Vec3(vs) =>
for v in vs {
buf.write_float_le(v.x)
buf.write_float_le(v.y)
buf.write_float_le(v.z)
}
Vec4(vs) =>
for v in vs {
buf.write_float_le(v.x)
buf.write_float_le(v.y)
buf.write_float_le(v.z)
buf.write_float_le(v.w)
}
Int(vs) | Sampler2D(vs) => for v in vs { buf.write_int_le(v) }
IVec2(vs) =>
for v in vs {
buf.write_int_le(v.0)
buf.write_int_le(v.1)
}
IVec3(vs) =>
for v in vs {
buf.write_int_le(v.0)
buf.write_int_le(v.1)
buf.write_int_le(v.2)
}
IVec4(vs) =>
for v in vs {
buf.write_int_le(v.0)
buf.write_int_le(v.1)
buf.write_int_le(v.2)
buf.write_int_le(v.3)
}
}
buf.to_bytes()
}
///|
fn ShaderUniformDataV::uniform_type(self : ShaderUniformDataV) -> Int {
match self {
Float(_) => ShaderUniformFloat
Vec2(_) => ShaderUniformVec2
Vec3(_) => ShaderUniformVec3
Vec4(_) => ShaderUniformVec4
Int(_) => ShaderUniformInt
IVec2(_) => ShaderUniformIvec2
IVec3(_) => ShaderUniformIvec3
IVec4(_) => ShaderUniformIvec4
Sampler2D(_) => ShaderUniformSampler2d
}
}
///|
fn ShaderUniformDataV::count(self : ShaderUniformDataV) -> Int {
match self {
Float(vs) => vs.length()
Vec2(vs) => vs.length()
Vec3(vs) => vs.length()
Vec4(vs) => vs.length()
Int(vs) | Sampler2D(vs) => vs.length()
IVec2(vs) => vs.length()
IVec3(vs) => vs.length()
IVec4(vs) => vs.length()
}
}
///|
fn ShaderUniformDataV::elem_size(self : ShaderUniformDataV) -> Int {
match self {
Float(_) | Int(_) | Sampler2D(_) => 4
Vec2(_) | IVec2(_) => 8
Vec3(_) | IVec3(_) => 12
Vec4(_) | IVec4(_) => 16
}
}
///|
#as_free_fn(is_shader_valid)
pub fn Shader::is_valid(self : Shader) -> Bool {
@ffi.is_shader_valid(self.0)
}
///|
#as_free_fn(unload_shader)
pub fn Shader::unload(self : Shader) -> Unit {
@ffi.unload_shader(self.0)
}
///|
#as_free_fn(begin_shader_mode)
pub fn Shader::begin_mode(self : Shader) -> Unit {
@ffi.begin_shader_mode(self.0)
}
///|
pub fn Shader::set_value(
self : Shader,
loc_index : Int,
value : ShaderUniformData,
) -> Unit {
@ffi.set_shader_value(
self.0,
loc_index,
value.to_bytes(),
value.uniform_type(),
)
}
///|
#deprecated("Use Shader::set_value instead")
pub fn set_shader_value(
shader : Shader,
loc_index : Int,
value : Bytes,
uniform_type : Int,
) -> Unit {
@ffi.set_shader_value(shader.0, loc_index, value, uniform_type)
}
///|
pub fn Shader::set_value_v(
self : Shader,
loc_index : Int,
values : ShaderUniformDataV,
) -> Unit {
let count = values.count()
if count == 0 {
return
}
@ffi.set_shader_value_v(
self.0,
loc_index,
values.to_bytes(),
values.uniform_type(),
count,
)
}
///|
#deprecated("Use Shader::set_value_v instead")
pub fn set_shader_value_v(
shader : Shader,
loc_index : Int,
value : Bytes,
uniform_type : Int,
count : Int,
) -> Unit {
@ffi.set_shader_value_v(shader.0, loc_index, value, uniform_type, count)
}
///|
#as_free_fn(set_shader_value_texture)
pub fn Shader::set_value_texture(
self : Shader,
loc_index : Int,
texture : Texture,
) -> Unit {
@ffi.set_shader_value_texture(self.0, loc_index, texture.0)
}
///|
#as_free_fn(set_shader_location, deprecated="Use Shader::set_locs or set_shader_locs instead")
#as_free_fn(set_shader_locs)
pub fn Shader::set_locs(
self : Shader,
loc_index : Int,
loc_value : Int,
) -> Unit {
@ffi.set_shader_locs(self.0, loc_index, loc_value)
}
///|
#as_free_fn(load_shader)
pub fn Shader::load(vs_file_name : String, fs_file_name : String) -> Shader {
@ffi.load_shader(@utf8.encode(vs_file_name), @utf8.encode(fs_file_name))
}
///|
#as_free_fn(load_shader_from_memory)
pub fn Shader::load_from_memory(vs_code : String, fs_code : String) -> Shader {
@ffi.load_shader_from_memory(@utf8.encode(vs_code), @utf8.encode(fs_code))
}
///|
#as_free_fn(get_shader_location)
pub fn Shader::get_location(self : Shader, uniform_name : String) -> Int {
@ffi.get_shader_location(self.0, @utf8.encode(uniform_name))
}
///|
#as_free_fn(get_shader_id)
pub fn Shader::id(self : Shader) -> UInt {
@ffi.get_shader_id(self.0)
}
///|
#as_free_fn(get_shader_location_attrib)
pub fn Shader::get_location_attrib(self : Shader, attrib_name : String) -> Int {
@ffi.get_shader_location_attrib(self.0, @utf8.encode(attrib_name))
}
///|
#as_free_fn(set_shader_value_matrix)
pub fn Shader::set_value_matrix(
self : Shader,
loc_index : Int,
mat : Matrix,
) -> Unit {
@ffi.set_shader_value_matrix(self.0, loc_index, mat.to_bytes())
}