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 glow::HasContext;
use bevy_ecs::prelude::*;
use winit::{event_loop::EventLoopBuilder, window::WindowBuilder}; use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
use winit::event::{Event, WindowEvent}; use winit::event::{Event, WindowEvent};
@ -117,8 +118,24 @@ fn main() {
}); });
// TODO write bevy Init code here // 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| { let _ = event_loop.run(move |event, _ ,control_flow| {
// new_frame for Framerate Locking // new_frame for Framerate Locking
let new_frame = Instant::now() + Duration::from_secs_f32(1.0/60.0); let new_frame = Instant::now() + Duration::from_secs_f32(1.0/60.0);
@ -151,12 +168,13 @@ fn main() {
}, },
Event::MainEventsCleared => { Event::MainEventsCleared => {
unsafe { 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); gl.clear(glow::COLOR_BUFFER_BIT);
} }
schedule.run(&mut world);
gl_surface.swap_buffers(&gl_context).unwrap();
}, },
// TODO to be implemented // TODO to be implemented

View File

@ -6,18 +6,18 @@ use bevy_ecs::prelude::*;
/// SpriteSheet Struct for Representing a Spritesheet /// SpriteSheet Struct for Representing a Spritesheet
/// ///
/// WARNING while it is very fast to clone the spritesheet, it is assumed that that /// 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 spritesheet object is the only one of it's kind, so before it gets dropped make sure to delete
/// the underlying texture /// the texture from vram
#[derive(Clone)] #[derive(Clone)]
pub struct SpriteSheet pub struct SpriteSheet
{ {
texture_id: glow::NativeTexture, pub texture_id: glow::NativeTexture,
// NOTE where the spritesheet is saved // NOTE where the spritesheet is saved
// really only use here is just to stop saving copies // 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 // 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? // NOTE possibly making it check vertically for saving multiple animations in one Texture?
//cuts_y: u32, //cuts_y: u32,
@ -26,7 +26,7 @@ pub struct SpriteSheet
// offsets: Vec<cgmath::Vec2<f32>> // 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 // 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 impl SpriteSheet
@ -57,14 +57,35 @@ pub struct Animator
{ {
// NOTE sprite sheets in a hashmap // NOTE sprite sheets in a hashmap
pub spritesheets: HashMap<AnimationType, SpriteSheet>, pub spritesheets: HashMap<AnimationType, SpriteSheet>,
// NOTE current is possibly unneeded as it would be the job of a different System/Component to manage that // 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? // 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 // 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 // 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 // Basic Animations, universal
Idle, Idle,
StandUp, StandUp,

View File

@ -13,6 +13,8 @@ use core::slice;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use glow::HasContext; use glow::HasContext;
use self::animation::Animator;
/// OpenGL context Resource /// OpenGL context Resource
#[derive(Resource)] #[derive(Resource)]
pub struct GL(pub std::sync::Arc<glow::Context>); 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()); let ebo = Some(gl.0.create_buffer().unwrap());
gl.0.bind_vertex_array(vao);
gl.0.bind_buffer(glow::ARRAY_BUFFER, vbo); gl.0.bind_buffer(glow::ARRAY_BUFFER, vbo);
// pass buffers // pass buffers
let data = core::slice::from_raw_parts( let data = core::slice::from_raw_parts(
VERTICES.as_ptr() as *const u8, 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)); 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 pub fn new(path: &str, gl: &glow::Context) -> Shader
{ {
//read file contents //read file contents
let VERT_SHADER = fs::read_to_string(format!("/data/shaders/{path}/shader.vert")).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(); let FRAG_SHADER = fs::read_to_string(format!("data/shaders/{path}/shader.frag")).unwrap();
//create vertex shader //create vertex shader
let vertex_shader = unsafe {gl.create_shader(glow::VERTEX_SHADER).unwrap() }; let vertex_shader = unsafe {gl.create_shader(glow::VERTEX_SHADER).unwrap() };