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

View File

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

View File

@ -1,4 +1,3 @@
use std::rc::Rc;
use std::sync::Arc;
use std::thread;
@ -7,64 +6,56 @@ use std::time::{Duration, Instant};
use egui_glow::EguiGlow;
use glow::HasContext;
use bevy_ecs::prelude::*;
use gui::Gui;
use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
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::{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 renderer;
fn main() {
// NOTE initialization code here
// create Event Loop
let event_loop = EventLoopBuilder::new().build();
// set event loop to poll events every frame
//event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let window_builder = Some(WindowBuilder::new()
.with_transparent(false)
.with_title("MGQ Fighter Test")
let window_builder = Some(
WindowBuilder::new()
.with_transparent(false)
.with_title("MGQ Fighter Test"),
);
let template = ConfigTemplateBuilder::new()
.with_transparency(false);
let template = ConfigTemplateBuilder::new().with_transparency(false);
let display_builder = DisplayBuilder::new()
.with_window_builder(window_builder);
let display_builder = DisplayBuilder::new().with_window_builder(window_builder);
let (window, gl_config) = display_builder
.build(&event_loop, template, |configs| {
configs.reduce(|accum, config| {
let transparency_check = config.supports_transparency().unwrap_or(true)
& !accum.supports_transparency().unwrap_or(true);
configs
.reduce(|accum, config| {
let transparency_check = config.supports_transparency().unwrap_or(true)
& !accum.supports_transparency().unwrap_or(true);
if transparency_check || config.num_samples() > accum.num_samples() {
config
}
else {
accum
}
})
.unwrap()
if transparency_check || config.num_samples() > accum.num_samples() {
config
} else {
accum
}
})
.unwrap()
})
.unwrap();
// probably not needed here
//let raw_window_handle = window.as_ref().map(|window| window.window_handle()
// .unwrap()
@ -79,32 +70,38 @@ fn main() {
.build(None);
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);
// 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
// opengl 3.3 is supported by most 64 bit computers
let mut not_current_gl_context = Some(unsafe {
gl_display.create_context(&gl_config, &context_attributes).unwrap_or_else(|_| {
gl_display.create_context(&gl_config, &fallback_attributes).unwrap_or_else(|_| {
gl_display
.create_context(&gl_config, &context_attributes)
.unwrap_or_else(|_| {
gl_display
.create_context(&gl_config, &compatibility_context_attributes)
.expect("get a newer Computer")
},
)
})
.create_context(&gl_config, &fallback_attributes)
.unwrap_or_else(|_| {
gl_display
.create_context(&gl_config, &compatibility_context_attributes)
.expect("get a newer Computer")
})
})
});
// current Window Reference Counter
let window = Arc::new(window.unwrap());
let attrs = window.build_surface_attributes(<_>::default());
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
@ -123,7 +120,7 @@ fn main() {
let mut gui = Gui::new(
EguiGlow::new(&event_loop, Arc::clone(&gl), None),
window.clone()
window.clone(),
);
unsafe {
@ -131,16 +128,12 @@ fn main() {
gl.blend_func(glow::ONE, glow::ZERO);
}
// TODO write bevy Init code here
let mut world = World::new();
let mut schedule = Schedule::default();
schedule.add_systems((
renderer::test_draw
));
schedule.add_systems((renderer::test_draw));
let init_defaults = world.register_system(renderer::initialize_defaults);
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(initialize_test);
let _ = event_loop.run(move |event, _ ,control_flow| {
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);
match event
{
let new_frame = Instant::now() + Duration::from_secs_f32(1.0 / 60.0);
match event {
Event::WindowEvent { event, .. } => {
if gui.passEvent(&event) == false
{
match event
{
if gui.passEvent(&event) == false {
match event {
WindowEvent::CloseRequested => {
println!("closing gracefully");
control_flow.set_exit();
},
}
WindowEvent::Resized(size) => {
if size.width !=0 && size.height !=0 {
if size.width != 0 && size.height != 0 {
gl_surface.resize(
&gl_context,
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
_ => ()
_ => (),
};
}
}
Event::Resumed => {
},
Event::Resumed => {}
Event::MainEventsCleared => {
unsafe {
gl.clear_color(0.0, 0.0, 0.0, 1.0);
gl.clear(glow::COLOR_BUFFER_BIT);
}
@ -194,11 +179,10 @@ fn main() {
gui.run(&mut world);
gl_surface.swap_buffers(&gl_context).unwrap();
},
}
// TODO to be implemented
_ => ()
_ => (),
}
// 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 texture from vram
#[derive(Clone)]
pub struct SpriteSheet
{
pub struct SpriteSheet {
pub texture_id: glow::NativeTexture,
// NOTE where the spritesheet is saved
// 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
pub cuts_x: u32,
pub cuts_x: u32,
// NOTE possibly making it check vertically for saving multiple animations in one Texture?
//cuts_y: u32,
@ -26,35 +25,30 @@ 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
pub hold: Vec<u32>
pub hold: Vec<u32>,
}
impl SpriteSheet
{
impl 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);
SpriteSheet
{
SpriteSheet {
texture_id,
path: String::from(path),
cuts_x,
hold
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
{
pub struct Animator {
// NOTE sprite sheets in a hashmap
pub spritesheets: HashMap<AnimationType, SpriteSheet>,
@ -63,16 +57,11 @@ pub struct Animator
// NOTE have a shader option to apply a different shader
//pub shader: Option<shader::Shader>
pub frame_time: f32
pub frame_time: f32,
}
impl Default for Animator
{
fn default() -> Self
{
impl Default for Animator {
fn default() -> Self {
Animator {
spritesheets: HashMap::new(),
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
// However just because an AnimationType is in this list doesn't mean it has to exist or be loaded in
#[derive(PartialEq, Eq, Hash)]
pub enum AnimationType
{
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
Crouch, // <- this is for the loop of being crouching
WalkingForward,
WalkingBackward,
Guard,
@ -178,43 +166,53 @@ pub enum AnimationType
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
{
fn texture_from_file(path: &str, gl: &glow::Context) -> glow::NativeTexture {
let texture_id;
unsafe {
texture_id = gl.create_texture().unwrap();
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 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 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();
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_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,
);
}
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
texture_id
}

View File

@ -1,12 +1,10 @@
/// Render Module
pub mod animation;
///
/// 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;
@ -35,41 +33,31 @@ pub struct DefaultShader(pub shader::Shader);
//
// 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
// 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
];
const INDICES: [u32; 6] = [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
let vao = unsafe {
Some(gl.0.create_vertex_array().unwrap())
};
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_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,
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);
@ -87,11 +75,11 @@ pub fn initialize_defaults(mut commands: Commands, gl: Res<GL>)
// Vertex Info
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
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
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));
}
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 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);
}
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()
{
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();
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, "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));
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_texture(glow::TEXTURE_2D, Some(sheet.texture_id));

View File

@ -3,135 +3,175 @@ use glow::*;
use std::fs;
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)]
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
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
///
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());
}
}
/// 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(),
);
}
}
}