use raylib_ffi::*;
use ::std::os::raw::*;
const MAX_LIGHTS: usize = 4;
struct Light {
enabled: i32,
kind: i32,
position: Vector3,
target: Vector3,
color: Color,
enabled_loc: i32,
kind_loc: i32,
position_loc: i32,
target_loc: i32,
color_loc: i32,
}
fn create_light(id: isize, kind: i32, position: Vector3, target : Vector3, color : Color, shader : Shader) -> Light {
unsafe {
let light = Light {
enabled: 1,
kind,
position,
target,
color,
enabled_loc: GetShaderLocation(shader, rl_str!(format!("lights[{}].enabled", id))),
kind_loc: GetShaderLocation(shader, rl_str!(format!("lights[{}].type", id))),
position_loc: GetShaderLocation(shader, rl_str!(format!("lights[{}].position", id))),
target_loc: GetShaderLocation(shader, rl_str!(format!("lights[{}].target", id))),
color_loc: GetShaderLocation(shader, rl_str!(format!("lights[{}].color", id)))
};
update_light_values(shader, &light);
return light;
}
}
fn update_light_values(shader: Shader, light: &Light) {
unsafe {
let enabled = [light.enabled].as_ptr();
SetShaderValue(shader, light.enabled_loc, enabled as *const c_void, enums::ShaderUniformDataType::Int as i32);
let kind = [light.kind].as_ptr();
SetShaderValue(shader, light.kind_loc, kind as *const c_void, enums::ShaderUniformDataType::Int as i32);
let position = [light.position.x, light.position.y, light.position.z].as_ptr();
SetShaderValue(shader, light.position_loc, position as *const c_void, enums::ShaderUniformDataType::Vec3 as i32);
let target = [light.position.x, light.position.y, light.position.z].as_ptr();
SetShaderValue(shader, light.target_loc, target as *const c_void, enums::ShaderUniformDataType::Vec3 as i32);
let color = [
light.color.r as f32 / 255.0,
light.color.g as f32 / 255.0,
light.color.b as f32 / 255.0,
light.color.a as f32 / 255.0
].as_ptr();
SetShaderValue(shader, light.color_loc, color as *const c_void, enums::ShaderUniformDataType::Vec4 as i32);
}
}
pub fn main() {
unsafe {
SetConfigFlags(enums::ConfigFlags::Msaa4xHint as u32); InitWindow(800, 450, rl_str!("raylib [shaders] example - basic lighting"));
let mut camera = Camera{
position: Vector3{ x: 2.0, y: 4.0, z: 6.0 }, target: Vector3{ x: 0.0, y: 0.5, z: 0.0 }, up: Vector3{ x: 0.0, y: 1.0, z: 0.0 }, fovy: 45.0, projection: enums::CameraProjection::Perspective as i32 };
let model = LoadModelFromMesh(GenMeshPlane(10.0, 10.0, 3, 3));
let cube = LoadModelFromMesh(GenMeshCube(2.0, 4.0, 2.0));
let shader = LoadShader(rl_str!("examples/shaders/lighting.vs"), rl_str!("examples/shaders/lighting.fs"));
let view_loc = shader.locs.offset(enums::ShaderLocationIndex::VectorView as isize) as *mut c_int;
*view_loc = GetShaderLocation(shader, rl_str!("viewPos"));
let ambient_loc = GetShaderLocation(shader, rl_str!("ambient"));
let ambient_value = [0.1 as f32, 0.1 as f32, 0.1 as f32, 1.0 as f32].as_ptr();
SetShaderValue(shader, ambient_loc, ambient_value as *const c_void, enums::ShaderUniformDataType::Ivec4 as i32);
(*(model.materials.offset(0))).shader = shader;
(*(cube.materials.offset(0))).shader = shader;
let mut lights = [
create_light(0, 1, Vector3{ x: -2.0, y: 1.0, z: -2.0 }, Vector3{ x: 0.0, y: 0.0, z: 0.0 }, colors::YELLOW, shader),
create_light(1, 1, Vector3{ x: 2.0, y: 1.0, z: 2.0 }, Vector3{ x: 0.0, y: 0.0, z: 0.0 }, colors::RED, shader),
create_light(2, 1, Vector3{ x: -2.0, y: 1.0, z: 2.0 }, Vector3{ x: 0.0, y: 0.0, z: 0.0 }, colors::GREEN, shader),
create_light(3, 1, Vector3{ x: 2.0, y: 1.0, z: -2.0 }, Vector3{ x: 0.0, y: 0.0, z: 0.0 }, colors::BLUE, shader)
];
SetTargetFPS(60);
while !WindowShouldClose() {
UpdateCamera(&mut camera, enums::CameraMode::Orbital as i32);
let camera_pos = [camera.position.x, camera.position.y, camera.position.z].as_ptr();
SetShaderValue(shader, shader.locs.offset(enums::ShaderLocationIndex::VectorView as isize).read(), camera_pos as *mut c_void, enums::ShaderUniformDataType::Ivec3 as c_int);
if IsKeyPressed(enums::KeyboardKey::R as i32) { lights[1].enabled = !lights[1].enabled; }
if IsKeyPressed(enums::KeyboardKey::G as i32) { lights[2].enabled = !lights[2].enabled; }
if IsKeyPressed(enums::KeyboardKey::B as i32) { lights[3].enabled = !lights[3].enabled; }
if IsKeyPressed(enums::KeyboardKey::Y as i32) { lights[0].enabled = !lights[0].enabled; }
for i in 0 .. MAX_LIGHTS {
update_light_values(shader, &lights[i]);
}
BeginDrawing();
ClearBackground(colors::WHITE);
BeginMode3D(camera);
DrawModel(model, Vector3{ x: 0.0, y: 0.0, z: 0.0 }, 1.0, colors::WHITE);
DrawModel(cube, Vector3{ x: 0.0, y: 0.0, z: 0.0 }, 1.0, colors::WHITE);
for i in 0 .. MAX_LIGHTS {
if lights[i].enabled > 0 {
DrawSphereEx(lights[i].position, 0.2, 8, 8, lights[i].color);
} else {
DrawSphereWires(lights[i].position, 0.2, 8, 8, ColorAlpha(lights[i].color, 0.3));
}
}
DrawGrid(10, 1.0);
EndMode3D();
DrawFPS(10, 10);
DrawText(rl_str!("Use keys [Y][R][G][B] to toggle lights"), 10, 40, 20, colors::DARKGRAY);
EndDrawing();
}
UnloadModel(model); UnloadModel(cube); UnloadShader(shader);
CloseWindow(); }
}