Compare commits
5 Commits
518ccff2aa
...
70d598bf13
Author | SHA1 | Date |
---|---|---|
Milk.H | 70d598bf13 | |
Milk.H | c78e556210 | |
Milk.H | 71add6cfc6 | |
Milk.H | 0028bd31c3 | |
Milk.H | e1c61d6799 |
|
@ -11,11 +11,12 @@ cgmath = "0.18.0"
|
||||||
egui = "0.23.0"
|
egui = "0.23.0"
|
||||||
egui-winit = "0.23.0"
|
egui-winit = "0.23.0"
|
||||||
egui_glow = { version = "0.23.0", features = ["winit"] }
|
egui_glow = { version = "0.23.0", features = ["winit"] }
|
||||||
gilrs = "0.10.7"
|
gilrs = { version = "0.10.7", features = ["serde-serialize"] }
|
||||||
glow = "0.12.3"
|
glow = "0.12.3"
|
||||||
glutin = "0.30.10"
|
glutin = "0.30.10"
|
||||||
glutin-winit = "0.3.0"
|
glutin-winit = "0.3.0"
|
||||||
image = "0.25.1"
|
image = "0.25.1"
|
||||||
raw-window-handle = "0.6.1"
|
raw-window-handle = "0.6.1"
|
||||||
ron = "0.8.1"
|
ron = "0.8.1"
|
||||||
|
serde = { version = "1.0.199", features = ["derive"] }
|
||||||
winit = "0.28.7"
|
winit = "0.28.7"
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
/// Configs Module
|
||||||
|
use gilrs::ev::Button;
|
||||||
|
///
|
||||||
|
///
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Configs {}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct DisplayConfigs {
|
||||||
|
// TODO set Resolutions
|
||||||
|
//Resolution:
|
||||||
|
// i think thats it tbqh
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||||
|
pub struct InputConfigs {
|
||||||
|
keyboard_single: KeyboardConfig,
|
||||||
|
//Keyboard_duo_1: KeyboardConfig,
|
||||||
|
// keyboard_duo_2: KeyboardConfig
|
||||||
|
Controller1: Option<ControllerConfig>,
|
||||||
|
Controller2: Option<ControllerConfig>,
|
||||||
|
Controller3: Option<ControllerConfig>,
|
||||||
|
Controller4: Option<ControllerConfig>,
|
||||||
|
Controller5: Option<ControllerConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct ControllerConfig {
|
||||||
|
// directionals
|
||||||
|
Up: Button,
|
||||||
|
Down: Button,
|
||||||
|
Right: Button,
|
||||||
|
Left: Button,
|
||||||
|
|
||||||
|
// the punches
|
||||||
|
LightPunch: Button,
|
||||||
|
MediumPunch: Button,
|
||||||
|
HeavyPunch: Button,
|
||||||
|
|
||||||
|
// the kicks
|
||||||
|
LightKick: Button,
|
||||||
|
MediumKick: Button,
|
||||||
|
HeavyKick: Button,
|
||||||
|
|
||||||
|
// Macros
|
||||||
|
PunchMacro: Option<Button>,
|
||||||
|
KickMacro: Option<Button>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ControllerConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
Up: Button::DPadUp,
|
||||||
|
Down: Button::DPadDown,
|
||||||
|
Right: Button::DPadRight,
|
||||||
|
Left: Button::DPadLeft,
|
||||||
|
|
||||||
|
LightPunch: Button::West,
|
||||||
|
MediumPunch: Button::North,
|
||||||
|
HeavyPunch: Button::RightTrigger,
|
||||||
|
|
||||||
|
LightKick: Button::South,
|
||||||
|
MediumKick: Button::East,
|
||||||
|
HeavyKick: Button::LeftTrigger,
|
||||||
|
|
||||||
|
PunchMacro: Some(Button::RightTrigger2),
|
||||||
|
KickMacro: Some(Button::LeftTrigger2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct KeyboardConfig {
|
||||||
|
// directionals
|
||||||
|
Up: ScanCodes,
|
||||||
|
Down: ScanCodes,
|
||||||
|
Right: ScanCodes,
|
||||||
|
Left: ScanCodes,
|
||||||
|
|
||||||
|
// the punches
|
||||||
|
LightPunch: ScanCodes,
|
||||||
|
MediumPunch: ScanCodes,
|
||||||
|
HeavyPunch: ScanCodes,
|
||||||
|
|
||||||
|
// the kicks
|
||||||
|
LightKick: ScanCodes,
|
||||||
|
MediumKick: ScanCodes,
|
||||||
|
HeavyKick: ScanCodes,
|
||||||
|
|
||||||
|
// Macros
|
||||||
|
PunchMacro: Option<ScanCodes>,
|
||||||
|
KickMacro: Option<ScanCodes>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for KeyboardConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
KeyboardConfig {
|
||||||
|
Up: ScanCodes::W,
|
||||||
|
Down: ScanCodes::S,
|
||||||
|
Right: ScanCodes::D,
|
||||||
|
Left: ScanCodes::A,
|
||||||
|
LightPunch: ScanCodes::U,
|
||||||
|
MediumPunch: ScanCodes::I,
|
||||||
|
HeavyPunch: ScanCodes::O,
|
||||||
|
LightKick: ScanCodes::H,
|
||||||
|
MediumKick: ScanCodes::J,
|
||||||
|
HeavyKick: ScanCodes::K,
|
||||||
|
PunchMacro: Some(ScanCodes::P),
|
||||||
|
KickMacro: Some(ScanCodes::L),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// these ones are written after this
|
||||||
|
/// https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
|
||||||
|
/// TODO finish this
|
||||||
|
/// UNTESTED AND UNFINISHED
|
||||||
|
#[repr(u32)]
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
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,
|
||||||
|
SemiColon = 0x27,
|
||||||
|
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,
|
||||||
|
// NOTE Skip the Function Keys,
|
||||||
|
// Delusional
|
||||||
|
// will have to do logic later to just ignore the call for that lmao
|
||||||
|
Numlock = 0x45,
|
||||||
|
ScrollLock = 0x46,
|
||||||
|
KeyPad7 = 0x47,
|
||||||
|
KeyPad8 = 0x48,
|
||||||
|
KeyPad9 = 0x49,
|
||||||
|
KeyPadMinus = 0x4a,
|
||||||
|
KeyPad4 = 0x4b,
|
||||||
|
KeyPad5 = 0x4c,
|
||||||
|
KeyPad6 = 0x4d,
|
||||||
|
KeyPadPlus = 0x4e,
|
||||||
|
KeyPad1 = 0x4f,
|
||||||
|
KeyPad2 = 0x50,
|
||||||
|
KeyPad3 = 0x51,
|
||||||
|
KeyPad0 = 0x52,
|
||||||
|
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,
|
||||||
|
}
|
80
src/gui.rs
80
src/gui.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
128
src/main.rs
128
src/main.rs
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
@ -7,64 +5,57 @@ 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 config;
|
||||||
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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue