renamed renderer, and worked more on the anicode
renamed spritesheet.rs to animation.rs, and i will be putting all of the animation related code in therepull/4/head
parent
ef8760a70f
commit
8cee2b5661
|
@ -1,6 +0,0 @@
|
|||
/// Render Module
|
||||
/// all of the code pertaining to Rendering will be written here
|
||||
/// this also includes all Bevy Components and Resources relating to rendering
|
||||
|
||||
pub mod shader;
|
||||
pub mod spritesheet;
|
|
@ -1,57 +0,0 @@
|
|||
use glow::HasContext;
|
||||
use std::path::Path;
|
||||
|
||||
|
||||
/// SpriteSheet Struct for Representing a Spritesheet
|
||||
/// feel free to clone
|
||||
#[derive(Clone)]
|
||||
pub struct SpriteSheet
|
||||
{
|
||||
texture_id: glow::NativeTexture,
|
||||
// NOTE where the spritesheet is saved
|
||||
path: String,
|
||||
cuts_x: u32,
|
||||
// NOTE possibly making it check vertically
|
||||
//cuts_y: u32,
|
||||
// NOTE maybe add an offset for each sprite
|
||||
// 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>
|
||||
}
|
||||
|
||||
/// load texture from a filepath and return the ID
|
||||
/// NOTE this function does not check if the texture has already loaded
|
||||
fn texture_from_file(path: &str, gl: &glow::Context) -> glow::NativeTexture
|
||||
{
|
||||
|
||||
let texture_id;
|
||||
unsafe {
|
||||
texture_id = gl.create_texture().unwrap();
|
||||
|
||||
let img = image::open(&Path::new(&path)).expect("texture failed to load");
|
||||
let img = img.flipv();
|
||||
|
||||
let format = match img {
|
||||
image::DynamicImage::ImageLuma8(_) => glow::RED,
|
||||
image::DynamicImage::ImageLumaA8(_) => glow::RG,
|
||||
image::DynamicImage::ImageRgb8(_) => glow::RGB,
|
||||
image::DynamicImage::ImageRgba8(_) => glow::RGBA,
|
||||
_ => panic!("unknown image format at {path}")
|
||||
};
|
||||
|
||||
let data = img.as_bytes();
|
||||
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(texture_id));
|
||||
gl.tex_image_2d(glow::TEXTURE_2D, 0, format as i32, img.width() as i32, img.height() as i32,
|
||||
0, format, glow::UNSIGNED_BYTE, Some(&data));
|
||||
gl.generate_mipmap(glow::TEXTURE_2D);
|
||||
|
||||
|
||||
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
|
||||
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
|
||||
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST_MIPMAP_NEAREST as i32);
|
||||
|
||||
}
|
||||
|
||||
texture_id
|
||||
}
|
|
@ -17,7 +17,7 @@ use glutin::{prelude::*, context::Version};
|
|||
use glutin_winit::{self, GlWindow};
|
||||
use glutin::display::GetGlDisplay;
|
||||
|
||||
pub mod Renderer;
|
||||
pub mod renderer;
|
||||
fn main() {
|
||||
|
||||
// NOTE initialization code here
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
use glow::HasContext;
|
||||
use std::{collections::HashMap, path::Path};
|
||||
|
||||
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
|
||||
#[derive(Clone)]
|
||||
pub struct SpriteSheet
|
||||
{
|
||||
texture_id: glow::NativeTexture,
|
||||
// NOTE where the spritesheet is saved
|
||||
// really only use here is just to stop saving copies
|
||||
path: String,
|
||||
|
||||
// NOTE amount of Horizontal Cuts, a spritesheet with 5 frames of animation will have 5 horizontal cuts
|
||||
cuts_x: u32,
|
||||
|
||||
// NOTE possibly making it check vertically for saving multiple animations in one Texture?
|
||||
//cuts_y: u32,
|
||||
|
||||
// NOTE maybe add an offset for each sprite
|
||||
// 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>
|
||||
}
|
||||
|
||||
impl SpriteSheet
|
||||
{
|
||||
/// creates a new Spritesheet
|
||||
pub fn new(path: &str, gl: &glow::Context, cuts_x: u32, hold: Vec<u32>) -> Self
|
||||
{
|
||||
let texture_id = texture_from_file(path, gl);
|
||||
|
||||
SpriteSheet
|
||||
{
|
||||
texture_id,
|
||||
path: String::from(path),
|
||||
cuts_x,
|
||||
hold
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Animation Component
|
||||
///
|
||||
/// currently it's using a hashmap with String keys
|
||||
///
|
||||
/// current also uses a String to identify the spritesheet
|
||||
#[derive(Component)]
|
||||
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
|
||||
}
|
||||
|
||||
// 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{
|
||||
// Basic Animations, universal
|
||||
Idle,
|
||||
StandUp,
|
||||
CrouchDown, // <- this is the animation of crouching down after standing
|
||||
Crouch, // <- this is for the loop of being crouching
|
||||
WalkingForward,
|
||||
WalkingBackward,
|
||||
Guard,
|
||||
CrouchGuard,
|
||||
AirGuard,
|
||||
JumpNeutral,
|
||||
JumpBackward,
|
||||
JumpForward,
|
||||
Fall,
|
||||
// Extra Movement animations, not universal
|
||||
AirDash,
|
||||
AirBackDash,
|
||||
Running,
|
||||
BackDashing,
|
||||
// Normals, Universal
|
||||
StandLP,
|
||||
StandMP,
|
||||
StandHP,
|
||||
StandLK,
|
||||
StandMK,
|
||||
StandHK,
|
||||
CrouchLP,
|
||||
CrouchMP,
|
||||
CrouchHP,
|
||||
CrouchLK,
|
||||
CrouchMK,
|
||||
CrouchHK,
|
||||
AirLP,
|
||||
AirMP,
|
||||
AirHP,
|
||||
AirLK,
|
||||
AirMK,
|
||||
AirHK,
|
||||
// hit animations, expect more complicated ones to show up, Universal
|
||||
CrouchHit,
|
||||
StandHit,
|
||||
AirHit,
|
||||
// command Normals, maybe would be Better to have them in the Specials
|
||||
CommandNormal01,
|
||||
CommandNormal02,
|
||||
CommandNormal03,
|
||||
CommandNormal04,
|
||||
CommandNormal05,
|
||||
CommandNormal06,
|
||||
CommandNormal07,
|
||||
CommandNormal08,
|
||||
CommandNormal09,
|
||||
CommandNormal10,
|
||||
// Specials, any Miscallenous Animations will also end up here
|
||||
// This includes fireballs
|
||||
// Rekkas will be seperated into different Animations
|
||||
Special01,
|
||||
Special02,
|
||||
Special03,
|
||||
Special04,
|
||||
Special05,
|
||||
Special06,
|
||||
Special07,
|
||||
Special08,
|
||||
Special09,
|
||||
Special10,
|
||||
Special11,
|
||||
Special12,
|
||||
Special13,
|
||||
Special14,
|
||||
Special15,
|
||||
// Supers
|
||||
Super01,
|
||||
Super02,
|
||||
Super03,
|
||||
Super04,
|
||||
Super05,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// load texture from a filepath and return the ID
|
||||
///
|
||||
/// NOTE this function does not check if the texture has already loaded
|
||||
fn texture_from_file(path: &str, gl: &glow::Context) -> glow::NativeTexture
|
||||
{
|
||||
|
||||
let texture_id;
|
||||
unsafe {
|
||||
texture_id = gl.create_texture().unwrap();
|
||||
|
||||
let img = image::open(&Path::new(&path)).expect("texture failed to load");
|
||||
let img = img.flipv();
|
||||
|
||||
let format = match img {
|
||||
image::DynamicImage::ImageLuma8(_) => glow::RED,
|
||||
image::DynamicImage::ImageLumaA8(_) => glow::RG,
|
||||
image::DynamicImage::ImageRgb8(_) => glow::RGB,
|
||||
image::DynamicImage::ImageRgba8(_) => glow::RGBA,
|
||||
_ => panic!("unknown image format at {path}")
|
||||
};
|
||||
|
||||
let data = img.as_bytes();
|
||||
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(texture_id));
|
||||
gl.tex_image_2d(glow::TEXTURE_2D, 0, format as i32, img.width() as i32, img.height() as i32,
|
||||
0, format, glow::UNSIGNED_BYTE, Some(&data));
|
||||
gl.generate_mipmap(glow::TEXTURE_2D);
|
||||
|
||||
|
||||
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
|
||||
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
|
||||
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST_MIPMAP_NEAREST as i32);
|
||||
|
||||
}
|
||||
|
||||
texture_id
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/// Render Module
|
||||
///
|
||||
/// all of the code pertaining to Rendering will be written here
|
||||
///
|
||||
/// this also includes all Bevy Components and Resources relating to rendering
|
||||
|
||||
pub mod shader;
|
||||
pub mod animation;
|
||||
|
||||
|
||||
use core::slice;
|
||||
|
||||
use bevy_ecs::prelude::*;
|
||||
use glow::HasContext;
|
||||
|
||||
/// OpenGL context Resource
|
||||
#[derive(Resource)]
|
||||
pub struct GL(pub std::sync::Arc<glow::Context>);
|
||||
|
||||
/// Default Vertex Array Object, Every 2d Square object with a texture would only need this
|
||||
#[derive(Resource)]
|
||||
pub struct DefaultVAO(pub glow::NativeVertexArray);
|
||||
|
||||
/// Default Shader, this will be much more likely to be different
|
||||
///
|
||||
/// for all systems The Default Shader is assumed to be the animation shader located at data/shaders/AnimationShader
|
||||
#[derive(Resource)]
|
||||
pub struct DefaultShader(pub shader::Shader);
|
||||
|
||||
// NOTE systems start here
|
||||
|
||||
// a square with texture coordinates
|
||||
//
|
||||
// in a line
|
||||
const VERTICES: [f32; 20] = [
|
||||
// X Y Z xTex yTex
|
||||
0.5, 0.5, 0.0, 1.0, 1.0,
|
||||
0.5, -0.5, 0.0, 1.0, 0.0,
|
||||
-0.5, -0.5, 0.0, 0.0, 0.0,
|
||||
-0.5, 0.5, 0.0, 0.0, 1.0
|
||||
];
|
||||
|
||||
// indices for the
|
||||
const INDICES: [u32; 6] = [
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
];
|
||||
|
||||
pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>)
|
||||
{
|
||||
// create vertex array
|
||||
let vao = unsafe {
|
||||
Some(gl.0.create_vertex_array().unwrap())
|
||||
};
|
||||
|
||||
unsafe {
|
||||
// create buffers
|
||||
let vbo = Some(gl.0.create_buffer().unwrap());
|
||||
let ebo = Some(gl.0.create_buffer().unwrap());
|
||||
|
||||
|
||||
gl.0.bind_buffer(glow::ARRAY_BUFFER, vbo);
|
||||
|
||||
// pass buffers
|
||||
let data = core::slice::from_raw_parts(
|
||||
VERTICES.as_ptr() as *const u8,
|
||||
VERTICES.len() * core::mem::size_of::<f32>()
|
||||
);
|
||||
|
||||
gl.0.named_buffer_data_u8_slice(vbo.unwrap(), data, glow::STATIC_DRAW);
|
||||
|
||||
gl.0.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, ebo);
|
||||
|
||||
let data = slice::from_raw_parts(
|
||||
INDICES.as_ptr() as *const u8,
|
||||
INDICES.len() * core::mem::size_of::<u32>(),
|
||||
);
|
||||
|
||||
gl.0.named_buffer_data_u8_slice(ebo.unwrap(), data, glow::STATIC_DRAW);
|
||||
|
||||
let size = core::mem::size_of::<f32>() as i32;
|
||||
|
||||
// Vertex Info
|
||||
gl.0.enable_vertex_attrib_array(0);
|
||||
gl.0.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size*5, 0);
|
||||
|
||||
// Texture Coordinates
|
||||
gl.0.enable_vertex_attrib_array(2);
|
||||
gl.0.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, size*5, size*3);
|
||||
|
||||
// unbind buffers and arrays
|
||||
gl.0.bind_buffer(glow::ARRAY_BUFFER, None);
|
||||
|
||||
gl.0.bind_vertex_array(None);
|
||||
}
|
||||
|
||||
// insert Default Vao
|
||||
commands.insert_resource(DefaultVAO(vao.unwrap()));
|
||||
|
||||
let shader = shader::Shader::new("AnimationShader", &gl.0);
|
||||
|
||||
commands.insert_resource(DefaultShader(shader));
|
||||
}
|
|
@ -20,11 +20,13 @@ pub struct Shader {
|
|||
impl Shader
|
||||
{
|
||||
/// Shader Constructor, will read, Compile and Create a GLSL Program for use
|
||||
///
|
||||
/// currently panics if the files can't be found or the shader is wrong
|
||||
///
|
||||
///
|
||||
/// # Example
|
||||
/// `let shader = Shader::new("Example", &gl);`
|
||||
///
|
||||
/// if the String given was "Example" the Program expects both shaders to be in the directory "data/shaders/Example/"
|
||||
/// with the vertex shader being called "shader.vert" and fragment "shader.frag"
|
||||
pub fn new(path: &str, gl: &glow::Context) -> Shader
|
Loading…
Reference in New Issue