///|
fn material_texture_slot_bindings() -> Array[MaterialTextureSlotBinding] {
[
{
shader_loc: @raylib.ShaderLocMapAlbedo,
uniform_name: "texture0",
slot: 0,
material_map: @raylib.MaterialMapAlbedo,
},
{
shader_loc: @raylib.ShaderLocMapMetalness,
uniform_name: "texture1",
slot: 1,
material_map: @raylib.MaterialMapMetalness,
},
{
shader_loc: @raylib.ShaderLocMapNormal,
uniform_name: "texture2",
slot: 2,
material_map: @raylib.MaterialMapNormal,
},
{
shader_loc: @raylib.ShaderLocMapOcclusion,
uniform_name: "texture4",
slot: 4,
material_map: @raylib.MaterialMapOcclusion,
},
{
shader_loc: @raylib.ShaderLocMapEmission,
uniform_name: "texture5",
slot: 5,
material_map: @raylib.MaterialMapEmission,
},
]
}
///|
fn uniform_color4(color : @render.Color) -> @raylib.ShaderUniformData {
Vec4(
@raylib.Vector4::new(
to_float(color.r.to_double() / 255.0),
to_float(color.g.to_double() / 255.0),
to_float(color.b.to_double() / 255.0),
to_float(color.a),
),
)
}
///|
fn reset_material_from_material(
target : @raylib.Material,
source : @raylib.Material,
) -> Unit {
target.set_shader(source.shader())
let target_maps = target.maps()
let source_maps = source.maps()
let count = @cmp.minimum(target_maps.count(), source_maps.count())
for i in 0.. (Double, Double, Double, Double) {
(
transform.offset[X],
transform.offset[Y],
transform.scale[X],
transform.scale[Y],
)
}
///|
fn texture_transform_rotation_sin_cos(
transform : @render3d_types.TextureTransform3D,
) -> @smath.Vec2 {
Vec2(@cmath.sin(transform.rotation), @cmath.cos(transform.rotation))
}
///|
fn uniform_texture_transform_offset_scale(
transform : @render3d_types.TextureTransform3D,
) -> @raylib.ShaderUniformData {
let (offset_x, offset_y, scale_x, scale_y) = texture_transform_offset_scale(
transform,
)
Vec4(
@raylib.Vector4::new(
to_float(offset_x),
to_float(offset_y),
to_float(scale_x),
to_float(scale_y),
),
)
}
///|
fn uniform_texture_transform_rotation(
transform : @render3d_types.TextureTransform3D,
) -> @raylib.ShaderUniformData {
uniform_vec2(texture_transform_rotation_sin_cos(transform))
}
///|
fn to_ray_vec3_array(
values : Array[@smath.Vec3],
count : Int,
) -> Array[@raylib.Vector3] {
let out : Array[@raylib.Vector3] = []
for index in 0.. Array[Float] {
let out : Array[Float] = []
for index in 0.. Unit {
if loc == -1 {
return
}
shader.set_value(loc, value)
}
///|
fn set_shader_uniform_v(
shader : @raylib.Shader,
loc : Int,
data : @raylib.ShaderUniformDataV,
) -> Unit {
if loc == -1 {
return
}
shader.set_value_v(loc, data)
}
///|
fn configure_lighting_shader_locations(shader : @raylib.Shader) -> Unit {
shader.set_locs(
@raylib.ShaderLocVertexPosition,
@raylib.get_shader_location_attrib(shader, "vertexPosition"),
)
shader.set_locs(
@raylib.ShaderLocVertexTexcoord01,
@raylib.get_shader_location_attrib(shader, "vertexTexCoord"),
)
shader.set_locs(
@raylib.ShaderLocVertexTexcoord02,
@raylib.get_shader_location_attrib(shader, "vertexTexCoord2"),
)
shader.set_locs(
@raylib.ShaderLocVertexNormal,
@raylib.get_shader_location_attrib(shader, "vertexNormal"),
)
shader.set_locs(
@raylib.ShaderLocVertexTangent,
@raylib.get_shader_location_attrib(shader, "vertexTangent"),
)
shader.set_locs(
@raylib.ShaderLocVertexColor,
@raylib.get_shader_location_attrib(shader, "vertexColor"),
)
shader.set_locs(
@raylib.ShaderLocMatrixMvp,
@raylib.get_shader_location(shader, "mvp"),
)
shader.set_locs(
@raylib.ShaderLocMatrixView,
@raylib.get_shader_location(shader, "matView"),
)
shader.set_locs(
@raylib.ShaderLocMatrixProjection,
@raylib.get_shader_location(shader, "matProjection"),
)
shader.set_locs(
@raylib.ShaderLocMatrixModel,
@raylib.get_shader_location(shader, "matModel"),
)
shader.set_locs(
@raylib.ShaderLocMatrixNormal,
@raylib.get_shader_location(shader, "matNormal"),
)
for binding in material_texture_slot_bindings() {
shader.set_locs(
binding.shader_loc,
@raylib.get_shader_location(shader, binding.uniform_name),
)
}
}
///|
fn create_lighting_shader_state() -> LightingShaderState {
let shader = @raylib.load_shader_from_memory(
raylib_lighting_vertex_shader, raylib_lighting_fragment_shader,
)
configure_lighting_shader_locations(shader)
let shadow_enabled_locs : Array[Int] = []
let shadow_cascade_count_locs : Array[Int] = []
let shadow_matrix_locs : Array[Int] = []
let shadow_rect_locs : Array[Int] = []
let shadow_bound_locs : Array[Int] = []
let shadow_depth_bias_locs : Array[Int] = []
let shadow_normal_bias_locs : Array[Int] = []
let shadow_sampler_locs : Array[Int] = []
let spot_shadow_enabled_locs : Array[Int] = []
let spot_shadow_matrix_locs : Array[Int] = []
let spot_shadow_rect_locs : Array[Int] = []
let spot_shadow_depth_bias_locs : Array[Int] = []
let spot_shadow_normal_bias_locs : Array[Int] = []
let point_shadow_enabled_locs : Array[Int] = []
let point_shadow_depth_bias_locs : Array[Int] = []
let point_shadow_normal_bias_locs : Array[Int] = []
let point_shadow_matrix_locs : Array[Int] = []
let point_shadow_rect_locs : Array[Int] = []
for index in 0.. LightingShaderState {
if backend.lighting_shader is Some(state) {
return state
}
let state = create_lighting_shader_state()
backend.lighting_shader = Some(state)
state
}
///|
fn white_render_color() -> @render.Color {
{ r: 255U, g: 255U, b: 255U, a: 1.0 }
}
///|
const INTERNAL_WHITE_TEXTURE_KEY : String = "__selene_internal:white_1x1"
///|
fn ensure_texture_mipmaps(texture : @raylib.Texture) -> Unit {
if texture.mipmaps() < 2 {
texture.gen_mipmaps()
}
}
///|
fn get_solid_texture(key : String, color : @render.Color) -> @raylib.Texture {
if backend.textures.get(key) is Some(texture) {
return texture
}
let image = @raylib.gen_image_color(1, 1, to_ray_color(color))
let texture = @raylib.load_texture_from_image(image)
@raylib.unload_image(image)
ensure_texture_mipmaps(texture)
@raylib.set_texture_filter(texture, @raylib.TextureFilterPoint)
backend.textures.set(key, texture)
texture
}
///|
fn get_white_texture() -> @raylib.Texture {
get_solid_texture(INTERNAL_WHITE_TEXTURE_KEY, white_render_color())
}
///|
fn fallback_lighting_texture_bundle() -> MaterialTextureBundle3D {
let default_transform = @render3d_types.default_texture_transform3d()
{
base_texture: get_white_texture(),
emissive_texture: get_white_texture(),
metallic_roughness_texture: get_white_texture(),
occlusion_texture: get_white_texture(),
normal_texture: null_texture(),
has_base_texture: false,
has_emissive_texture: false,
has_metallic_roughness_texture: false,
has_occlusion_texture: false,
has_normal_texture: false,
base_transform: default_transform,
emissive_transform: default_transform,
metallic_roughness_transform: default_transform,
occlusion_transform: default_transform,
normal_transform: default_transform,
base_texcoord_set: 0,
emissive_texcoord_set: 0,
metallic_roughness_texcoord_set: 0,
occlusion_texcoord_set: 0,
normal_texcoord_set: 0,
}
}
///|
fn get_lit_material(textured : Bool) -> @raylib.Material {
let existing = if textured {
backend.lit_textured_material
} else {
backend.lit_material
}
if existing is Some(material) {
return material
}
let material = @raylib.Material::default()
@raylib.set_material_shader(material, get_lighting_shader_state().shader)
@raylib.set_material_map_color(
material,
@raylib.MaterialMapAlbedo,
to_ray_color(white_render_color()),
)
if textured {
backend.lit_textured_material = Some(material)
} else {
backend.lit_material = Some(material)
}
material
}
///|
fn bind_shadow_textures(shadow_state : FrameShadowState?) -> Unit {
guard shadow_state is Some(frame_shadow) else { return }
for index in 0.. Unit {
guard shadow_state is Some(frame_shadow) else { return }
for index in 0..