pull/4/head
Milk.H 2024-05-07 13:45:51 +02:00
parent e1c61d6799
commit 0028bd31c3
Signed by: milk
GPG Key ID: 1C656AF758F96101
6 changed files with 409 additions and 432 deletions

View File

@ -1,37 +1,24 @@
/// Configs Module /// Configs Module
///
///
use serde::{Deserialize, Serialize};
use ron; use ron;
///
///
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Configs pub struct Configs {}
{
}
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct DisplayConfigs pub struct DisplayConfigs {
{
// TODO set Resolutions // TODO set Resolutions
//Resolution: //Resolution:
// i think thats it tbqh // i think thats it tbqh
} }
#[derive(Deserialize, Serialize)]
pub struct InputConfigs {}
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct InputConfigs pub struct KeyboardConfig {
{
}
#[derive(Deserialize, Serialize)]
pub struct KeyboardConfig
{
// directionals // directionals
Up: u32, Up: u32,
Down: u32, Down: u32,
@ -50,13 +37,11 @@ pub struct KeyboardConfig
// Macros // Macros
PunchMacro: u32, PunchMacro: u32,
KickMacro: u32 KickMacro: u32,
} }
impl Default for KeyboardConfig impl Default for KeyboardConfig {
{ fn default() -> Self {
fn default() -> Self
{
KeyboardConfig { KeyboardConfig {
Up: ScanCodes::W, Up: ScanCodes::W,
Down: ScanCodes::S, Down: ScanCodes::S,
@ -69,9 +54,8 @@ impl Default for KeyboardConfig
MediumKick: ScanCodes::J, MediumKick: ScanCodes::J,
HeavyKick: ScanCodes::K, HeavyKick: ScanCodes::K,
PunchMacro: ScanCodes::P, PunchMacro: ScanCodes::P,
KickMacro: ScanCodes::L KickMacro: ScanCodes::L,
} }
} }
} }
@ -80,68 +64,67 @@ impl Default for KeyboardConfig
/// TODO finish this /// TODO finish this
/// UNTESTED AND UNFINISHED /// UNTESTED AND UNFINISHED
#[repr(u32)] #[repr(u32)]
pub enum ScanCodes pub enum ScanCodes {
{ Escape = 0x01,
Escape = 0x01, Key1 = 0x02,
Key1 = 0x02, Key2 = 0x03,
Key2 = 0x03, Key3 = 0x04,
Key3 = 0x04, Key4 = 0x05,
Key4 = 0x05, Key5 = 0x06,
Key5 = 0x06, Key6 = 0x07,
Key6 = 0x07, Key7 = 0x08,
Key7 = 0x08, Key8 = 0x09,
Key8 = 0x09, Key9 = 0x0a,
Key9 = 0x0a, Key0 = 0x0b,
Key0 = 0x0b, Minus = 0x0c,
Minus = 0x0c, Equal = 0x0d,
Equal = 0x0d, BackSpace = 0x0e,
BackSpace = 0x0e, Tab = 0x0f,
Tab = 0x0f, Q = 0x10,
Q = 0x10, W = 0x11,
W = 0x11, E = 0x12,
E = 0x12, R = 0x13,
R = 0x13, T = 0x14,
T = 0x14, Y = 0x15,
Y = 0x15, U = 0x16,
U = 0x16, I = 0x17,
I = 0x17, O = 0x18,
O = 0x18, P = 0x19,
P = 0x19, OpenBracket = 0x1a,
OpenBracket = 0x1a,
CloseBrack = 0x1b, CloseBrack = 0x1b,
Enter = 0x1c, Enter = 0x1c,
LCtrl = 0x1d, LCtrl = 0x1d,
A = 0x1e, A = 0x1e,
S = 0x1f, S = 0x1f,
D = 0x20, D = 0x20,
F = 0x21, F = 0x21,
G = 0x22, G = 0x22,
H = 0x23, H = 0x23,
J = 0x24, J = 0x24,
K = 0x25, K = 0x25,
L = 0x26, L = 0x26,
SemiColon = 0x27, SemiColon = 0x27,
Quote = 0x28, Quote = 0x28,
Tilde = 0x29, Tilde = 0x29,
LShift = 0x2a, LShift = 0x2a,
Pipe = 0x2b, Pipe = 0x2b,
Z = 0x2c, Z = 0x2c,
X = 0x2d, X = 0x2d,
C = 0x2e, C = 0x2e,
V = 0x2f, V = 0x2f,
B = 0x30, B = 0x30,
N = 0x31, N = 0x31,
M = 0x32, M = 0x32,
// TODO figure out what these are called lmao // TODO figure out what these are called lmao
// "<" and ">" // "<" and ">"
LeftTri = 0x33, LeftTri = 0x33,
RightTri = 0x34, RightTri = 0x34,
QMark = 0x35, QMark = 0x35,
RShift = 0x36, RShift = 0x36,
KeyPad = 0x37, KeyPad = 0x37,
LAlt = 0x38, LAlt = 0x38,
Space = 0x39, Space = 0x39,
Caps = 0x3a, Caps = 0x3a,
// NOTE Skip the Function Keys, // NOTE Skip the Function Keys,
// Delusional // Delusional
// will have to do logic later to just ignore the call for that lmao // will have to do logic later to just ignore the call for that lmao
@ -154,16 +137,16 @@ pub enum ScanCodes
KeyPad4 = 0x4b, KeyPad4 = 0x4b,
KeyPad5 = 0x4c, KeyPad5 = 0x4c,
KeyPad6 = 0x4d, KeyPad6 = 0x4d,
KeyPadPlus = 0x4e, KeyPadPlus = 0x4e,
KeyPad1 = 0x4f, KeyPad1 = 0x4f,
KeyPad2 = 0x50, KeyPad2 = 0x50,
KeyPad3 = 0x51, KeyPad3 = 0x51,
KeyPad0 = 0x52, KeyPad0 = 0x52,
KeyPadDot = 0x53, KeyPadDot = 0x53,
// NOTE don't bother with the ones after this, these are super important // NOTE don't bother with the ones after this, these are super important
// (for some degenerates) // (for some degenerates)
UpArrow = 0x67, UpArrow = 0x67,
LeftArrow = 0x69, LeftArrow = 0x69,
RightArrow = 0x6a, RightArrow = 0x6a,
DownArrow = 0x6c DownArrow = 0x6c,
} }

View File

@ -1,81 +1,67 @@
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use egui::Key; use egui::Key;
use winit::event;
use std::sync::Arc;
use egui_glow::EguiGlow; use egui_glow::EguiGlow;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc;
use winit::event;
pub struct Gui pub struct Gui {
{
egui_ctx: EguiGlow, egui_ctx: EguiGlow,
menus: MenuManager, menus: MenuManager,
window: Arc<winit::window::Window>, window: Arc<winit::window::Window>,
} }
impl Gui impl Gui {
{ pub fn new(ctx: EguiGlow, window: Arc<winit::window::Window>) -> Self {
pub fn new(ctx: EguiGlow, window: Arc<winit::window::Window>) -> Self
{
let mut menus = MenuManager::new(); let mut menus = MenuManager::new();
menus.add(Menu::Hello); menus.add(Menu::Hello);
Self Self {
{
egui_ctx: ctx, egui_ctx: ctx,
menus, menus,
window window,
} }
} }
pub fn passEvent(&mut self, event: &event::WindowEvent) -> bool pub fn passEvent(&mut self, event: &event::WindowEvent) -> bool {
{
self.egui_ctx.on_event(event).consumed self.egui_ctx.on_event(event).consumed
} }
pub fn run(&mut self, world: &mut World) pub fn run(&mut self, world: &mut World) {
{
let mut to_be_removed = Vec::new(); let mut to_be_removed = Vec::new();
self.egui_ctx.run(&self.window, |ctx| self.egui_ctx.run(&self.window, |ctx| {
{ for (key, value) in &mut self.menus.0.iter_mut() {
for (key, value) in &mut self.menus.0.iter_mut() match value {
{ Menu::Hello => {
match value if hellotest(ctx) {
{ to_be_removed.push(*key);
Menu::Hello => if hellotest(ctx) }
{ }
to_be_removed.push(*key); Menu::Second => (),
}, }
Menu::Second => () }
});
} for remove in to_be_removed {
}
});
for remove in to_be_removed
{
self.menus.0.remove(&remove); self.menus.0.remove(&remove);
} }
self.egui_ctx.paint(&self.window); self.egui_ctx.paint(&self.window);
} }
} }
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum Menu pub enum Menu {
{
Hello, Hello,
Second Second,
} }
fn hellotest(ctx: &egui::Context) -> bool fn hellotest(ctx: &egui::Context) -> bool {
{
let mut open = true; let mut open = true;
egui::Window::new("hello there") egui::Window::new("hello there")
.open(&mut open) .open(&mut open)
.show(ctx, |ui| { .show(ctx, |ui| {
if ui.button("hello").clicked() if ui.button("hello").clicked() {
{
println!("hai"); println!("hai");
} }
}); });
@ -85,19 +71,15 @@ fn hellotest(ctx: &egui::Context) -> bool
struct MenuManager(pub HashMap<u8, Menu>, u8); struct MenuManager(pub HashMap<u8, Menu>, u8);
impl MenuManager impl MenuManager {
{ pub fn new() -> Self {
pub fn new() -> Self Self {
{
Self
{
0: HashMap::new(), 0: HashMap::new(),
1: 0 1: 0,
} }
} }
pub fn add(&mut self, new: Menu) pub fn add(&mut self, new: Menu) {
{
self.0.insert(self.1, new); self.0.insert(self.1, new);
self.1 = self.1.wrapping_add(1); self.1 = self.1.wrapping_add(1);
} }

View File

@ -1,4 +1,3 @@
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::thread; use std::thread;
@ -7,64 +6,56 @@ use std::time::{Duration, Instant};
use egui_glow::EguiGlow; use egui_glow::EguiGlow;
use glow::HasContext; use glow::HasContext;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use gui::Gui; use gui::Gui;
use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
use winit::event::{Event, WindowEvent}; use winit::event::{Event, WindowEvent};
use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
use glutin::{config::ConfigTemplateBuilder, context::ContextAttributesBuilder};
use glutin_winit::DisplayBuilder;
use glutin::{prelude::*, context::Version};
use glutin_winit::{self, GlWindow};
use glutin::display::GetGlDisplay; use glutin::display::GetGlDisplay;
use glutin::{config::ConfigTemplateBuilder, context::ContextAttributesBuilder};
use glutin::{context::Version, prelude::*};
use glutin_winit::DisplayBuilder;
use glutin_winit::{self, GlWindow};
pub mod renderer;
pub mod gui; pub mod gui;
pub mod renderer;
fn main() { fn main() {
// NOTE initialization code here // NOTE initialization code here
// create Event Loop // create Event Loop
let event_loop = EventLoopBuilder::new().build(); let event_loop = EventLoopBuilder::new().build();
// set event loop to poll events every frame // set event loop to poll events every frame
//event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll); //event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let window_builder = Some(
let window_builder = Some(WindowBuilder::new() WindowBuilder::new()
.with_transparent(false) .with_transparent(false)
.with_title("MGQ Fighter Test") .with_title("MGQ Fighter Test"),
); );
let template = ConfigTemplateBuilder::new() let template = ConfigTemplateBuilder::new().with_transparency(false);
.with_transparency(false);
let display_builder = DisplayBuilder::new() let display_builder = DisplayBuilder::new().with_window_builder(window_builder);
.with_window_builder(window_builder);
let (window, gl_config) = display_builder let (window, gl_config) = display_builder
.build(&event_loop, template, |configs| { .build(&event_loop, template, |configs| {
configs.reduce(|accum, config| { configs
let transparency_check = config.supports_transparency().unwrap_or(true) .reduce(|accum, config| {
& !accum.supports_transparency().unwrap_or(true); let transparency_check = config.supports_transparency().unwrap_or(true)
& !accum.supports_transparency().unwrap_or(true);
if transparency_check || config.num_samples() > accum.num_samples() { if transparency_check || config.num_samples() > accum.num_samples() {
config config
} } else {
accum
else { }
accum })
} .unwrap()
})
.unwrap()
}) })
.unwrap(); .unwrap();
// probably not needed here // probably not needed here
//let raw_window_handle = window.as_ref().map(|window| window.window_handle() //let raw_window_handle = window.as_ref().map(|window| window.window_handle()
// .unwrap() // .unwrap()
@ -79,32 +70,38 @@ fn main() {
.build(None); .build(None);
let compatibility_context_attributes = ContextAttributesBuilder::new() let compatibility_context_attributes = ContextAttributesBuilder::new()
.with_context_api(glutin::context::ContextApi::OpenGl(Some(Version::new(3, 3)))) .with_context_api(glutin::context::ContextApi::OpenGl(Some(Version::new(
3, 3,
))))
.build(None); .build(None);
// decide on the opengl Context to use, will use the newest one available // decide on the opengl Context to use, will use the newest one available
// If the device does NOT at least support opengl 3.3 it will crash // If the device does NOT at least support opengl 3.3 it will crash
// opengl 3.3 is supported by most 64 bit computers // opengl 3.3 is supported by most 64 bit computers
let mut not_current_gl_context = Some(unsafe { let mut not_current_gl_context = Some(unsafe {
gl_display.create_context(&gl_config, &context_attributes).unwrap_or_else(|_| { gl_display
gl_display.create_context(&gl_config, &fallback_attributes).unwrap_or_else(|_| { .create_context(&gl_config, &context_attributes)
.unwrap_or_else(|_| {
gl_display gl_display
.create_context(&gl_config, &compatibility_context_attributes) .create_context(&gl_config, &fallback_attributes)
.expect("get a newer Computer") .unwrap_or_else(|_| {
}, gl_display
) .create_context(&gl_config, &compatibility_context_attributes)
}) .expect("get a newer Computer")
})
})
}); });
// current Window Reference Counter // current Window Reference Counter
let window = Arc::new(window.unwrap()); let window = Arc::new(window.unwrap());
let attrs = window.build_surface_attributes(<_>::default()); let attrs = window.build_surface_attributes(<_>::default());
let gl_surface = unsafe { let gl_surface = unsafe {
gl_config.display().create_window_surface(&gl_config, &attrs).unwrap() gl_config
.display()
.create_window_surface(&gl_config, &attrs)
.unwrap()
}; };
let gl_context = not_current_gl_context let gl_context = not_current_gl_context
@ -123,7 +120,7 @@ fn main() {
let mut gui = Gui::new( let mut gui = Gui::new(
EguiGlow::new(&event_loop, Arc::clone(&gl), None), EguiGlow::new(&event_loop, Arc::clone(&gl), None),
window.clone() window.clone(),
); );
unsafe { unsafe {
@ -131,16 +128,12 @@ fn main() {
gl.blend_func(glow::ONE, glow::ZERO); gl.blend_func(glow::ONE, glow::ZERO);
} }
// TODO write bevy Init code here // TODO write bevy Init code here
let mut world = World::new(); let mut world = World::new();
let mut schedule = Schedule::default(); let mut schedule = Schedule::default();
schedule.add_systems(( schedule.add_systems((renderer::test_draw));
renderer::test_draw
));
let init_defaults = world.register_system(renderer::initialize_defaults); let init_defaults = world.register_system(renderer::initialize_defaults);
let initialize_test = world.register_system(renderer::test_init); let initialize_test = world.register_system(renderer::test_init);
@ -149,43 +142,35 @@ fn main() {
let _ = world.run_system(init_defaults); let _ = world.run_system(init_defaults);
let _ = world.run_system(initialize_test); 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);
match event match event {
{
Event::WindowEvent { event, .. } => { Event::WindowEvent { event, .. } => {
if gui.passEvent(&event) == false {
if gui.passEvent(&event) == false match event {
{
match event
{
WindowEvent::CloseRequested => { WindowEvent::CloseRequested => {
println!("closing gracefully"); println!("closing gracefully");
control_flow.set_exit(); control_flow.set_exit();
}, }
WindowEvent::Resized(size) => { WindowEvent::Resized(size) => {
if size.width !=0 && size.height !=0 { if size.width != 0 && size.height != 0 {
gl_surface.resize( gl_surface.resize(
&gl_context, &gl_context,
std::num::NonZeroU32::new(size.width).unwrap(), std::num::NonZeroU32::new(size.width).unwrap(),
std::num::NonZeroU32::new(size.height).unwrap() std::num::NonZeroU32::new(size.height).unwrap(),
); );
} }
}, }
// TODO to be implemented later // TODO to be implemented later
_ => () _ => (),
}; };
} }
} }
Event::Resumed => { Event::Resumed => {}
},
Event::MainEventsCleared => { Event::MainEventsCleared => {
unsafe { unsafe {
gl.clear_color(0.0, 0.0, 0.0, 1.0); gl.clear_color(0.0, 0.0, 0.0, 1.0);
gl.clear(glow::COLOR_BUFFER_BIT); gl.clear(glow::COLOR_BUFFER_BIT);
} }
@ -194,11 +179,10 @@ fn main() {
gui.run(&mut world); gui.run(&mut world);
gl_surface.swap_buffers(&gl_context).unwrap(); gl_surface.swap_buffers(&gl_context).unwrap();
}, }
// TODO to be implemented // TODO to be implemented
_ => () _ => (),
} }
// will wait until it's time for the next frame // will wait until it's time for the next frame

View File

@ -9,15 +9,14 @@ use bevy_ecs::prelude::*;
/// the spritesheet object is the only one of it's kind, so before it gets dropped make sure to delete /// the spritesheet object is the only one of it's kind, so before it gets dropped make sure to delete
/// the texture from vram /// the texture from vram
#[derive(Clone)] #[derive(Clone)]
pub struct SpriteSheet pub struct SpriteSheet {
{
pub 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
pub 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
pub 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,35 +25,30 @@ 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
pub hold: Vec<u32> pub hold: Vec<u32>,
} }
impl SpriteSheet impl SpriteSheet {
{
/// creates a new Spritesheet /// creates a new Spritesheet
pub fn new(path: &str, gl: &glow::Context, cuts_x: u32, hold: Vec<u32>) -> Self pub fn new(path: &str, gl: &glow::Context, cuts_x: u32, hold: Vec<u32>) -> Self {
{
let texture_id = texture_from_file(path, gl); let texture_id = texture_from_file(path, gl);
SpriteSheet SpriteSheet {
{
texture_id, texture_id,
path: String::from(path), path: String::from(path),
cuts_x, cuts_x,
hold hold,
} }
} }
} }
/// Animation Component /// Animation Component
/// ///
/// currently it's using a hashmap with String keys /// currently it's using a hashmap with String keys
/// ///
/// current also uses a String to identify the spritesheet /// current also uses a String to identify the spritesheet
#[derive(Component)] #[derive(Component)]
pub struct Animator 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>,
@ -63,16 +57,11 @@ pub struct Animator
// NOTE have a shader option to apply a different shader // NOTE have a shader option to apply a different shader
//pub shader: Option<shader::Shader> //pub shader: Option<shader::Shader>
pub frame_time: f32,
pub frame_time: f32
} }
impl Default for Animator impl Default for Animator {
{ fn default() -> Self {
fn default() -> Self
{
Animator { Animator {
spritesheets: HashMap::new(), spritesheets: HashMap::new(),
current: AnimationType::Idle, current: AnimationType::Idle,
@ -84,13 +73,12 @@ impl Default for Animator
// 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
#[derive(PartialEq, Eq, Hash)] #[derive(PartialEq, Eq, Hash)]
pub enum AnimationType pub enum AnimationType {
{
// Basic Animations, universal // Basic Animations, universal
Idle, Idle,
StandUp, StandUp,
CrouchDown, // <- this is the animation of crouching down after standing CrouchDown, // <- this is the animation of crouching down after standing
Crouch, // <- this is for the loop of being crouching Crouch, // <- this is for the loop of being crouching
WalkingForward, WalkingForward,
WalkingBackward, WalkingBackward,
Guard, Guard,
@ -178,43 +166,53 @@ pub enum AnimationType
Super05, Super05,
} }
/// load texture from a filepath and return the ID /// load texture from a filepath and return the ID
/// ///
/// NOTE this function does not check if the texture has already loaded /// NOTE this function does not check if the texture has already loaded
fn texture_from_file(path: &str, gl: &glow::Context) -> glow::NativeTexture fn texture_from_file(path: &str, gl: &glow::Context) -> glow::NativeTexture {
{ let texture_id;
unsafe {
texture_id = gl.create_texture().unwrap();
let texture_id; let img = image::open(&Path::new(&path)).expect("texture failed to load");
unsafe { let img = img.flipv();
texture_id = gl.create_texture().unwrap();
let img = image::open(&Path::new(&path)).expect("texture failed to load"); let format = match img {
let img = img.flipv(); 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 format = match img { let data = img.as_bytes();
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.bind_texture(glow::TEXTURE_2D, Some(texture_id)); gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
gl.tex_image_2d(glow::TEXTURE_2D, 0, format as i32, img.width() as i32, img.height() as i32, gl.tex_parameter_i32(
0, format, glow::UNSIGNED_BYTE, Some(&data)); glow::TEXTURE_2D,
gl.generate_mipmap(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
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
} }

View File

@ -1,12 +1,10 @@
/// Render Module /// Render Module
pub mod animation;
/// ///
/// all of the code pertaining to Rendering will be written here /// all of the code pertaining to Rendering will be written here
/// ///
/// this also includes all Bevy Components and Resources relating to rendering /// this also includes all Bevy Components and Resources relating to rendering
pub mod shader; pub mod shader;
pub mod animation;
use core::slice; use core::slice;
@ -35,41 +33,31 @@ pub struct DefaultShader(pub shader::Shader);
// //
// in a line // in a line
const VERTICES: [f32; 20] = [ const VERTICES: [f32; 20] = [
// X Y Z xTex yTex // X Y Z xTex yTex
0.5, 0.5, 0.0, 1.0, 1.0, 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.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0,
-0.5, -0.5, 0.0, 0.0, 0.0,
-0.5, 0.5, 0.0, 0.0, 1.0
]; ];
// indices for the // indices for the
const INDICES: [u32; 6] = [ const INDICES: [u32; 6] = [0, 1, 3, 1, 2, 3];
0, 1, 3,
1, 2, 3
];
pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>) pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>) {
{
// create vertex array // create vertex array
let vao = unsafe { let vao = unsafe { Some(gl.0.create_vertex_array().unwrap()) };
Some(gl.0.create_vertex_array().unwrap())
};
unsafe { unsafe {
// create buffers // create buffers
let vbo = Some(gl.0.create_buffer().unwrap()); let vbo = Some(gl.0.create_buffer().unwrap());
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_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,
VERTICES.len() * core::mem::size_of::<f32>() VERTICES.len() * core::mem::size_of::<f32>(),
); );
gl.0.named_buffer_data_u8_slice(vbo.unwrap(), data, glow::STATIC_DRAW); gl.0.named_buffer_data_u8_slice(vbo.unwrap(), data, glow::STATIC_DRAW);
@ -87,11 +75,11 @@ pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>)
// Vertex Info // Vertex Info
gl.0.enable_vertex_attrib_array(0); gl.0.enable_vertex_attrib_array(0);
gl.0.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size*5, 0); gl.0.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size * 5, 0);
// Texture Coordinates // Texture Coordinates
gl.0.enable_vertex_attrib_array(1); gl.0.enable_vertex_attrib_array(1);
gl.0.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, size*5, size*3); gl.0.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, size * 5, size * 3);
// unbind buffers and arrays // unbind buffers and arrays
gl.0.bind_buffer(glow::ARRAY_BUFFER, None); gl.0.bind_buffer(glow::ARRAY_BUFFER, None);
@ -107,42 +95,44 @@ 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>) pub fn test_init(mut commands: Commands, gl: Res<GL>) {
{
let mut animator = Animator::default(); let mut animator = Animator::default();
let spritesheet = animation::SpriteSheet::new("data/sprite1.png", &gl.0, 4, Vec::new()); let spritesheet = animation::SpriteSheet::new("data/sprite1.png", &gl.0, 4, Vec::new());
animator.spritesheets.insert(animation::AnimationType::Idle, spritesheet); animator
.spritesheets
.insert(animation::AnimationType::Idle, spritesheet);
commands.spawn(animator); commands.spawn(animator);
} }
pub fn test_draw(mut query: Query<&mut Animator>, pub fn test_draw(
gl: Res<GL>, mut query: Query<&mut Animator>,
vao: Res<DefaultVAO>, gl: Res<GL>,
shader: Res<DefaultShader> vao: Res<DefaultVAO>,
) shader: Res<DefaultShader>,
{ ) {
for mut animator in query.iter_mut() for mut animator in query.iter_mut() {
{
animator.frame_time += 0.1; animator.frame_time += 0.1;
let frame_time = animator.frame_time.clone(); let frame_time = animator.frame_time.clone();
let sheet = &animator let sheet = &animator.spritesheets.get(&animator.current).unwrap();
.spritesheets
.get(&animator.current)
.unwrap();
shader.0.Use(&gl.0); shader.0.Use(&gl.0);
shader.0.set_float(&gl.0, "frameCount", 1.0 / (sheet.cuts_x as f32)); shader
shader.0.set_float(&gl.0, "frameTime", frame_time.floor() + 1.0); .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); shader.0.set_float(&gl.0, "scale", 1.0);
// NOTE this is where you would put the position // NOTE this is where you would put the position
shader.0.set_vector2(&gl.0, "uniPos", cgmath::Vector2::new(0.0, 0.0)); shader
.0
.set_vector2(&gl.0, "uniPos", cgmath::Vector2::new(0.0, 0.0));
unsafe{ unsafe {
gl.0.bind_vertex_array(Some(vao.0)); gl.0.bind_vertex_array(Some(vao.0));
gl.0.bind_texture(glow::TEXTURE_2D, Some(sheet.texture_id)); gl.0.bind_texture(glow::TEXTURE_2D, Some(sheet.texture_id));

View File

@ -3,135 +3,175 @@ use glow::*;
use std::fs; use std::fs;
use std::str; use std::str;
/// Shader Struct for creating and using shaders in the Context of engine
///
/// Shader Struct for creating and using shaders in the Context of engine
///
#[derive(Clone)] #[derive(Clone)]
pub struct Shader { pub struct Shader {
pub ID: NativeProgram,
pub ID: NativeProgram, pub path: String,
}
pub path: String 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 {
//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();
//create vertex shader
let vertex_shader = unsafe { gl.create_shader(glow::VERTEX_SHADER).unwrap() };
unsafe {
gl.shader_source(vertex_shader, &VERT_SHADER);
gl.compile_shader(vertex_shader);
}
// create fragment shader
let fragment_shader = unsafe { gl.create_shader(glow::FRAGMENT_SHADER).unwrap() };
unsafe {
gl.shader_source(fragment_shader, &FRAG_SHADER);
gl.compile_shader(fragment_shader);
if !gl.get_shader_compile_status(fragment_shader) {
panic!(
"Error, Compiling Fragment Shader: {}",
gl.get_shader_info_log(fragment_shader)
);
}
let shader_program = gl.create_program().unwrap();
gl.attach_shader(shader_program, vertex_shader);
gl.attach_shader(shader_program, fragment_shader);
gl.link_program(shader_program);
if !gl.get_program_link_status(shader_program) {
panic!(
"Error, Linking Shader Program {}",
gl.get_program_info_log(shader_program)
);
}
gl.detach_shader(shader_program, vertex_shader);
gl.detach_shader(shader_program, fragment_shader);
gl.delete_shader(vertex_shader);
gl.delete_shader(fragment_shader);
Shader {
ID: shader_program,
path: path.to_string(),
}
}
} }
// return program
/// uses Shader
impl Shader ///
{ pub fn Use(&self, gl: &glow::Context) {
/// Shader Constructor, will read, Compile and Create a GLSL Program for use unsafe {
/// gl.use_program(Some(self.ID));
/// 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
{
//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();
//create vertex shader
let vertex_shader = unsafe {gl.create_shader(glow::VERTEX_SHADER).unwrap() };
unsafe {
gl.shader_source(vertex_shader, &VERT_SHADER);
gl.compile_shader(vertex_shader);
}
// create fragment shader
let fragment_shader = unsafe{gl.create_shader(glow::FRAGMENT_SHADER).unwrap()};
unsafe {
gl.shader_source(fragment_shader, &FRAG_SHADER);
gl.compile_shader(fragment_shader);
if !gl.get_shader_compile_status(fragment_shader) {
panic!("Error, Compiling Fragment Shader: {}", gl.get_shader_info_log(fragment_shader));
}
let shader_program = gl.create_program().unwrap();
gl.attach_shader(shader_program, vertex_shader);
gl.attach_shader(shader_program, fragment_shader);
gl.link_program(shader_program);
if !gl.get_program_link_status(shader_program) {
panic!("Error, Linking Shader Program {}", gl.get_program_info_log(shader_program));
}
gl.detach_shader(shader_program, vertex_shader);
gl.detach_shader(shader_program, fragment_shader);
gl.delete_shader(vertex_shader);
gl.delete_shader(fragment_shader);
Shader {
ID: shader_program,
path: path.to_string()
}
}
}
// return program
/// uses Shader
///
pub fn Use(&self, gl: &glow::Context)
{
unsafe {gl.use_program(Some(self.ID));}
}
// BOILERPLATE JUMPSCARE
//pub fn set_bool(&self, gl: &glow::Context name: &str, value: bool )
//{unsafe {gl.uniform_1_bool(gl.get_uniform_location(self.ID, name).as_ref(), value);}}
pub fn set_int(&self, gl: &glow::Context, name: &str, value: i32 )
{unsafe {gl.uniform_1_i32(gl.get_uniform_location(self.ID, name).as_ref(), value);}}
pub fn set_float(&self, gl: &glow::Context, name: &str, value: f32 )
{unsafe {gl.uniform_1_f32(gl.get_uniform_location(self.ID, name).as_ref(), value);}}
pub fn set_vector2(&self, gl: &glow::Context, name: &str, value: cgmath::Vector2<f32> )
{unsafe {gl.uniform_2_f32(gl.get_uniform_location(self.ID, name).as_ref(), value[0], value[1]);}}
pub fn set_vector2d(&self, gl: &glow::Context, name: &str, x: f32, y: f32)
{unsafe {gl.uniform_2_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y);}}
pub fn set_vector3(&self, gl: &glow::Context, name: &str, value: cgmath::Vector3<f32> )
{unsafe {gl.uniform_3_f32(gl.get_uniform_location(self.ID, name).as_ref(), value[0], value[1], value[2]);}}
pub fn set_vector3d(&self, gl: &glow::Context, name: &str, x: f32, y: f32, z: f32 )
{unsafe {gl.uniform_3_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y, z);}}
pub fn set_vector4(&self, gl: &glow::Context, name: &str, value: &cgmath::Vector4<f32> )
{unsafe {gl.uniform_4_f32(gl.get_uniform_location(self.ID, name).as_ref(), value[0], value[1], value[2], value[3]);}}
pub fn set_vector4d(&self, gl: &glow::Context, name: &str, x: f32, y: f32, z: f32, w: f32)
{unsafe {gl.uniform_4_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y, z, w);}}
//pub fn setMat2(&self, name: &str, value: cgmath::Matrix2<f32>)
pub fn set_mat3(&self, gl: &glow::Context, name: &str, value: cgmath::Matrix3<f32>)
{
let nums = vec![value.x.x, value.x.y, value.x.z,
value.y.x, value.y.y, value.y.z,
value.z.x, value.z.y, value.z.z];
unsafe
{
gl.uniform_matrix_3_f32_slice(gl.get_uniform_location(self.ID, name).as_ref(), false, nums.as_ref());
}
}
pub fn set_mat4(&self, gl: &glow::Context, name: &str, value: &cgmath::Matrix4<f32>)
{
let nums = vec![value.x.x, value.x.y, value.x.z, value.x.w,
value.y.x, value.y.y, value.y.z, value.y.w,
value.z.x, value.z.y, value.z.z, value.z.w,
value.w.x, value.w.y, value.w.z, value.w.w];
unsafe
{
gl.uniform_matrix_4_f32_slice(gl.get_uniform_location(self.ID, name).as_ref(), false, nums.as_ref());
}
}
} }
}
// BOILERPLATE JUMPSCARE
//pub fn set_bool(&self, gl: &glow::Context name: &str, value: bool )
//{unsafe {gl.uniform_1_bool(gl.get_uniform_location(self.ID, name).as_ref(), value);}}
pub fn set_int(&self, gl: &glow::Context, name: &str, value: i32) {
unsafe {
gl.uniform_1_i32(gl.get_uniform_location(self.ID, name).as_ref(), value);
}
}
pub fn set_float(&self, gl: &glow::Context, name: &str, value: f32) {
unsafe {
gl.uniform_1_f32(gl.get_uniform_location(self.ID, name).as_ref(), value);
}
}
pub fn set_vector2(&self, gl: &glow::Context, name: &str, value: cgmath::Vector2<f32>) {
unsafe {
gl.uniform_2_f32(
gl.get_uniform_location(self.ID, name).as_ref(),
value[0],
value[1],
);
}
}
pub fn set_vector2d(&self, gl: &glow::Context, name: &str, x: f32, y: f32) {
unsafe {
gl.uniform_2_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y);
}
}
pub fn set_vector3(&self, gl: &glow::Context, name: &str, value: cgmath::Vector3<f32>) {
unsafe {
gl.uniform_3_f32(
gl.get_uniform_location(self.ID, name).as_ref(),
value[0],
value[1],
value[2],
);
}
}
pub fn set_vector3d(&self, gl: &glow::Context, name: &str, x: f32, y: f32, z: f32) {
unsafe {
gl.uniform_3_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y, z);
}
}
pub fn set_vector4(&self, gl: &glow::Context, name: &str, value: &cgmath::Vector4<f32>) {
unsafe {
gl.uniform_4_f32(
gl.get_uniform_location(self.ID, name).as_ref(),
value[0],
value[1],
value[2],
value[3],
);
}
}
pub fn set_vector4d(&self, gl: &glow::Context, name: &str, x: f32, y: f32, z: f32, w: f32) {
unsafe {
gl.uniform_4_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y, z, w);
}
}
//pub fn setMat2(&self, name: &str, value: cgmath::Matrix2<f32>)
pub fn set_mat3(&self, gl: &glow::Context, name: &str, value: cgmath::Matrix3<f32>) {
let nums = vec![
value.x.x, value.x.y, value.x.z, value.y.x, value.y.y, value.y.z, value.z.x, value.z.y,
value.z.z,
];
unsafe {
gl.uniform_matrix_3_f32_slice(
gl.get_uniform_location(self.ID, name).as_ref(),
false,
nums.as_ref(),
);
}
}
pub fn set_mat4(&self, gl: &glow::Context, name: &str, value: &cgmath::Matrix4<f32>) {
let nums = vec![
value.x.x, value.x.y, value.x.z, value.x.w, value.y.x, value.y.y, value.y.z, value.y.w,
value.z.x, value.z.y, value.z.z, value.z.w, value.w.x, value.w.y, value.w.z, value.w.w,
];
unsafe {
gl.uniform_matrix_4_f32_slice(
gl.get_uniform_location(self.ID, name).as_ref(),
false,
nums.as_ref(),
);
}
}
}