finished animation code, however needs a triangle test

pull/4/head
Milk.H 2024-04-26 12:14:02 +01:00
parent 8cee2b5661
commit 977c1baca3
Signed by: milk
GPG Key ID: 94C7CB70FFF80593
4 changed files with 100 additions and 12 deletions

View File

@ -7,6 +7,7 @@ use std::time::{Duration, Instant};
use glow::HasContext;
use bevy_ecs::prelude::*;
use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
use winit::event::{Event, WindowEvent};
@ -117,8 +118,24 @@ fn main() {
});
// TODO write bevy Init code here
let mut world = World::new();
let mut schedule = Schedule::default();
schedule.add_systems((
renderer::test_draw
));
let init_defaults = world.register_system(renderer::initialize_defaults);
let initialize_test = world.register_system(renderer::test_init);
world.insert_resource(renderer::GL(gl.clone()));
let _ = world.run_system(init_defaults);
let _ = world.run_system(initialize_test);
let _ = event_loop.run(move |event, _ ,control_flow| {
// new_frame for Framerate Locking
let new_frame = Instant::now() + Duration::from_secs_f32(1.0/60.0);
@ -151,12 +168,13 @@ fn main() {
},
Event::MainEventsCleared => {
unsafe {
gl_surface.swap_buffers(&gl_context).unwrap();
gl.clear_color(0.0, 0.0, 0.0, 1.0);
gl.clear_color(0.0, 0.0, 0.0, 0.5);
gl.clear(glow::COLOR_BUFFER_BIT);
}
schedule.run(&mut world);
gl_surface.swap_buffers(&gl_context).unwrap();
},
// TODO to be implemented

View File

@ -6,18 +6,18 @@ use bevy_ecs::prelude::*;
/// SpriteSheet Struct for Representing a Spritesheet
///
/// WARNING while it is very fast to clone the spritesheet, it is assumed that that
/// the spritesheet object is the only one of it's kind, when it gets dropped it will unload
/// the underlying texture
/// the spritesheet object is the only one of it's kind, so before it gets dropped make sure to delete
/// the texture from vram
#[derive(Clone)]
pub struct SpriteSheet
{
texture_id: glow::NativeTexture,
pub texture_id: glow::NativeTexture,
// NOTE where the spritesheet is saved
// really only use here is just to stop saving copies
path: String,
pub path: String,
// NOTE amount of Horizontal Cuts, a spritesheet with 5 frames of animation will have 5 horizontal cuts
cuts_x: u32,
pub cuts_x: u32,
// NOTE possibly making it check vertically for saving multiple animations in one Texture?
//cuts_y: u32,
@ -26,7 +26,7 @@ pub struct SpriteSheet
// offsets: Vec<cgmath::Vec2<f32>>
// NOTE Hold frames, if 0 it means it will be displayed for only 1 frame, 1 means it will be held for 2 etc
hold: Vec<u32>
pub hold: Vec<u32>
}
impl SpriteSheet
@ -57,14 +57,35 @@ pub struct Animator
{
// NOTE sprite sheets in a hashmap
pub spritesheets: HashMap<AnimationType, SpriteSheet>,
// NOTE current is possibly unneeded as it would be the job of a different System/Component to manage that
pub current: AnimationType
pub current: AnimationType,
// NOTE have a shader option to apply a different shader
//pub shader: Option<shader::Shader>
pub frame_time: f32
}
impl Default for Animator
{
fn default() -> Self
{
Animator {
spritesheets: HashMap::new(),
current: AnimationType::Idle,
frame_time: 0.0,
}
}
}
// TODO should pre-jump and jump frames be seperate?
// WIP all the animations that *could* show up, most of the air ones are expected to exist
// However just because an AnimationType is in this list doesn't mean it has to exist or be loaded in
pub enum AnimationType{
#[derive(PartialEq, Eq, Hash)]
pub enum AnimationType
{
// Basic Animations, universal
Idle,
StandUp,

View File

@ -13,6 +13,8 @@ use core::slice;
use bevy_ecs::prelude::*;
use glow::HasContext;
use self::animation::Animator;
/// OpenGL context Resource
#[derive(Resource)]
pub struct GL(pub std::sync::Arc<glow::Context>);
@ -59,8 +61,11 @@ pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>)
let ebo = Some(gl.0.create_buffer().unwrap());
gl.0.bind_vertex_array(vao);
gl.0.bind_buffer(glow::ARRAY_BUFFER, vbo);
// pass buffers
let data = core::slice::from_raw_parts(
VERTICES.as_ptr() as *const u8,
@ -101,3 +106,47 @@ pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>)
commands.insert_resource(DefaultShader(shader));
}
pub fn test_init(mut commands: Commands, gl: Res<GL>)
{
let mut animator = Animator::default();
let spritesheet = animation::SpriteSheet::new("data/sprite1.png", &gl.0, 4, Vec::new());
animator.spritesheets.insert(animation::AnimationType::Idle, spritesheet);
commands.spawn(animator);
}
pub fn test_draw(mut query: Query<&mut Animator>,
gl: Res<GL>,
vao: Res<DefaultVAO>,
shader: Res<DefaultShader>
)
{
for mut animator in query.iter_mut()
{
animator.frame_time += 0.1;
let frame_time = animator.frame_time.clone();
let sheet = &animator
.spritesheets
.get(&animator.current)
.unwrap();
shader.0.Use(&gl.0);
shader.0.set_float(&gl.0, "frameCount", 1.0 / (sheet.cuts_x as f32));
shader.0.set_float(&gl.0, "frameTime", frame_time.floor() + 1.0);
shader.0.set_float(&gl.0, "scale", 1.0);
// NOTE this is where you would put the position
shader.0.set_vector2(&gl.0, "uniPos", cgmath::Vector2::new(0.0, 0.0));
unsafe{
gl.0.bind_vertex_array(Some(vao.0));
gl.0.bind_texture(glow::TEXTURE_2D, Some(sheet.texture_id));
gl.0.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT, 0);
}
}
}

View File

@ -32,8 +32,8 @@ impl Shader
pub fn new(path: &str, gl: &glow::Context) -> Shader
{
//read file contents
let VERT_SHADER = fs::read_to_string(format!("/data/shaders/{path}/shader.vert")).unwrap();
let FRAG_SHADER = fs::read_to_string(format!("/data/shaders/{path}/shader.frag")).unwrap();
let VERT_SHADER = fs::read_to_string(format!("data/shaders/{path}/shader.vert")).unwrap();
let FRAG_SHADER = fs::read_to_string(format!("data/shaders/{path}/shader.frag")).unwrap();
//create vertex shader
let vertex_shader = unsafe {gl.create_shader(glow::VERTEX_SHADER).unwrap() };