A Quadrilateral Cowboy clone intended to help me learn Game Dev

Successfully rendered UI onto terminal screen

+41 -32
+1
assets/fonts/NotoSans.ttf
··· 1 + /usr/share/fonts/truetype/noto/NotoSans-Regular.ttf
+3 -1
src/game.rs
··· 13 13 14 14 #[derive(Resource)] 15 15 pub struct GameAssets { 16 - pub terminal: Handle<Scene> 16 + pub terminal_primitive0: Handle<Mesh>, 17 + pub terminal_primitive1: Handle<Mesh>, 18 + pub terminal_chassis_mat: Handle<StandardMaterial> 17 19 }
+34 -31
src/level.rs
··· 1 - use bevy::{asset::RenderAssetUsages, camera::{RenderTarget}, prelude::*, render::render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages}}; 1 + use bevy::{asset::RenderAssetUsages, camera::RenderTarget, prelude::*, render::render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages}, math::Affine2}; 2 2 use crate::game::{GameAssets, GameState}; 3 3 4 4 pub fn plugin(app: &mut App) { ··· 39 39 40 40 fn load_resources(mut commands: Commands, asset_server: Res<AssetServer>, mut next_state: ResMut<NextState<GameState>>) { 41 41 let assets = GameAssets{ 42 - terminal: asset_server.load("models/terminal.glb#Scene0") 42 + terminal_primitive0: asset_server.load("models/terminal.glb#Mesh0/Primitive0"), 43 + terminal_primitive1: asset_server.load("models/terminal.glb#Mesh0/Primitive1"), 44 + terminal_chassis_mat: asset_server.load("models/terminal.glb#Material0") 43 45 }; 44 46 commands.insert_resource(assets); 45 47 next_state.set(GameState::Test); 46 48 } 47 49 48 - fn run_test(mut commands: Commands, _game_assets: Res<GameAssets>, mut images: ResMut<Assets<Image>>, mut materials: ResMut<Assets<StandardMaterial>>, mut meshes: ResMut<Assets<Mesh>>, asset_server: Res<AssetServer>) { 50 + fn run_test(mut commands: Commands, game_assets: Res<GameAssets>, mut meshes: ResMut<Assets<Mesh>>, mut images: ResMut<Assets<Image>>, mut materials: ResMut<Assets<StandardMaterial>>, asset_server: Res<AssetServer>) { 51 + if let Some(mesh) = meshes.get_mut(&game_assets.terminal_primitive1) { 52 + // A simple Quad (4 vertices) UV mapping 53 + let uvs = vec![ 54 + [1.0, 1.0], [0.0, 1.0], // Top Left, Top Right 55 + [1.0, 0.0], [0.0, 0.0] // Bottom Left, Bottom Right 56 + ]; 57 + 58 + // This overwrites the existing UV_0 attribute 59 + mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs); 60 + } 61 + 49 62 let size = Extent3d{ 50 63 width: 512, 51 64 height: 512, ··· 85 98 align_items: AlignItems::Center, 86 99 ..default() 87 100 }, 88 - BackgroundColor(bevy::color::palettes::css::GRAY.into()), 101 + BackgroundColor(bevy::color::palettes::css::BLACK.into()), 89 102 UiTargetCamera(texture_camera) 90 103 )).with_children(|parent| { 91 104 parent.spawn(( ··· 113 126 }); 114 127 }); 115 128 116 - let mesh_handle = meshes.add(Cuboid::default()); 117 - 118 129 let material_handle = materials.add(StandardMaterial{ 119 130 base_color_texture: Some(image_handle), 120 131 reflectance: 0.02, 121 132 unlit: false, 133 + uv_transform: Affine2::from_scale_angle_translation( 134 + Vec2::new(1.0, 1.0), // Scale (e.g., 2.0 zooms in) 135 + 0.0, // Rotation in radians 136 + Vec2::new(0.0, 0.0) // Offset (X, Y) 137 + ), 122 138 ..default() 123 139 }); 124 140 125 - commands.spawn(( 126 - Mesh3d(mesh_handle), 127 - MeshMaterial3d(material_handle), 128 - Transform::from_xyz(0.0, 0.0, 1.5).with_rotation(Quat::from_rotation_x(std::f32::consts::PI)) 129 - )); 130 - 131 - commands.spawn(( 132 - Camera3d::default(), 133 - Transform::from_xyz(0.0, 0.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y), 134 - Camera{ 135 - order: 0, 136 - ..default() 137 - } 138 - )); 139 - 140 - /* 141 141 // terminal mesh 142 142 commands.spawn(( 143 - SceneRoot(game_assets.terminal.clone()), 143 + Node::default(), 144 144 Transform::from_translation(Vec3::ZERO).with_rotation(Quat::from_rotation_y(-std::f32::consts::FRAC_PI_2)) 145 - )); 145 + )).with_children(|parent| { 146 + parent.spawn(( 147 + Mesh3d(game_assets.terminal_primitive0.clone()), 148 + MeshMaterial3d(game_assets.terminal_chassis_mat.clone()) 149 + )); 150 + 151 + parent.spawn(( 152 + Mesh3d(game_assets.terminal_primitive1.clone()), 153 + MeshMaterial3d(material_handle) 154 + )); 155 + }); 146 156 // light 147 157 commands.spawn(( 148 158 PointLight{ ··· 154 164 // camera 155 165 commands.spawn(( 156 166 Camera3d::default(), 157 - Camera{ 158 - order: -1, 159 - clear_color: Color::WHITE.into(), 160 - ..default() 161 - }, 162 - RenderTarget::Image(image_handle.clone().into()), 163 167 Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y) 164 168 )); 165 - */ 166 169 }
+3
src/main.rs
··· 1 1 use bevy::{prelude::*, input::common_conditions::input_toggle_active}; 2 + use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; 2 3 3 4 mod game; 4 5 mod level; ··· 6 7 fn main() { 7 8 App::new() 8 9 .add_plugins(DefaultPlugins) 10 + .add_plugins(EguiPlugin::default()) 11 + .add_plugins(WorldInspectorPlugin::new().run_if(input_toggle_active(false, KeyCode::Escape))) 9 12 .init_state::<game::GameState>() 10 13 .add_plugins(level::plugin) 11 14 .init_resource::<level::LevelManifest>()