use sevenx_engine::*;
use sevenx_engine::world::World;
struct Game3D {
renderer3d: Renderer3D,
cube: Mesh3D,
sphere: Mesh3D,
torus: Mesh3D,
rotation_speed: f32,
particle_system: ParticleSystem3D,
phong_shader: PhongShader,
fresnel_shader: FresnelShader,
fog_shader: FogShader,
time: f32,
shader_mode: usize,
material_mode: usize,
show_help: bool,
}
impl GameState for Game3D {
fn new() -> Self {
println!("🎮 SevenX Engine v0.2.7 - Demo 3D Avançado");
println!("✨ Texturas 3D + Materiais PBR + Shaders");
println!();
let mut cube = Mesh3D::cube(2.0);
cube.position = Vec3::new(-3.0, 0.0, 0.0);
let texture = Texture3D::checkerboard(32, [255, 50, 50, 255], [255, 200, 200, 255]);
let material = Material3D::new([255, 255, 255, 255])
.with_texture(texture)
.with_metallic(0.3)
.with_roughness(0.5);
cube.set_material(material);
let mut sphere = Mesh3D::sphere(1.2, 16);
sphere.position = Vec3::new(0.0, 0.0, 0.0);
sphere.set_material(Material3D::metal());
let mut torus = Mesh3D::torus(1.0, 0.3, 16, 12);
torus.position = Vec3::new(3.0, 0.0, 0.0);
torus.set_material(Material3D::plastic());
let mut renderer3d = Renderer3D::new(800, 600);
renderer3d.camera.position = Vec3::new(0.0, 3.0, 10.0);
renderer3d.camera.look_at(Vec3::zero());
renderer3d.wireframe = false;
renderer3d.backface_culling = true;
let particle_system = ParticleSystem3D::new(500);
let mut phong_shader = PhongShader::new();
phong_shader.add_light(Light3D::new(
Vec3::new(5.0, 10.0, 5.0),
[1.0, 1.0, 1.0],
1.5,
));
phong_shader.add_light(Light3D::new(
Vec3::new(-5.0, 5.0, -5.0),
[0.5, 0.5, 1.0],
0.8,
));
let fresnel_shader = FresnelShader::new();
let fog_shader = FogShader::new();
Self {
renderer3d,
cube,
sphere,
torus,
rotation_speed: 1.0,
particle_system,
phong_shader,
fresnel_shader,
fog_shader,
time: 0.0,
shader_mode: 0,
material_mode: 0,
show_help: true,
}
}
fn update(&mut self, dt: f32, input: &sevenx_engine::input::InputHandler, _world: &mut World) {
self.time += dt;
self.cube.rotation.y += self.rotation_speed * dt;
self.cube.rotation.x += self.rotation_speed * 0.5 * dt;
self.sphere.rotation.y += self.rotation_speed * 1.5 * dt;
self.torus.rotation.x += self.rotation_speed * dt;
self.torus.rotation.y += self.rotation_speed * 0.7 * dt;
let (move_x, move_y) = input.get_movement_vector();
let camera_speed = if input.is_shift_pressed() { 10.0 } else { 5.0 };
if move_y != 0.0 {
self.renderer3d.camera.move_forward(move_y * camera_speed * dt);
}
if move_x != 0.0 {
self.renderer3d.camera.rotate_around_target(0.0, -move_x * 2.0 * dt);
}
let scroll = input.get_mouse_wheel_delta();
if scroll != 0.0 {
self.renderer3d.camera.move_forward(scroll * 2.0);
}
if input.is_key_just_pressed(KeyCode::Space) {
self.renderer3d.wireframe = !self.renderer3d.wireframe;
println!("🔲 Wireframe: {}", if self.renderer3d.wireframe { "ON" } else { "OFF" });
}
if input.is_key_just_pressed(KeyCode::F1) {
self.show_help = !self.show_help;
}
if input.is_key_just_pressed(KeyCode::Digit1) {
self.shader_mode = 0;
println!("🎨 Shader: Normal");
}
if input.is_key_just_pressed(KeyCode::Digit2) {
self.shader_mode = 1;
println!("🎨 Shader: Fresnel");
}
if input.is_key_just_pressed(KeyCode::Digit3) {
self.shader_mode = 2;
println!("🎨 Shader: Fog");
}
if input.is_key_just_pressed(KeyCode::Digit4) {
self.sphere.set_material(Material3D::metal());
println!("⚙️ Material: Metal");
}
if input.is_key_just_pressed(KeyCode::Digit5) {
self.sphere.set_material(Material3D::plastic());
println!("⚙️ Material: Plastic");
}
if input.is_key_just_pressed(KeyCode::Digit6) {
self.sphere.set_material(Material3D::rubber());
println!("⚙️ Material: Rubber");
}
if input.is_key_just_pressed(KeyCode::Digit7) {
self.sphere.set_material(Material3D::glass());
println!("⚙️ Material: Glass");
}
if input.is_key_just_pressed(KeyCode::KeyE) {
self.particle_system.explosion(Vec3::new(0.0, 0.0, 0.0));
}
if input.is_key_just_pressed(KeyCode::KeyF) {
self.particle_system.fire(Vec3::new(0.0, -1.0, 0.0));
}
if input.is_key_just_pressed(KeyCode::KeyM) {
self.particle_system.magic(Vec3::new(0.0, 0.0, 0.0));
}
if input.is_key_just_pressed(KeyCode::KeyT) {
let direction = Vec3::new(
(self.time * 2.0).cos(),
0.5,
(self.time * 2.0).sin(),
);
self.particle_system.trail(Vec3::new(0.0, 0.0, 0.0), direction);
}
self.particle_system.update(dt);
}
fn draw(&mut self, _world: &World, frame: &mut [u8]) {
let bg_color = match self.shader_mode {
0 => [20, 20, 40],
1 => [40, 20, 40],
2 => [20, 40, 40],
_ => [20, 20, 40],
};
for pixel in frame.chunks_exact_mut(4) {
pixel[0] = bg_color[0];
pixel[1] = bg_color[1];
pixel[2] = bg_color[2];
pixel[3] = 255;
}
for particle in &self.particle_system.particles {
let screen_pos = self.project_to_screen(particle.position);
if let Some((sx, sy)) = screen_pos {
let size = (particle.size * particle.scale * 10.0) as i32;
self.draw_circle(frame, sx, sy, size, particle.color);
}
}
self.renderer3d.render_mesh(&self.cube, frame, 800, 600);
self.renderer3d.render_mesh(&self.sphere, frame, 800, 600);
self.renderer3d.render_mesh(&self.torus, frame, 800, 600);
self.draw_ui(frame);
}
}
impl Game3D {
fn project_to_screen(&self, pos: Vec3) -> Option<(i32, i32)> {
let view_pos = Vec3::new(
pos.x - self.renderer3d.camera.position.x,
pos.y - self.renderer3d.camera.position.y,
pos.z - self.renderer3d.camera.position.z,
);
if view_pos.z <= 0.0 {
return None;
}
let fov = 70.0_f32.to_radians();
let aspect = 800.0 / 600.0;
let scale = (fov / 2.0).tan();
let x = (view_pos.x / (view_pos.z * scale * aspect)) * 400.0 + 400.0;
let y = (view_pos.y / (view_pos.z * scale)) * -300.0 + 300.0;
Some((x as i32, y as i32))
}
fn draw_circle(&self, frame: &mut [u8], cx: i32, cy: i32, radius: i32, color: [u8; 4]) {
for dy in -radius..=radius {
for dx in -radius..=radius {
if dx * dx + dy * dy <= radius * radius {
let x = cx + dx;
let y = cy + dy;
if x >= 0 && x < 800 && y >= 0 && y < 600 {
let idx = ((y * 800 + x) * 4) as usize;
if idx + 3 < frame.len() {
let alpha = color[3] as f32 / 255.0;
frame[idx] = ((color[0] as f32 * alpha) + (frame[idx] as f32 * (1.0 - alpha))) as u8;
frame[idx + 1] = ((color[1] as f32 * alpha) + (frame[idx + 1] as f32 * (1.0 - alpha))) as u8;
frame[idx + 2] = ((color[2] as f32 * alpha) + (frame[idx + 2] as f32 * (1.0 - alpha))) as u8;
}
}
}
}
}
}
fn draw_ui(&self, frame: &mut [u8]) {
if !self.show_help {
let particles_text = format!("Partículas: {} | F1: Ajuda", self.particle_system.particles.len());
self.draw_text_simple(frame, 10, 10, &particles_text);
return;
}
for y in 0..180 {
for x in 0..800 {
let idx = ((y * 800 + x) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx] = (frame[idx] as f32 * 0.3) as u8;
frame[idx + 1] = (frame[idx + 1] as f32 * 0.3) as u8;
frame[idx + 2] = (frame[idx + 2] as f32 * 0.3) as u8;
}
}
}
let shader_name = match self.shader_mode {
0 => "Normal",
1 => "Fresnel",
2 => "Fog",
_ => "Unknown",
};
self.draw_text_simple(frame, 10, 10, "=== SevenX Engine v0.2.7 - Demo 3D ===");
self.draw_text_simple(frame, 10, 30, &format!("Shader: {} | Partículas: {}", shader_name, self.particle_system.particles.len()));
self.draw_text_simple(frame, 10, 50, &format!("Wireframe: {}", if self.renderer3d.wireframe { "ON" } else { "OFF" }));
self.draw_text_simple(frame, 10, 75, "Controles:");
self.draw_text_simple(frame, 10, 95, " WASD/Setas - Camera | Shift - Rapido | Scroll - Zoom");
self.draw_text_simple(frame, 10, 115, " Space - Wireframe | 1-3 - Shaders | 4-7 - Materiais");
self.draw_text_simple(frame, 10, 135, " E/F/M/T - Particulas | F1 - Toggle Ajuda");
self.draw_text_simple(frame, 10, 160, "Objetos: Cubo (Textura) | Esfera (Material) | Torus (Plastico)");
}
fn draw_text_simple(&self, frame: &mut [u8], x: i32, y: i32, text: &str) {
for (i, _c) in text.chars().enumerate() {
let px = x + (i as i32 * 8);
if px >= 0 && px < 800 && y >= 0 && y < 600 {
let idx = ((y * 800 + px) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx] = 255;
frame[idx + 1] = 255;
frame[idx + 2] = 255;
}
}
}
}
}
fn main() {
println!("🎮 SevenX Engine v0.2.7 - Demo 3D Avançado");
println!("✨ Novidades:");
println!(" 🎲 Texturas 3D (Checkerboard)");
println!(" ⚙️ Materiais PBR (Metal, Plastic, Rubber, Glass)");
println!(" 🎨 Shaders Avançados (Phong, Fresnel, Fog)");
println!(" 💫 Sistema de Partículas 3D");
println!(" 🖱️ Input Avançado (Scroll, Just Pressed)");
println!();
let config = EngineConfig::default()
.with_title("SevenX Engine v0.2.7 - Demo 3D (Texturas + Materiais + Shaders)")
.with_size(800, 600);
let engine = Engine::with_config(config);
engine.run::<Game3D>();
}