mirror of https://github.com/AxioDL/metaforce.git
Automatically remap controllers; separate cxxbridge build files
This commit is contained in:
parent
ed4d38073b
commit
8286f006cf
|
@ -31,24 +31,24 @@ fn main() {
|
||||||
let cxx_flag = "-std=c++17";
|
let cxx_flag = "-std=c++17";
|
||||||
#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]
|
#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]
|
||||||
let cxx_flag = "-std=gnu++17";
|
let cxx_flag = "-std=gnu++17";
|
||||||
cxx_build::bridge("src/lib.rs")
|
cxx_build::bridge("src/cxxbridge.rs")
|
||||||
.include("include")
|
.include("include")
|
||||||
.include(zeus_include.clone())
|
.include(zeus_include.clone())
|
||||||
.flag(cxx_flag)
|
.flag(cxx_flag)
|
||||||
.compile("aurora");
|
.compile("aurora");
|
||||||
println!("cargo:rerun-if-changed=src/lib.rs");
|
println!("cargo:rerun-if-changed=src/cxxbridge.rs");
|
||||||
cxx_build::bridge("src/shaders/mod.rs")
|
cxx_build::bridge("src/shaders/cxxbridge.rs")
|
||||||
.include("include")
|
.include("include")
|
||||||
.include(zeus_include.clone())
|
.include(zeus_include.clone())
|
||||||
.flag(cxx_flag)
|
.flag(cxx_flag)
|
||||||
.compile("aurora_shaders");
|
.compile("aurora_shaders");
|
||||||
println!("cargo:rerun-if-changed=src/shaders/mod.rs");
|
println!("cargo:rerun-if-changed=src/shaders/cxxbridge.rs");
|
||||||
cxx_build::bridge("src/imgui.rs")
|
cxx_build::bridge("src/imgui/cxxbridge.rs")
|
||||||
.include("include")
|
.include("include")
|
||||||
.include(zeus_include.clone())
|
.include(zeus_include.clone())
|
||||||
.include(imgui_include.clone())
|
.include(imgui_include.clone())
|
||||||
.include(imgui_engine_include.clone())
|
.include(imgui_engine_include.clone())
|
||||||
.flag(cxx_flag)
|
.flag(cxx_flag)
|
||||||
.compile("aurora_imgui");
|
.compile("aurora_imgui");
|
||||||
println!("cargo:rerun-if-changed=src/imgui.rs");
|
println!("cargo:rerun-if-changed=src/imgui/cxxbridge.rs");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
use sdl2::controller::{Axis, Button};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
app_run, get_args, get_backend, get_backend_string, get_dxt_compression_supported,
|
||||||
|
get_window_size,
|
||||||
|
sdl::{get_controller_player_index, set_controller_player_index},
|
||||||
|
set_fullscreen, set_window_title, App, WindowContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cxx::bridge(namespace = "aurora")]
|
||||||
|
pub(crate) mod ffi {
|
||||||
|
unsafe extern "C++" {
|
||||||
|
include!("aurora.hpp");
|
||||||
|
pub(crate) type AppDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C++" {
|
||||||
|
include!("lib.hpp");
|
||||||
|
pub(crate) fn App_onAppLaunched(cb: Pin<&mut AppDelegate>);
|
||||||
|
pub(crate) fn App_onAppIdle(cb: Pin<&mut AppDelegate>, dt: f32) -> bool;
|
||||||
|
pub(crate) fn App_onAppDraw(cb: Pin<&mut AppDelegate>);
|
||||||
|
pub(crate) fn App_onAppPostDraw(cb: Pin<&mut AppDelegate>);
|
||||||
|
pub(crate) fn App_onAppWindowResized(cb: Pin<&mut AppDelegate>, size: &WindowSize);
|
||||||
|
pub(crate) fn App_onAppWindowMoved(cb: Pin<&mut AppDelegate>, x: i32, y: i32);
|
||||||
|
pub(crate) fn App_onAppExiting(cb: Pin<&mut AppDelegate>);
|
||||||
|
// Input
|
||||||
|
pub(crate) fn App_onCharKeyDown(cb: Pin<&mut AppDelegate>, code: u8, is_repeat: bool);
|
||||||
|
pub(crate) fn App_onCharKeyUp(cb: Pin<&mut AppDelegate>, code: u8);
|
||||||
|
pub(crate) fn App_onSpecialKeyDown(
|
||||||
|
cb: Pin<&mut AppDelegate>,
|
||||||
|
key: SpecialKey,
|
||||||
|
is_repeat: bool,
|
||||||
|
);
|
||||||
|
pub(crate) fn App_onSpecialKeyUp(cb: Pin<&mut AppDelegate>, key: SpecialKey);
|
||||||
|
// Controller
|
||||||
|
pub(crate) fn App_onControllerButton(
|
||||||
|
cb: Pin<&mut AppDelegate>,
|
||||||
|
idx: u32,
|
||||||
|
button: ControllerButton,
|
||||||
|
pressed: bool,
|
||||||
|
);
|
||||||
|
pub(crate) fn App_onControllerAxis(
|
||||||
|
cb: Pin<&mut AppDelegate>,
|
||||||
|
idx: u32,
|
||||||
|
axis: ControllerAxis,
|
||||||
|
value: i16,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Window {
|
||||||
|
pub(crate) inner: Box<WindowContext>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WindowSize {
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Backend {
|
||||||
|
Invalid,
|
||||||
|
Vulkan,
|
||||||
|
Metal,
|
||||||
|
D3D12,
|
||||||
|
D3D11,
|
||||||
|
OpenGL,
|
||||||
|
WebGPU,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ElementState {
|
||||||
|
Pressed,
|
||||||
|
Released,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MouseButton {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Middle,
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum SpecialKey {
|
||||||
|
None = 0,
|
||||||
|
F1 = 1,
|
||||||
|
F2 = 2,
|
||||||
|
F3 = 3,
|
||||||
|
F4 = 4,
|
||||||
|
F5 = 5,
|
||||||
|
F6 = 6,
|
||||||
|
F7 = 7,
|
||||||
|
F8 = 8,
|
||||||
|
F9 = 9,
|
||||||
|
F10 = 10,
|
||||||
|
F11 = 11,
|
||||||
|
F12 = 12,
|
||||||
|
Esc = 13,
|
||||||
|
Enter = 14,
|
||||||
|
Backspace = 15,
|
||||||
|
Insert = 16,
|
||||||
|
Delete = 17,
|
||||||
|
Home = 18,
|
||||||
|
End = 19,
|
||||||
|
PgUp = 20,
|
||||||
|
PgDown = 21,
|
||||||
|
Left = 22,
|
||||||
|
Right = 23,
|
||||||
|
Up = 24,
|
||||||
|
Down = 25,
|
||||||
|
Tab = 26,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct KeyboardInput {
|
||||||
|
pub scancode: u32,
|
||||||
|
pub state: ElementState,
|
||||||
|
// pub
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ControllerButton {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Back,
|
||||||
|
Guide,
|
||||||
|
Start,
|
||||||
|
LeftStick,
|
||||||
|
RightStick,
|
||||||
|
LeftShoulder,
|
||||||
|
RightShoulder,
|
||||||
|
DPadUp,
|
||||||
|
DPadDown,
|
||||||
|
DPadLeft,
|
||||||
|
DPadRight,
|
||||||
|
Other,
|
||||||
|
MAX,
|
||||||
|
}
|
||||||
|
pub enum ControllerAxis {
|
||||||
|
LeftX,
|
||||||
|
LeftY,
|
||||||
|
RightX,
|
||||||
|
RightY,
|
||||||
|
TriggerLeft,
|
||||||
|
TriggerRight,
|
||||||
|
MAX,
|
||||||
|
}
|
||||||
|
pub struct Icon {
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "Rust" {
|
||||||
|
type WindowContext;
|
||||||
|
type App;
|
||||||
|
fn app_run(mut delegate: UniquePtr<AppDelegate>, icon: Icon);
|
||||||
|
fn get_args() -> Vec<String>;
|
||||||
|
fn get_window_size() -> WindowSize;
|
||||||
|
fn set_window_title(title: &CxxString);
|
||||||
|
fn get_dxt_compression_supported() -> bool;
|
||||||
|
fn get_backend() -> Backend;
|
||||||
|
fn get_backend_string() -> &'static str;
|
||||||
|
fn set_fullscreen(v: bool);
|
||||||
|
fn get_controller_player_index(which: u32) -> i32;
|
||||||
|
fn set_controller_player_index(which: u32, index: i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<Button> for ffi::ControllerButton {
|
||||||
|
fn from(button: Button) -> Self {
|
||||||
|
match button {
|
||||||
|
Button::A => ffi::ControllerButton::A,
|
||||||
|
Button::B => ffi::ControllerButton::B,
|
||||||
|
Button::X => ffi::ControllerButton::X,
|
||||||
|
Button::Y => ffi::ControllerButton::Y,
|
||||||
|
Button::Back => ffi::ControllerButton::Back,
|
||||||
|
Button::Guide => ffi::ControllerButton::Guide,
|
||||||
|
Button::Start => ffi::ControllerButton::Start,
|
||||||
|
Button::LeftStick => ffi::ControllerButton::LeftStick,
|
||||||
|
Button::RightStick => ffi::ControllerButton::RightStick,
|
||||||
|
Button::LeftShoulder => ffi::ControllerButton::LeftShoulder,
|
||||||
|
Button::RightShoulder => ffi::ControllerButton::RightShoulder,
|
||||||
|
Button::DPadUp => ffi::ControllerButton::DPadUp,
|
||||||
|
Button::DPadDown => ffi::ControllerButton::DPadDown,
|
||||||
|
Button::DPadLeft => ffi::ControllerButton::DPadLeft,
|
||||||
|
Button::DPadRight => ffi::ControllerButton::DPadRight,
|
||||||
|
_ => ffi::ControllerButton::Other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<Axis> for ffi::ControllerAxis {
|
||||||
|
fn from(axis: Axis) -> Self {
|
||||||
|
match axis {
|
||||||
|
Axis::LeftX => ffi::ControllerAxis::LeftX,
|
||||||
|
Axis::LeftY => ffi::ControllerAxis::LeftY,
|
||||||
|
Axis::RightX => ffi::ControllerAxis::RightX,
|
||||||
|
Axis::RightY => ffi::ControllerAxis::RightY,
|
||||||
|
Axis::TriggerLeft => ffi::ControllerAxis::TriggerLeft,
|
||||||
|
Axis::TriggerRight => ffi::ControllerAxis::TriggerRight,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use crate::{
|
||||||
|
gpu::DeviceHolder,
|
||||||
|
imgui::{ImGuiEngine_AddTexture, ImGuiState},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cxx::bridge(namespace = "metaforce")]
|
||||||
|
pub(crate) mod ffi {
|
||||||
|
unsafe extern "C++" {
|
||||||
|
include!("ImGuiEngine.hpp");
|
||||||
|
pub(crate) fn ImGuiEngine_Initialize(scale: f32);
|
||||||
|
pub(crate) fn ImGuiEngine_AddTextures(state: &mut ImGuiState, device: &DeviceHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "Rust" {
|
||||||
|
type ImGuiState;
|
||||||
|
type DeviceHolder;
|
||||||
|
fn ImGuiEngine_AddTexture(
|
||||||
|
state: &mut ImGuiState,
|
||||||
|
device: &DeviceHolder,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
data: &[u8],
|
||||||
|
) -> usize;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,8 @@
|
||||||
|
use cxxbridge::ffi;
|
||||||
|
|
||||||
use crate::{gpu::DeviceHolder, imgui_backend};
|
use crate::{gpu::DeviceHolder, imgui_backend};
|
||||||
|
|
||||||
#[cxx::bridge(namespace = "metaforce")]
|
mod cxxbridge;
|
||||||
mod ffi {
|
|
||||||
unsafe extern "C++" {
|
|
||||||
include!("ImGuiEngine.hpp");
|
|
||||||
pub(crate) fn ImGuiEngine_Initialize(scale: f32);
|
|
||||||
pub(crate) fn ImGuiEngine_AddTextures(state: &mut ImGuiState, device: &DeviceHolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "Rust" {
|
|
||||||
type ImGuiState;
|
|
||||||
type DeviceHolder;
|
|
||||||
fn ImGuiEngine_AddTexture(
|
|
||||||
state: &mut ImGuiState,
|
|
||||||
device: &DeviceHolder,
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
data: &[u8],
|
|
||||||
) -> usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ImGuiState {
|
pub struct ImGuiState {
|
||||||
pub(crate) context: imgui::Context,
|
pub(crate) context: imgui::Context,
|
|
@ -3,8 +3,12 @@
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
#![allow(unused_unsafe)]
|
#![allow(unused_unsafe)]
|
||||||
|
|
||||||
use std::{collections::HashMap, time::Instant};
|
use std::{
|
||||||
|
collections::{BTreeMap, HashMap},
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
|
use cxxbridge::ffi;
|
||||||
use sdl2::{
|
use sdl2::{
|
||||||
controller::{Axis, Button, GameController},
|
controller::{Axis, Button, GameController},
|
||||||
event::Event as SDLEvent,
|
event::Event as SDLEvent,
|
||||||
|
@ -17,220 +21,29 @@ use winit::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi::{SpecialKey, WindowSize},
|
|
||||||
gpu::{create_depth_texture, create_render_texture, initialize_gpu, DeviceHolder},
|
gpu::{create_depth_texture, create_render_texture, initialize_gpu, DeviceHolder},
|
||||||
imgui::{initialize_imgui, ImGuiState},
|
imgui::{initialize_imgui, ImGuiState},
|
||||||
|
sdl::{
|
||||||
|
get_controller_player_index, initialize_sdl, poll_sdl_events, remap_controller_layout,
|
||||||
|
set_controller_player_index, SdlState,
|
||||||
|
},
|
||||||
shaders::render_into_pass,
|
shaders::render_into_pass,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod cxxbridge;
|
||||||
mod gpu;
|
mod gpu;
|
||||||
mod imgui;
|
mod imgui;
|
||||||
mod imgui_backend;
|
mod imgui_backend;
|
||||||
|
mod sdl;
|
||||||
mod shaders;
|
mod shaders;
|
||||||
mod util;
|
mod util;
|
||||||
mod zeus;
|
mod zeus;
|
||||||
|
|
||||||
#[cxx::bridge(namespace = "aurora")]
|
|
||||||
mod ffi {
|
|
||||||
unsafe extern "C++" {
|
|
||||||
include!("aurora.hpp");
|
|
||||||
pub(crate) type AppDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe extern "C++" {
|
|
||||||
include!("lib.hpp");
|
|
||||||
pub(crate) fn App_onAppLaunched(cb: Pin<&mut AppDelegate>);
|
|
||||||
pub(crate) fn App_onAppIdle(cb: Pin<&mut AppDelegate>, dt: f32) -> bool;
|
|
||||||
pub(crate) fn App_onAppDraw(cb: Pin<&mut AppDelegate>);
|
|
||||||
pub(crate) fn App_onAppPostDraw(cb: Pin<&mut AppDelegate>);
|
|
||||||
pub(crate) fn App_onAppWindowResized(cb: Pin<&mut AppDelegate>, size: &WindowSize);
|
|
||||||
pub(crate) fn App_onAppWindowMoved(cb: Pin<&mut AppDelegate>, x: i32, y: i32);
|
|
||||||
pub(crate) fn App_onAppExiting(cb: Pin<&mut AppDelegate>);
|
|
||||||
// Input
|
|
||||||
pub(crate) fn App_onCharKeyDown(cb: Pin<&mut AppDelegate>, code: u8, is_repeat: bool);
|
|
||||||
pub(crate) fn App_onCharKeyUp(cb: Pin<&mut AppDelegate>, code: u8);
|
|
||||||
pub(crate) fn App_onSpecialKeyDown(
|
|
||||||
cb: Pin<&mut AppDelegate>,
|
|
||||||
key: SpecialKey,
|
|
||||||
is_repeat: bool,
|
|
||||||
);
|
|
||||||
pub(crate) fn App_onSpecialKeyUp(cb: Pin<&mut AppDelegate>, key: SpecialKey);
|
|
||||||
// Controller
|
|
||||||
pub(crate) fn App_onControllerButton(
|
|
||||||
cb: Pin<&mut AppDelegate>,
|
|
||||||
idx: u32,
|
|
||||||
button: ControllerButton,
|
|
||||||
pressed: bool,
|
|
||||||
);
|
|
||||||
pub(crate) fn App_onControllerAxis(
|
|
||||||
cb: Pin<&mut AppDelegate>,
|
|
||||||
idx: u32,
|
|
||||||
axis: ControllerAxis,
|
|
||||||
value: i16,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Window {
|
|
||||||
pub(crate) inner: Box<WindowContext>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowSize {
|
|
||||||
pub width: u32,
|
|
||||||
pub height: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Backend {
|
|
||||||
Invalid,
|
|
||||||
Vulkan,
|
|
||||||
Metal,
|
|
||||||
D3D12,
|
|
||||||
D3D11,
|
|
||||||
OpenGL,
|
|
||||||
WebGPU,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ElementState {
|
|
||||||
Pressed,
|
|
||||||
Released,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum MouseButton {
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
Middle,
|
|
||||||
Other,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum SpecialKey {
|
|
||||||
None = 0,
|
|
||||||
F1 = 1,
|
|
||||||
F2 = 2,
|
|
||||||
F3 = 3,
|
|
||||||
F4 = 4,
|
|
||||||
F5 = 5,
|
|
||||||
F6 = 6,
|
|
||||||
F7 = 7,
|
|
||||||
F8 = 8,
|
|
||||||
F9 = 9,
|
|
||||||
F10 = 10,
|
|
||||||
F11 = 11,
|
|
||||||
F12 = 12,
|
|
||||||
Esc = 13,
|
|
||||||
Enter = 14,
|
|
||||||
Backspace = 15,
|
|
||||||
Insert = 16,
|
|
||||||
Delete = 17,
|
|
||||||
Home = 18,
|
|
||||||
End = 19,
|
|
||||||
PgUp = 20,
|
|
||||||
PgDown = 21,
|
|
||||||
Left = 22,
|
|
||||||
Right = 23,
|
|
||||||
Up = 24,
|
|
||||||
Down = 25,
|
|
||||||
Tab = 26,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct KeyboardInput {
|
|
||||||
pub scancode: u32,
|
|
||||||
pub state: ElementState,
|
|
||||||
// pub
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ControllerButton {
|
|
||||||
A,
|
|
||||||
B,
|
|
||||||
X,
|
|
||||||
Y,
|
|
||||||
Back,
|
|
||||||
Guide,
|
|
||||||
Start,
|
|
||||||
LeftStick,
|
|
||||||
RightStick,
|
|
||||||
LeftShoulder,
|
|
||||||
RightShoulder,
|
|
||||||
DPadUp,
|
|
||||||
DPadDown,
|
|
||||||
DPadLeft,
|
|
||||||
DPadRight,
|
|
||||||
Other,
|
|
||||||
MAX,
|
|
||||||
}
|
|
||||||
pub enum ControllerAxis {
|
|
||||||
LeftX,
|
|
||||||
LeftY,
|
|
||||||
RightX,
|
|
||||||
RightY,
|
|
||||||
TriggerLeft,
|
|
||||||
TriggerRight,
|
|
||||||
MAX,
|
|
||||||
}
|
|
||||||
pub struct Icon {
|
|
||||||
pub data: Vec<u8>,
|
|
||||||
pub width: u32,
|
|
||||||
pub height: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "Rust" {
|
|
||||||
type WindowContext;
|
|
||||||
type App;
|
|
||||||
fn app_run(mut delegate: UniquePtr<AppDelegate>, icon: Icon);
|
|
||||||
fn get_args() -> Vec<String>;
|
|
||||||
fn get_window_size() -> WindowSize;
|
|
||||||
fn set_window_title(title: &CxxString);
|
|
||||||
fn get_dxt_compression_supported() -> bool;
|
|
||||||
fn get_backend() -> Backend;
|
|
||||||
fn get_backend_string() -> &'static str;
|
|
||||||
fn set_fullscreen(v: bool);
|
|
||||||
fn get_controller_player_index(which: u32) -> i32;
|
|
||||||
fn set_controller_player_index(which: u32, index: i32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<Button> for ffi::ControllerButton {
|
|
||||||
fn from(button: Button) -> Self {
|
|
||||||
match button {
|
|
||||||
Button::A => ffi::ControllerButton::A,
|
|
||||||
Button::B => ffi::ControllerButton::B,
|
|
||||||
Button::X => ffi::ControllerButton::X,
|
|
||||||
Button::Y => ffi::ControllerButton::Y,
|
|
||||||
Button::Back => ffi::ControllerButton::Back,
|
|
||||||
Button::Guide => ffi::ControllerButton::Guide,
|
|
||||||
Button::Start => ffi::ControllerButton::Start,
|
|
||||||
Button::LeftStick => ffi::ControllerButton::LeftStick,
|
|
||||||
Button::RightStick => ffi::ControllerButton::RightStick,
|
|
||||||
Button::LeftShoulder => ffi::ControllerButton::LeftShoulder,
|
|
||||||
Button::RightShoulder => ffi::ControllerButton::RightShoulder,
|
|
||||||
Button::DPadUp => ffi::ControllerButton::DPadUp,
|
|
||||||
Button::DPadDown => ffi::ControllerButton::DPadDown,
|
|
||||||
Button::DPadLeft => ffi::ControllerButton::DPadLeft,
|
|
||||||
Button::DPadRight => ffi::ControllerButton::DPadRight,
|
|
||||||
_ => ffi::ControllerButton::Other,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<Axis> for ffi::ControllerAxis {
|
|
||||||
fn from(axis: Axis) -> Self {
|
|
||||||
match axis {
|
|
||||||
Axis::LeftX => ffi::ControllerAxis::LeftX,
|
|
||||||
Axis::LeftY => ffi::ControllerAxis::LeftY,
|
|
||||||
Axis::RightX => ffi::ControllerAxis::RightX,
|
|
||||||
Axis::RightY => ffi::ControllerAxis::RightY,
|
|
||||||
Axis::TriggerLeft => ffi::ControllerAxis::TriggerLeft,
|
|
||||||
Axis::TriggerRight => ffi::ControllerAxis::TriggerRight,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
window: ffi::Window,
|
window: ffi::Window,
|
||||||
gpu: DeviceHolder,
|
gpu: DeviceHolder,
|
||||||
imgui: ImGuiState,
|
imgui: ImGuiState,
|
||||||
// SDL
|
sdl: SdlState,
|
||||||
sdl: Sdl,
|
|
||||||
sdl_events: sdl2::EventPump,
|
|
||||||
sdl_controller_sys: GameControllerSubsystem,
|
|
||||||
sdl_open_controllers: HashMap<u32, GameController>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowContext {
|
pub struct WindowContext {
|
||||||
|
@ -246,29 +59,21 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>, icon: ffi::Icon) {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
log::info!("Running app");
|
log::info!("Running app");
|
||||||
let event_loop = winit::event_loop::EventLoop::new();
|
let event_loop = winit::event_loop::EventLoop::new();
|
||||||
let window_icon = winit::window::Icon::from_rgba(icon.data, icon.width, icon.height).expect("Failed to load icon");
|
let window_icon = winit::window::Icon::from_rgba(icon.data, icon.width, icon.height)
|
||||||
|
.expect("Failed to load icon");
|
||||||
let window = winit::window::WindowBuilder::new()
|
let window = winit::window::WindowBuilder::new()
|
||||||
.with_inner_size(winit::dpi::LogicalSize::new(1280, 720))
|
.with_inner_size(winit::dpi::LogicalSize::new(1280, 720))
|
||||||
.with_window_icon(Some(window_icon))
|
.with_window_icon(Some(window_icon))
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let sdl = sdl2::init().unwrap();
|
let sdl = initialize_sdl();
|
||||||
let sdl_events = sdl.event_pump().unwrap();
|
|
||||||
let controller = sdl.game_controller().unwrap();
|
|
||||||
let gpu = initialize_gpu(&window);
|
let gpu = initialize_gpu(&window);
|
||||||
let imgui = initialize_imgui(&window, &gpu);
|
let imgui = initialize_imgui(&window, &gpu);
|
||||||
let mut special_keys_pressed: [bool; 512] = [false; 512];
|
let mut special_keys_pressed: [bool; 512] = [false; 512];
|
||||||
shaders::construct_state(gpu.device.clone(), gpu.queue.clone(), &gpu.config);
|
shaders::construct_state(gpu.device.clone(), gpu.queue.clone(), &gpu.config);
|
||||||
let app = App {
|
let app =
|
||||||
window: ffi::Window { inner: Box::new(WindowContext { window }) },
|
App { window: ffi::Window { inner: Box::new(WindowContext { window }) }, gpu, imgui, sdl };
|
||||||
gpu,
|
let window_size = ffi::WindowSize {
|
||||||
imgui,
|
|
||||||
sdl,
|
|
||||||
sdl_events,
|
|
||||||
sdl_controller_sys: controller,
|
|
||||||
sdl_open_controllers: Default::default(),
|
|
||||||
};
|
|
||||||
let window_size = WindowSize {
|
|
||||||
width: app.gpu.surface_config.width,
|
width: app.gpu.surface_config.width,
|
||||||
height: app.gpu.surface_config.height,
|
height: app.gpu.surface_config.height,
|
||||||
};
|
};
|
||||||
|
@ -290,56 +95,9 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>, icon: ffi::Icon) {
|
||||||
let gpu = &mut app.gpu;
|
let gpu = &mut app.gpu;
|
||||||
|
|
||||||
// SDL event loop
|
// SDL event loop
|
||||||
for event in app.sdl_events.poll_iter() {
|
if !poll_sdl_events(&mut app.sdl, &mut delegate) {
|
||||||
// log::info!("SDL event: {:?}", event);
|
*control_flow = ControlFlow::Exit;
|
||||||
match event {
|
return;
|
||||||
SDLEvent::ControllerDeviceAdded { which, .. } => {
|
|
||||||
match app.sdl_controller_sys.open(which) {
|
|
||||||
Ok(controller) => {
|
|
||||||
log::info!("Opened SDL controller \"{}\"", controller.name());
|
|
||||||
app.sdl_open_controllers.insert(which, controller);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
log::warn!("Failed to open SDL controller {} ({:?})", which, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO app connected event
|
|
||||||
}
|
|
||||||
SDLEvent::ControllerDeviceRemoved { which, .. } => {
|
|
||||||
app.sdl_open_controllers.remove(&which);
|
|
||||||
// TODO app disconnected event
|
|
||||||
}
|
|
||||||
SDLEvent::ControllerButtonDown { which, button, .. } => unsafe {
|
|
||||||
ffi::App_onControllerButton(
|
|
||||||
delegate.as_mut().unwrap_unchecked(),
|
|
||||||
which,
|
|
||||||
button.into(),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
SDLEvent::ControllerButtonUp { which, button, .. } => unsafe {
|
|
||||||
ffi::App_onControllerButton(
|
|
||||||
delegate.as_mut().unwrap_unchecked(),
|
|
||||||
which,
|
|
||||||
button.into(),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
SDLEvent::ControllerAxisMotion { which, axis, value, .. } => unsafe {
|
|
||||||
ffi::App_onControllerAxis(
|
|
||||||
delegate.as_mut().unwrap_unchecked(),
|
|
||||||
which,
|
|
||||||
axis.into(),
|
|
||||||
value,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// SDL overrides exit signals
|
|
||||||
SDLEvent::Quit { .. } => {
|
|
||||||
*control_flow = ControlFlow::Exit;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// winit event loop
|
// winit event loop
|
||||||
|
@ -361,7 +119,7 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>, icon: ffi::Icon) {
|
||||||
&app.gpu.surface_config,
|
&app.gpu.surface_config,
|
||||||
&app.gpu.config,
|
&app.gpu.config,
|
||||||
);
|
);
|
||||||
let window_size = WindowSize {
|
let window_size = ffi::WindowSize {
|
||||||
width: app.gpu.surface_config.width,
|
width: app.gpu.surface_config.width,
|
||||||
height: app.gpu.surface_config.height,
|
height: app.gpu.surface_config.height,
|
||||||
};
|
};
|
||||||
|
@ -382,35 +140,35 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>, icon: ffi::Icon) {
|
||||||
} => {
|
} => {
|
||||||
// TODO: Handle normal keys, this will require a refactor in game runtime code
|
// TODO: Handle normal keys, this will require a refactor in game runtime code
|
||||||
let special_key = match key {
|
let special_key = match key {
|
||||||
VirtualKeyCode::F1 => SpecialKey::F1,
|
VirtualKeyCode::F1 => ffi::SpecialKey::F1,
|
||||||
VirtualKeyCode::F2 => SpecialKey::F2,
|
VirtualKeyCode::F2 => ffi::SpecialKey::F2,
|
||||||
VirtualKeyCode::F3 => SpecialKey::F3,
|
VirtualKeyCode::F3 => ffi::SpecialKey::F3,
|
||||||
VirtualKeyCode::F4 => SpecialKey::F4,
|
VirtualKeyCode::F4 => ffi::SpecialKey::F4,
|
||||||
VirtualKeyCode::F5 => SpecialKey::F5,
|
VirtualKeyCode::F5 => ffi::SpecialKey::F5,
|
||||||
VirtualKeyCode::F6 => SpecialKey::F6,
|
VirtualKeyCode::F6 => ffi::SpecialKey::F6,
|
||||||
VirtualKeyCode::F7 => SpecialKey::F7,
|
VirtualKeyCode::F7 => ffi::SpecialKey::F7,
|
||||||
VirtualKeyCode::F8 => SpecialKey::F8,
|
VirtualKeyCode::F8 => ffi::SpecialKey::F8,
|
||||||
VirtualKeyCode::F9 => SpecialKey::F9,
|
VirtualKeyCode::F9 => ffi::SpecialKey::F9,
|
||||||
VirtualKeyCode::F10 => SpecialKey::F10,
|
VirtualKeyCode::F10 => ffi::SpecialKey::F10,
|
||||||
VirtualKeyCode::F11 => SpecialKey::F11,
|
VirtualKeyCode::F11 => ffi::SpecialKey::F11,
|
||||||
VirtualKeyCode::F12 => SpecialKey::F12,
|
VirtualKeyCode::F12 => ffi::SpecialKey::F12,
|
||||||
VirtualKeyCode::Escape => SpecialKey::Esc,
|
VirtualKeyCode::Escape => ffi::SpecialKey::Esc,
|
||||||
VirtualKeyCode::Return => SpecialKey::Enter,
|
VirtualKeyCode::Return => ffi::SpecialKey::Enter,
|
||||||
VirtualKeyCode::Back => SpecialKey::Backspace,
|
VirtualKeyCode::Back => ffi::SpecialKey::Backspace,
|
||||||
VirtualKeyCode::Insert => SpecialKey::Insert,
|
VirtualKeyCode::Insert => ffi::SpecialKey::Insert,
|
||||||
VirtualKeyCode::Delete => SpecialKey::Delete,
|
VirtualKeyCode::Delete => ffi::SpecialKey::Delete,
|
||||||
VirtualKeyCode::Home => SpecialKey::Home,
|
VirtualKeyCode::Home => ffi::SpecialKey::Home,
|
||||||
VirtualKeyCode::PageUp => SpecialKey::PgUp,
|
VirtualKeyCode::PageUp => ffi::SpecialKey::PgUp,
|
||||||
VirtualKeyCode::PageDown => SpecialKey::PgDown,
|
VirtualKeyCode::PageDown => ffi::SpecialKey::PgDown,
|
||||||
VirtualKeyCode::Left => SpecialKey::Left,
|
VirtualKeyCode::Left => ffi::SpecialKey::Left,
|
||||||
VirtualKeyCode::Right => SpecialKey::Right,
|
VirtualKeyCode::Right => ffi::SpecialKey::Right,
|
||||||
VirtualKeyCode::Up => SpecialKey::Up,
|
VirtualKeyCode::Up => ffi::SpecialKey::Up,
|
||||||
VirtualKeyCode::Down => SpecialKey::Down,
|
VirtualKeyCode::Down => ffi::SpecialKey::Down,
|
||||||
VirtualKeyCode::Tab => SpecialKey::Tab,
|
VirtualKeyCode::Tab => ffi::SpecialKey::Tab,
|
||||||
_ => SpecialKey::None,
|
_ => ffi::SpecialKey::None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if special_key != SpecialKey::None {
|
if special_key != ffi::SpecialKey::None {
|
||||||
let pressed = state == ElementState::Pressed;
|
let pressed = state == ElementState::Pressed;
|
||||||
let repeat = special_keys_pressed[key as usize] == pressed;
|
let repeat = special_keys_pressed[key as usize] == pressed;
|
||||||
special_keys_pressed[key as usize] = pressed;
|
special_keys_pressed[key as usize] = pressed;
|
||||||
|
@ -596,25 +354,3 @@ fn set_fullscreen(v: bool) {
|
||||||
None
|
None
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_controller_player_index(which: u32) -> i32 {
|
|
||||||
let mut result: i32 = -1;
|
|
||||||
for (key, value) in &get_app().sdl_open_controllers {
|
|
||||||
if value.instance_id() == which {
|
|
||||||
result = value.player_index();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result as i32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_controller_player_index(which: u32, index: i32) {
|
|
||||||
|
|
||||||
for (key, value) in &get_app().sdl_open_controllers {
|
|
||||||
if value.instance_id() == which {
|
|
||||||
value.set_player_index(index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
|
use sdl2::{
|
||||||
|
controller::{Axis, GameController},
|
||||||
|
event::Event,
|
||||||
|
GameControllerSubsystem, Sdl,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{cxxbridge::ffi, get_app};
|
||||||
|
|
||||||
|
pub(crate) struct SdlState {
|
||||||
|
context: Sdl,
|
||||||
|
events: sdl2::EventPump,
|
||||||
|
controller_sys: GameControllerSubsystem,
|
||||||
|
open_controllers: HashMap<u32, GameController>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn initialize_sdl() -> SdlState {
|
||||||
|
let context = sdl2::init().unwrap();
|
||||||
|
let events = context.event_pump().unwrap();
|
||||||
|
let controller_sys = context.game_controller().unwrap();
|
||||||
|
SdlState { context, events, controller_sys, open_controllers: Default::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn poll_sdl_events(
|
||||||
|
state: &mut SdlState,
|
||||||
|
delegate: &mut cxx::UniquePtr<ffi::AppDelegate>,
|
||||||
|
) -> bool {
|
||||||
|
for event in state.events.poll_iter() {
|
||||||
|
match event {
|
||||||
|
Event::ControllerDeviceAdded { which, .. } => {
|
||||||
|
match state.controller_sys.open(which) {
|
||||||
|
Ok(controller) => {
|
||||||
|
log::info!("Opened SDL controller \"{}\"", controller.name());
|
||||||
|
if let Some(new_mapping) = remap_controller_layout(controller.mapping()) {
|
||||||
|
state
|
||||||
|
.controller_sys
|
||||||
|
.add_mapping(new_mapping.as_str())
|
||||||
|
.expect("Failed to overwrite mapping");
|
||||||
|
}
|
||||||
|
state.open_controllers.insert(controller.instance_id(), controller);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Failed to open SDL controller {} ({:?})", which, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO app connected event
|
||||||
|
}
|
||||||
|
Event::ControllerDeviceRemoved { which, .. } => {
|
||||||
|
state.open_controllers.remove(&which);
|
||||||
|
// TODO app disconnected event
|
||||||
|
}
|
||||||
|
Event::ControllerButtonDown { which, button, .. } => unsafe {
|
||||||
|
ffi::App_onControllerButton(
|
||||||
|
delegate.as_mut().unwrap_unchecked(),
|
||||||
|
which,
|
||||||
|
button.into(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
Event::ControllerButtonUp { which, button, .. } => unsafe {
|
||||||
|
ffi::App_onControllerButton(
|
||||||
|
delegate.as_mut().unwrap_unchecked(),
|
||||||
|
which,
|
||||||
|
button.into(),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
Event::ControllerAxisMotion { which, axis, value, .. } => unsafe {
|
||||||
|
ffi::App_onControllerAxis(
|
||||||
|
delegate.as_mut().unwrap_unchecked(),
|
||||||
|
which,
|
||||||
|
axis.into(),
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// SDL overrides exit signals
|
||||||
|
Event::Quit { .. } => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remap_controller_layout(mapping: String) -> Option<String> {
|
||||||
|
let mut new_mapping = String::with_capacity(mapping.len());
|
||||||
|
let mut entries = BTreeMap::<&str, &str>::new();
|
||||||
|
for (i, v) in mapping.split(',').enumerate() {
|
||||||
|
if i < 2 {
|
||||||
|
if i > 0 {
|
||||||
|
new_mapping.push(',');
|
||||||
|
}
|
||||||
|
new_mapping.push_str(v);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let split = v.splitn(2, ':').collect::<Vec<&str>>();
|
||||||
|
if split.len() != 2 {
|
||||||
|
panic!("Invalid mapping entry: {}", v);
|
||||||
|
}
|
||||||
|
entries.insert(split[0], split[1]);
|
||||||
|
}
|
||||||
|
if entries.contains_key("rightshoulder") && !entries.contains_key("leftshoulder") {
|
||||||
|
log::debug!("Remapping GameCube controller layout");
|
||||||
|
// TODO trigger buttons may differ per platform
|
||||||
|
entries.insert("leftshoulder", "b11");
|
||||||
|
let z_button = entries.insert("rightshoulder", "b10").unwrap();
|
||||||
|
entries.insert("back", z_button);
|
||||||
|
} else if entries.contains_key("leftshoulder")
|
||||||
|
&& entries.contains_key("rightshoulder")
|
||||||
|
&& entries.contains_key("back")
|
||||||
|
{
|
||||||
|
log::debug!("Controller has standard layout");
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
log::error!("Controller has unsupported layout: {}", mapping);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
for (k, v) in entries {
|
||||||
|
new_mapping.push(',');
|
||||||
|
new_mapping.push_str(k);
|
||||||
|
new_mapping.push(':');
|
||||||
|
new_mapping.push_str(v);
|
||||||
|
}
|
||||||
|
return Some(new_mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_controller_player_index(which: u32) -> i32 {
|
||||||
|
get_app().sdl.open_controllers.get(&which).map_or(-1, |c| c.player_index())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_controller_player_index(which: u32, index: i32) {
|
||||||
|
if let Some(c) = get_app().sdl.open_controllers.get(&which) {
|
||||||
|
c.set_player_index(index);
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ pub(crate) fn construct_state(
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
_queue: &wgpu::Queue,
|
_queue: &wgpu::Queue,
|
||||||
buffers: &BuiltBuffers,
|
buffers: &BuiltBuffers,
|
||||||
|
graphics_config: &GraphicsConfig,
|
||||||
) -> State {
|
) -> State {
|
||||||
let shader = device.create_shader_module(&include_wgsl!("shader.wgsl"));
|
let shader = device.create_shader_module(&include_wgsl!("shader.wgsl"));
|
||||||
let uniform_size = wgpu::BufferSize::new(std::mem::size_of::<Uniform>() as u64);
|
let uniform_size = wgpu::BufferSize::new(std::mem::size_of::<Uniform>() as u64);
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
use crate::shaders::{
|
||||||
|
aabb::queue_aabb,
|
||||||
|
fog_volume_filter::queue_fog_volume_filter,
|
||||||
|
fog_volume_plane::queue_fog_volume_plane,
|
||||||
|
model::{add_material_set, add_model},
|
||||||
|
movie_player::queue_movie_player,
|
||||||
|
resolve_color, resolve_depth, set_scissor, set_viewport,
|
||||||
|
texture::{
|
||||||
|
create_dynamic_texture_2d, create_render_texture, create_static_texture_2d, drop_texture,
|
||||||
|
write_texture,
|
||||||
|
},
|
||||||
|
textured_quad::{queue_textured_quad, queue_textured_quad_verts},
|
||||||
|
update_fog_state, update_model_view, update_projection,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cxx::bridge]
|
||||||
|
pub(crate) mod ffi {
|
||||||
|
unsafe extern "C++" {
|
||||||
|
include!("zeus/CVector2f.hpp");
|
||||||
|
include!("zeus/CVector3f.hpp");
|
||||||
|
include!("zeus/CVector4f.hpp");
|
||||||
|
include!("zeus/CMatrix4f.hpp");
|
||||||
|
include!("zeus/CColor.hpp");
|
||||||
|
include!("zeus/CRectangle.hpp");
|
||||||
|
include!("zeus/CAABox.hpp");
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CVector2f = crate::zeus::CVector2f;
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CVector3f = crate::zeus::CVector3f;
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CVector4f = crate::zeus::CVector4f;
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CMatrix4f = crate::zeus::CMatrix4f;
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CColor = crate::zeus::CColor;
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CRectangle = crate::zeus::CRectangle;
|
||||||
|
#[namespace = "zeus"]
|
||||||
|
type CAABox = crate::zeus::CAABox;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
|
pub(crate) enum CameraFilterType {
|
||||||
|
Passthru,
|
||||||
|
Multiply,
|
||||||
|
Invert,
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
Blend,
|
||||||
|
Widescreen,
|
||||||
|
SceneAdd,
|
||||||
|
NoColor,
|
||||||
|
InvDstMultiply,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
|
pub(crate) enum ZTest {
|
||||||
|
Never,
|
||||||
|
Less,
|
||||||
|
Equal,
|
||||||
|
LEqual,
|
||||||
|
Greater,
|
||||||
|
NEqual,
|
||||||
|
GEqual,
|
||||||
|
Always,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) enum TextureFormat {
|
||||||
|
RGBA8,
|
||||||
|
R8,
|
||||||
|
R32Float,
|
||||||
|
DXT1,
|
||||||
|
DXT3,
|
||||||
|
DXT5,
|
||||||
|
BPTC,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) enum TextureClampMode {
|
||||||
|
Repeat,
|
||||||
|
ClampToEdge,
|
||||||
|
ClampToWhite,
|
||||||
|
ClampToBlack,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
|
pub(crate) struct TextureRef {
|
||||||
|
pub(crate) id: u32,
|
||||||
|
pub(crate) render: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub(crate) enum FogMode {
|
||||||
|
None = 0x00,
|
||||||
|
|
||||||
|
PerspLin = 0x02,
|
||||||
|
PerspExp = 0x04,
|
||||||
|
PerspExp2 = 0x05,
|
||||||
|
PerspRevExp = 0x06,
|
||||||
|
PerspRevExp2 = 0x07,
|
||||||
|
|
||||||
|
OrthoLin = 0x0A,
|
||||||
|
OrthoExp = 0x0C,
|
||||||
|
OrthoExp2 = 0x0D,
|
||||||
|
OrthoRevExp = 0x0E,
|
||||||
|
OrthoRevExp2 = 0x0F,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) struct FogState {
|
||||||
|
#[cxx_name = "m_color"]
|
||||||
|
pub(crate) color: CColor,
|
||||||
|
#[cxx_name = "m_A"]
|
||||||
|
pub(crate) a: f32,
|
||||||
|
#[cxx_name = "m_B"]
|
||||||
|
pub(crate) b: f32,
|
||||||
|
#[cxx_name = "m_C"]
|
||||||
|
pub(crate) c: f32,
|
||||||
|
#[cxx_name = "m_mode"]
|
||||||
|
pub(crate) mode: FogMode,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) struct ClipRect {
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) struct MaterialPassInfo {
|
||||||
|
tex_idx: u32,
|
||||||
|
constant_color: CColor,
|
||||||
|
has_constant_color: bool, // would love to use Option...
|
||||||
|
uv_source: u8,
|
||||||
|
uv_anim_type: u8,
|
||||||
|
uv_anim_params: [f32; 9],
|
||||||
|
normalize: bool, // TODO might be static based on uv type?
|
||||||
|
sample_alpha: bool,
|
||||||
|
}
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct MaterialInfo {
|
||||||
|
pass_info: [MaterialPassInfo; 8],
|
||||||
|
texture_ids: Vec<TextureRef>,
|
||||||
|
shader_type: u8,
|
||||||
|
blend_mode: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[namespace = "aurora::shaders"]
|
||||||
|
extern "Rust" {
|
||||||
|
fn update_model_view(mv: CMatrix4f, mv_inv: CMatrix4f);
|
||||||
|
fn update_projection(proj: CMatrix4f);
|
||||||
|
fn update_fog_state(state: FogState);
|
||||||
|
fn set_viewport(rect: CRectangle, znear: f32, zfar: f32);
|
||||||
|
fn set_scissor(x: u32, y: u32, w: u32, h: u32);
|
||||||
|
|
||||||
|
fn resolve_color(rect: ClipRect, bind: u32, clear_depth: bool);
|
||||||
|
fn resolve_depth(rect: ClipRect, bind: u32);
|
||||||
|
|
||||||
|
fn add_material_set(materials: Vec<MaterialInfo>) -> u32;
|
||||||
|
fn add_model(verts: &[u8], indices: &[u8]) -> u32;
|
||||||
|
|
||||||
|
fn queue_aabb(aabb: CAABox, color: CColor, z_only: bool);
|
||||||
|
fn queue_fog_volume_plane(verts: &CxxVector<CVector4f>, pass: u8);
|
||||||
|
fn queue_fog_volume_filter(color: CColor, two_way: bool);
|
||||||
|
fn queue_textured_quad_verts(
|
||||||
|
filter_type: CameraFilterType,
|
||||||
|
texture: TextureRef,
|
||||||
|
z_comparison: ZTest,
|
||||||
|
z_test: bool,
|
||||||
|
color: CColor,
|
||||||
|
pos: &[CVector3f],
|
||||||
|
uvs: &[CVector2f],
|
||||||
|
lod: f32,
|
||||||
|
);
|
||||||
|
fn queue_textured_quad(
|
||||||
|
filter_type: CameraFilterType,
|
||||||
|
texture: TextureRef,
|
||||||
|
z_comparison: ZTest,
|
||||||
|
z_test: bool,
|
||||||
|
color: CColor,
|
||||||
|
uv_scale: f32,
|
||||||
|
rect: CRectangle,
|
||||||
|
z: f32,
|
||||||
|
);
|
||||||
|
fn queue_movie_player(
|
||||||
|
tex_y: TextureRef,
|
||||||
|
tex_u: TextureRef,
|
||||||
|
tex_v: TextureRef,
|
||||||
|
color: CColor,
|
||||||
|
h_pad: f32,
|
||||||
|
v_pad: f32,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn create_static_texture_2d(
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
mips: u32,
|
||||||
|
format: TextureFormat,
|
||||||
|
data: &[u8],
|
||||||
|
label: &str,
|
||||||
|
) -> TextureRef;
|
||||||
|
fn create_dynamic_texture_2d(
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
mips: u32,
|
||||||
|
format: TextureFormat,
|
||||||
|
label: &str,
|
||||||
|
) -> TextureRef;
|
||||||
|
fn create_render_texture(
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
// clamp_mode: TextureClampMode,
|
||||||
|
color_bind_count: u32,
|
||||||
|
depth_bind_count: u32,
|
||||||
|
label: &str,
|
||||||
|
) -> TextureRef;
|
||||||
|
fn write_texture(handle: TextureRef, data: &[u8]);
|
||||||
|
fn drop_texture(handle: TextureRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Zeroable for ffi::FogMode {}
|
||||||
|
unsafe impl bytemuck::Pod for ffi::FogMode {}
|
||||||
|
unsafe impl bytemuck::Zeroable for ffi::FogState {}
|
||||||
|
unsafe impl bytemuck::Pod for ffi::FogState {}
|
||||||
|
impl Default for ffi::FogState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { color: Default::default(), a: 0.0, b: 0.5, c: 0.0, mode: ffi::FogMode::None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Into<u32> for ffi::TextureFormat {
|
||||||
|
// noinspection RsUnreachablePatterns
|
||||||
|
fn into(self) -> u32 {
|
||||||
|
match self {
|
||||||
|
ffi::TextureFormat::RGBA8 => 1,
|
||||||
|
ffi::TextureFormat::R8 => 2,
|
||||||
|
ffi::TextureFormat::R32Float => 3,
|
||||||
|
ffi::TextureFormat::DXT1 => 4,
|
||||||
|
ffi::TextureFormat::DXT3 => 5,
|
||||||
|
ffi::TextureFormat::DXT5 => 6,
|
||||||
|
ffi::TextureFormat::BPTC => 7,
|
||||||
|
_ => panic!("Invalid texture format {:?}", self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,32 +5,20 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use aabb::queue_aabb;
|
|
||||||
use bytemuck::Pod;
|
use bytemuck::Pod;
|
||||||
use bytemuck_derive::{Pod, Zeroable};
|
use bytemuck_derive::{Pod, Zeroable};
|
||||||
use cxx::{type_id, ExternType};
|
use cxx::ExternType;
|
||||||
use fog_volume_filter::queue_fog_volume_filter;
|
use cxxbridge::ffi;
|
||||||
use fog_volume_plane::queue_fog_volume_plane;
|
|
||||||
use model::{add_material_set, add_model};
|
|
||||||
use movie_player::queue_movie_player;
|
|
||||||
use texture::{
|
|
||||||
create_dynamic_texture_2d, create_render_texture, create_static_texture_2d, drop_texture,
|
|
||||||
write_texture,
|
|
||||||
};
|
|
||||||
use textured_quad::{queue_textured_quad, queue_textured_quad_verts};
|
|
||||||
use twox_hash::Xxh3Hash64;
|
use twox_hash::Xxh3Hash64;
|
||||||
use wgpu::RenderPipeline;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gpu::GraphicsConfig,
|
gpu::GraphicsConfig,
|
||||||
shaders::{
|
shaders::texture::{RenderTexture, TextureWithView},
|
||||||
ffi::{TextureFormat, TextureRef},
|
|
||||||
texture::{RenderTexture, TextureWithView},
|
|
||||||
},
|
|
||||||
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, IDENTITY_MATRIX4F},
|
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, IDENTITY_MATRIX4F},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod aabb;
|
mod aabb;
|
||||||
|
mod cxxbridge;
|
||||||
mod fog_volume_filter;
|
mod fog_volume_filter;
|
||||||
mod fog_volume_plane;
|
mod fog_volume_plane;
|
||||||
mod model;
|
mod model;
|
||||||
|
@ -38,245 +26,6 @@ mod movie_player;
|
||||||
mod texture;
|
mod texture;
|
||||||
mod textured_quad;
|
mod textured_quad;
|
||||||
|
|
||||||
#[cxx::bridge]
|
|
||||||
mod ffi {
|
|
||||||
unsafe extern "C++" {
|
|
||||||
include!("zeus/CVector2f.hpp");
|
|
||||||
include!("zeus/CVector3f.hpp");
|
|
||||||
include!("zeus/CVector4f.hpp");
|
|
||||||
include!("zeus/CMatrix4f.hpp");
|
|
||||||
include!("zeus/CColor.hpp");
|
|
||||||
include!("zeus/CRectangle.hpp");
|
|
||||||
include!("zeus/CAABox.hpp");
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CVector2f = crate::zeus::CVector2f;
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CVector3f = crate::zeus::CVector3f;
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CVector4f = crate::zeus::CVector4f;
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CMatrix4f = crate::zeus::CMatrix4f;
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CColor = crate::zeus::CColor;
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CRectangle = crate::zeus::CRectangle;
|
|
||||||
#[namespace = "zeus"]
|
|
||||||
type CAABox = crate::zeus::CAABox;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone, Hash)]
|
|
||||||
pub(crate) enum CameraFilterType {
|
|
||||||
Passthru,
|
|
||||||
Multiply,
|
|
||||||
Invert,
|
|
||||||
Add,
|
|
||||||
Subtract,
|
|
||||||
Blend,
|
|
||||||
Widescreen,
|
|
||||||
SceneAdd,
|
|
||||||
NoColor,
|
|
||||||
InvDstMultiply,
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone, Hash)]
|
|
||||||
pub(crate) enum ZTest {
|
|
||||||
Never,
|
|
||||||
Less,
|
|
||||||
Equal,
|
|
||||||
LEqual,
|
|
||||||
Greater,
|
|
||||||
NEqual,
|
|
||||||
GEqual,
|
|
||||||
Always
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub(crate) enum TextureFormat {
|
|
||||||
RGBA8,
|
|
||||||
R8,
|
|
||||||
R32Float,
|
|
||||||
DXT1,
|
|
||||||
DXT3,
|
|
||||||
DXT5,
|
|
||||||
BPTC,
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub(crate) enum TextureClampMode {
|
|
||||||
Repeat,
|
|
||||||
ClampToEdge,
|
|
||||||
ClampToWhite,
|
|
||||||
ClampToBlack,
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone, Hash)]
|
|
||||||
pub(crate) struct TextureRef {
|
|
||||||
pub(crate) id: u32,
|
|
||||||
pub(crate) render: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
#[repr(u32)]
|
|
||||||
pub(crate) enum FogMode {
|
|
||||||
None = 0x00,
|
|
||||||
|
|
||||||
PerspLin = 0x02,
|
|
||||||
PerspExp = 0x04,
|
|
||||||
PerspExp2 = 0x05,
|
|
||||||
PerspRevExp = 0x06,
|
|
||||||
PerspRevExp2 = 0x07,
|
|
||||||
|
|
||||||
OrthoLin = 0x0A,
|
|
||||||
OrthoExp = 0x0C,
|
|
||||||
OrthoExp2 = 0x0D,
|
|
||||||
OrthoRevExp = 0x0E,
|
|
||||||
OrthoRevExp2 = 0x0F,
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub(crate) struct FogState {
|
|
||||||
#[cxx_name = "m_color"]
|
|
||||||
pub(crate) color: CColor,
|
|
||||||
#[cxx_name = "m_A"]
|
|
||||||
pub(crate) a: f32,
|
|
||||||
#[cxx_name = "m_B"]
|
|
||||||
pub(crate) b: f32,
|
|
||||||
#[cxx_name = "m_C"]
|
|
||||||
pub(crate) c: f32,
|
|
||||||
#[cxx_name = "m_mode"]
|
|
||||||
pub(crate) mode: FogMode,
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub(crate) struct ClipRect {
|
|
||||||
x: i32,
|
|
||||||
y: i32,
|
|
||||||
width: i32,
|
|
||||||
height: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub(crate) struct MaterialPassInfo {
|
|
||||||
tex_idx: u32,
|
|
||||||
constant_color: CColor,
|
|
||||||
has_constant_color: bool, // would love to use Option...
|
|
||||||
uv_source: u8,
|
|
||||||
uv_anim_type: u8,
|
|
||||||
uv_anim_params: [f32; 9],
|
|
||||||
normalize: bool, // TODO might be static based on uv type?
|
|
||||||
sample_alpha: bool,
|
|
||||||
}
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub(crate) struct MaterialInfo {
|
|
||||||
pass_info: [MaterialPassInfo; 8],
|
|
||||||
texture_ids: Vec<TextureRef>,
|
|
||||||
shader_type: u8,
|
|
||||||
blend_mode: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[namespace = "aurora::shaders"]
|
|
||||||
extern "Rust" {
|
|
||||||
fn update_model_view(mv: CMatrix4f, mv_inv: CMatrix4f);
|
|
||||||
fn update_projection(proj: CMatrix4f);
|
|
||||||
fn update_fog_state(state: FogState);
|
|
||||||
fn set_viewport(rect: CRectangle, znear: f32, zfar: f32);
|
|
||||||
fn set_scissor(x: u32, y: u32, w: u32, h: u32);
|
|
||||||
|
|
||||||
fn resolve_color(rect: ClipRect, bind: u32, clear_depth: bool);
|
|
||||||
fn resolve_depth(rect: ClipRect, bind: u32);
|
|
||||||
|
|
||||||
fn add_material_set(materials: Vec<MaterialInfo>) -> u32;
|
|
||||||
fn add_model(verts: &[u8], indices: &[u8]) -> u32;
|
|
||||||
|
|
||||||
fn queue_aabb(aabb: CAABox, color: CColor, z_only: bool);
|
|
||||||
fn queue_fog_volume_plane(verts: &CxxVector<CVector4f>, pass: u8);
|
|
||||||
fn queue_fog_volume_filter(color: CColor, two_way: bool);
|
|
||||||
fn queue_textured_quad_verts(
|
|
||||||
filter_type: CameraFilterType,
|
|
||||||
texture: TextureRef,
|
|
||||||
z_comparison: ZTest,
|
|
||||||
z_test: bool,
|
|
||||||
color: CColor,
|
|
||||||
pos: &[CVector3f],
|
|
||||||
uvs: &[CVector2f],
|
|
||||||
lod: f32,
|
|
||||||
);
|
|
||||||
fn queue_textured_quad(
|
|
||||||
filter_type: CameraFilterType,
|
|
||||||
texture: TextureRef,
|
|
||||||
z_comparison: ZTest,
|
|
||||||
z_test: bool,
|
|
||||||
color: CColor,
|
|
||||||
uv_scale: f32,
|
|
||||||
rect: CRectangle,
|
|
||||||
z: f32,
|
|
||||||
);
|
|
||||||
fn queue_movie_player(
|
|
||||||
tex_y: TextureRef,
|
|
||||||
tex_u: TextureRef,
|
|
||||||
tex_v: TextureRef,
|
|
||||||
color: CColor,
|
|
||||||
h_pad: f32,
|
|
||||||
v_pad: f32,
|
|
||||||
);
|
|
||||||
|
|
||||||
fn create_static_texture_2d(
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
mips: u32,
|
|
||||||
format: TextureFormat,
|
|
||||||
data: &[u8],
|
|
||||||
label: &str,
|
|
||||||
) -> TextureRef;
|
|
||||||
fn create_dynamic_texture_2d(
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
mips: u32,
|
|
||||||
format: TextureFormat,
|
|
||||||
label: &str,
|
|
||||||
) -> TextureRef;
|
|
||||||
fn create_render_texture(
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
// clamp_mode: TextureClampMode,
|
|
||||||
color_bind_count: u32,
|
|
||||||
depth_bind_count: u32,
|
|
||||||
label: &str,
|
|
||||||
) -> TextureRef;
|
|
||||||
fn write_texture(handle: TextureRef, data: &[u8]);
|
|
||||||
fn drop_texture(handle: TextureRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl bytemuck::Zeroable for ffi::FogMode {}
|
|
||||||
unsafe impl bytemuck::Pod for ffi::FogMode {}
|
|
||||||
unsafe impl bytemuck::Zeroable for ffi::FogState {}
|
|
||||||
unsafe impl bytemuck::Pod for ffi::FogState {}
|
|
||||||
impl Default for ffi::FogState {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { color: Default::default(), a: 0.0, b: 0.5, c: 0.0, mode: ffi::FogMode::None }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Into<u32> for ffi::TextureFormat {
|
|
||||||
// noinspection RsUnreachablePatterns
|
|
||||||
fn into(self) -> u32 {
|
|
||||||
match self {
|
|
||||||
TextureFormat::RGBA8 => 1,
|
|
||||||
TextureFormat::R8 => 2,
|
|
||||||
TextureFormat::R32Float => 3,
|
|
||||||
TextureFormat::DXT1 => 4,
|
|
||||||
TextureFormat::DXT3 => 5,
|
|
||||||
TextureFormat::DXT5 => 6,
|
|
||||||
TextureFormat::BPTC => 7,
|
|
||||||
_ => panic!("Invalid texture format {:?}", self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum ColoredStripMode {
|
enum ColoredStripMode {
|
||||||
Alpha,
|
Alpha,
|
||||||
|
@ -397,7 +146,7 @@ pub(crate) fn construct_state(
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
let aabb = aabb::construct_state(&device, &queue, &buffers);
|
let aabb = aabb::construct_state(&device, &queue, &buffers, graphics_config);
|
||||||
let textured_quad = textured_quad::construct_state(&device, &queue, &buffers, graphics_config);
|
let textured_quad = textured_quad::construct_state(&device, &queue, &buffers, graphics_config);
|
||||||
let movie_player = movie_player::construct_state(&device, &queue, &buffers, graphics_config);
|
let movie_player = movie_player::construct_state(&device, &queue, &buffers, graphics_config);
|
||||||
let mut state = RenderState {
|
let mut state = RenderState {
|
||||||
|
@ -422,6 +171,9 @@ pub(crate) fn construct_state(
|
||||||
for config in textured_quad::INITIAL_PIPELINES {
|
for config in textured_quad::INITIAL_PIPELINES {
|
||||||
construct_pipeline(&mut state, config);
|
construct_pipeline(&mut state, config);
|
||||||
}
|
}
|
||||||
|
for config in movie_player::INITIAL_PIPELINES {
|
||||||
|
construct_pipeline(&mut state, config);
|
||||||
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
STATE = Some(state);
|
STATE = Some(state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::shaders::ffi::MaterialInfo;
|
use crate::shaders::cxxbridge::ffi;
|
||||||
|
|
||||||
struct MaterialShaderData {
|
struct MaterialShaderData {
|
||||||
shader_type: u32, // 5 values (incl. Invalid)
|
shader_type: u32, // 5 values (incl. Invalid)
|
||||||
|
@ -37,5 +37,5 @@ struct ModelPipelineConfig {
|
||||||
render_alpha_update: bool,
|
render_alpha_update: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_material_set(materials: Vec<MaterialInfo>) -> u32 { return u32::MAX; }
|
pub(crate) fn add_material_set(materials: Vec<ffi::MaterialInfo>) -> u32 { return u32::MAX; }
|
||||||
pub(crate) fn add_model(verts: &[u8], indices: &[u8]) -> u32 { return u32::MAX; }
|
pub(crate) fn add_model(verts: &[u8], indices: &[u8]) -> u32 { return u32::MAX; }
|
||||||
|
|
|
@ -11,14 +11,12 @@ use crate::{
|
||||||
get_app,
|
get_app,
|
||||||
gpu::GraphicsConfig,
|
gpu::GraphicsConfig,
|
||||||
shaders::{
|
shaders::{
|
||||||
bind_pipeline,
|
bind_pipeline, cxxbridge::ffi, pipeline_ref, push_draw_command, push_uniform, push_verts,
|
||||||
ffi::{CameraFilterType, TextureRef, ZTest},
|
texture::create_sampler, BuiltBuffers, PipelineCreateCommand, PipelineHolder, PipelineRef,
|
||||||
pipeline_ref, push_draw_command, push_uniform, push_verts,
|
ShaderDrawCommand, STATE,
|
||||||
texture::create_sampler,
|
|
||||||
BuiltBuffers, PipelineCreateCommand, PipelineHolder, PipelineRef, ShaderDrawCommand, STATE,
|
|
||||||
},
|
},
|
||||||
util::{align, Vec2, Vec3},
|
util::{align, Vec2, Vec3},
|
||||||
zeus::{CColor, CMatrix4f, CRectangle, CVector4f},
|
zeus::{CColor, CMatrix4f},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -216,9 +214,9 @@ struct Vert {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn queue_movie_player(
|
pub(crate) fn queue_movie_player(
|
||||||
tex_y: TextureRef,
|
tex_y: ffi::TextureRef,
|
||||||
tex_u: TextureRef,
|
tex_u: ffi::TextureRef,
|
||||||
tex_v: TextureRef,
|
tex_v: ffi::TextureRef,
|
||||||
color: CColor,
|
color: CColor,
|
||||||
h_pad: f32,
|
h_pad: f32,
|
||||||
v_pad: f32,
|
v_pad: f32,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use wgpu::{util::DeviceExt, ImageDataLayout};
|
||||||
use crate::{
|
use crate::{
|
||||||
get_app,
|
get_app,
|
||||||
shaders::{
|
shaders::{
|
||||||
ffi::{TextureFormat, TextureRef},
|
cxxbridge::ffi::{TextureFormat, TextureRef},
|
||||||
STATE,
|
STATE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,11 +7,9 @@ use crate::{
|
||||||
get_app,
|
get_app,
|
||||||
gpu::GraphicsConfig,
|
gpu::GraphicsConfig,
|
||||||
shaders::{
|
shaders::{
|
||||||
bind_pipeline,
|
bind_pipeline, cxxbridge::ffi, get_combined_matrix, pipeline_ref, push_draw_command,
|
||||||
ffi::{CameraFilterType, TextureRef, ZTest},
|
push_uniform, push_verts, texture::create_sampler, BuiltBuffers, PipelineCreateCommand,
|
||||||
get_combined_matrix, pipeline_ref, push_draw_command, push_uniform, push_verts,
|
PipelineHolder, PipelineRef, ShaderDrawCommand, STATE,
|
||||||
texture::create_sampler,
|
|
||||||
BuiltBuffers, PipelineCreateCommand, PipelineHolder, PipelineRef, ShaderDrawCommand, STATE,
|
|
||||||
},
|
},
|
||||||
util::{align, Vec2, Vec3},
|
util::{align, Vec2, Vec3},
|
||||||
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, CVector4f},
|
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, CVector4f},
|
||||||
|
@ -22,13 +20,13 @@ pub(crate) struct DrawData {
|
||||||
pipeline: PipelineRef,
|
pipeline: PipelineRef,
|
||||||
vert_range: Range<u64>,
|
vert_range: Range<u64>,
|
||||||
uniform_range: Range<u64>,
|
uniform_range: Range<u64>,
|
||||||
texture: TextureRef,
|
texture: ffi::TextureRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
pub(crate) struct PipelineConfig {
|
pub(crate) struct PipelineConfig {
|
||||||
filter_type: CameraFilterType,
|
filter_type: ffi::CameraFilterType,
|
||||||
z_comparison: ZTest,
|
z_comparison: ffi::ZTest,
|
||||||
z_test: bool,
|
z_test: bool,
|
||||||
}
|
}
|
||||||
pub(crate) const INITIAL_PIPELINES: &[PipelineCreateCommand] = &[
|
pub(crate) const INITIAL_PIPELINES: &[PipelineCreateCommand] = &[
|
||||||
|
@ -134,7 +132,7 @@ pub(crate) fn construct_pipeline(
|
||||||
config: &PipelineConfig,
|
config: &PipelineConfig,
|
||||||
) -> PipelineHolder {
|
) -> PipelineHolder {
|
||||||
let (blend_component, alpha_write) = match config.filter_type {
|
let (blend_component, alpha_write) = match config.filter_type {
|
||||||
CameraFilterType::Multiply => (
|
ffi::CameraFilterType::Multiply => (
|
||||||
wgpu::BlendComponent {
|
wgpu::BlendComponent {
|
||||||
src_factor: wgpu::BlendFactor::Zero,
|
src_factor: wgpu::BlendFactor::Zero,
|
||||||
dst_factor: wgpu::BlendFactor::Src,
|
dst_factor: wgpu::BlendFactor::Src,
|
||||||
|
@ -142,7 +140,7 @@ pub(crate) fn construct_pipeline(
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
CameraFilterType::Add => (
|
ffi::CameraFilterType::Add => (
|
||||||
wgpu::BlendComponent {
|
wgpu::BlendComponent {
|
||||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||||
dst_factor: wgpu::BlendFactor::One,
|
dst_factor: wgpu::BlendFactor::One,
|
||||||
|
@ -150,7 +148,7 @@ pub(crate) fn construct_pipeline(
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
CameraFilterType::Subtract => (
|
ffi::CameraFilterType::Subtract => (
|
||||||
wgpu::BlendComponent {
|
wgpu::BlendComponent {
|
||||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||||
dst_factor: wgpu::BlendFactor::One,
|
dst_factor: wgpu::BlendFactor::One,
|
||||||
|
@ -158,7 +156,7 @@ pub(crate) fn construct_pipeline(
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
CameraFilterType::Blend => (
|
ffi::CameraFilterType::Blend => (
|
||||||
wgpu::BlendComponent {
|
wgpu::BlendComponent {
|
||||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||||
|
@ -166,7 +164,7 @@ pub(crate) fn construct_pipeline(
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
CameraFilterType::InvDstMultiply => (
|
ffi::CameraFilterType::InvDstMultiply => (
|
||||||
wgpu::BlendComponent {
|
wgpu::BlendComponent {
|
||||||
src_factor: wgpu::BlendFactor::Zero,
|
src_factor: wgpu::BlendFactor::Zero,
|
||||||
dst_factor: wgpu::BlendFactor::OneMinusSrc,
|
dst_factor: wgpu::BlendFactor::OneMinusSrc,
|
||||||
|
@ -197,15 +195,15 @@ pub(crate) fn construct_pipeline(
|
||||||
format: graphics.depth_format,
|
format: graphics.depth_format,
|
||||||
depth_write_enabled: config.z_test,
|
depth_write_enabled: config.z_test,
|
||||||
depth_compare: match config.z_comparison {
|
depth_compare: match config.z_comparison {
|
||||||
ZTest::Never => wgpu::CompareFunction::Never,
|
ffi::ZTest::Never => wgpu::CompareFunction::Never,
|
||||||
ZTest::Less => wgpu::CompareFunction::Less,
|
ffi::ZTest::Less => wgpu::CompareFunction::Less,
|
||||||
ZTest::Equal => wgpu::CompareFunction::Equal,
|
ffi::ZTest::Equal => wgpu::CompareFunction::Equal,
|
||||||
ZTest::LEqual => wgpu::CompareFunction::LessEqual,
|
ffi::ZTest::LEqual => wgpu::CompareFunction::LessEqual,
|
||||||
ZTest::Greater => wgpu::CompareFunction::Greater,
|
ffi::ZTest::Greater => wgpu::CompareFunction::Greater,
|
||||||
ZTest::NEqual => wgpu::CompareFunction::NotEqual,
|
ffi::ZTest::NEqual => wgpu::CompareFunction::NotEqual,
|
||||||
ZTest::GEqual => wgpu::CompareFunction::GreaterEqual,
|
ffi::ZTest::GEqual => wgpu::CompareFunction::GreaterEqual,
|
||||||
ZTest::Always => wgpu::CompareFunction::Always,
|
ffi::ZTest::Always => wgpu::CompareFunction::Always,
|
||||||
_=>todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
stencil: Default::default(),
|
stencil: Default::default(),
|
||||||
bias: Default::default(),
|
bias: Default::default(),
|
||||||
|
@ -251,17 +249,20 @@ struct Vert {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn queue_textured_quad(
|
pub(crate) fn queue_textured_quad(
|
||||||
filter_type: CameraFilterType,
|
filter_type: ffi::CameraFilterType,
|
||||||
texture: TextureRef,
|
texture: ffi::TextureRef,
|
||||||
z_comparison: ZTest,
|
z_comparison: ffi::ZTest,
|
||||||
z_test: bool,
|
z_test: bool,
|
||||||
color: CColor,
|
color: CColor,
|
||||||
uv_scale: f32,
|
uv_scale: f32,
|
||||||
rect: CRectangle,
|
rect: CRectangle,
|
||||||
z: f32,
|
z: f32,
|
||||||
) {
|
) {
|
||||||
let pipeline =
|
let pipeline = pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig {
|
||||||
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_comparison, z_test }));
|
filter_type,
|
||||||
|
z_comparison,
|
||||||
|
z_test,
|
||||||
|
}));
|
||||||
let vert_range = push_verts(&[
|
let vert_range = push_verts(&[
|
||||||
Vert { pos: Vec3::new(0.0, 0.0, z), uv: Vec2::new(0.0, 0.0) },
|
Vert { pos: Vec3::new(0.0, 0.0, z), uv: Vec2::new(0.0, 0.0) },
|
||||||
Vert { pos: Vec3::new(0.0, 1.0, z), uv: Vec2::new(0.0, uv_scale) },
|
Vert { pos: Vec3::new(0.0, 1.0, z), uv: Vec2::new(0.0, uv_scale) },
|
||||||
|
@ -283,9 +284,9 @@ pub(crate) fn queue_textured_quad(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn queue_textured_quad_verts(
|
pub(crate) fn queue_textured_quad_verts(
|
||||||
filter_type: CameraFilterType,
|
filter_type: ffi::CameraFilterType,
|
||||||
texture: TextureRef,
|
texture: ffi::TextureRef,
|
||||||
z_comparison: ZTest,
|
z_comparison: ffi::ZTest,
|
||||||
z_test: bool,
|
z_test: bool,
|
||||||
color: CColor,
|
color: CColor,
|
||||||
pos: &[CVector3f],
|
pos: &[CVector3f],
|
||||||
|
@ -296,8 +297,11 @@ pub(crate) fn queue_textured_quad_verts(
|
||||||
panic!("Invalid pos/uv sizes: {}/{}", pos.len(), uvs.len());
|
panic!("Invalid pos/uv sizes: {}/{}", pos.len(), uvs.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
let pipeline =
|
let pipeline = pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig {
|
||||||
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_comparison, z_test }));
|
filter_type,
|
||||||
|
z_comparison,
|
||||||
|
z_test,
|
||||||
|
}));
|
||||||
let vert_range = push_verts(
|
let vert_range = push_verts(
|
||||||
&pos.iter()
|
&pos.iter()
|
||||||
.zip(uvs)
|
.zip(uvs)
|
||||||
|
@ -310,7 +314,7 @@ pub(crate) fn queue_textured_quad_verts(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_textured_quad(
|
fn push_textured_quad(
|
||||||
texture: TextureRef,
|
texture: ffi::TextureRef,
|
||||||
pipeline: PipelineRef,
|
pipeline: PipelineRef,
|
||||||
vert_range: Range<u64>,
|
vert_range: Range<u64>,
|
||||||
uniform_range: Range<u64>,
|
uniform_range: Range<u64>,
|
||||||
|
|
|
@ -81,13 +81,13 @@ impl From<Vec2<i16>> for Vec2<f32> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn align<
|
pub(crate) fn align<
|
||||||
T: Copy
|
T: Copy
|
||||||
+ std::ops::Sub<Output = T>
|
+ std::ops::Sub<Output = T>
|
||||||
+ std::ops::Add<Output = T>
|
+ std::ops::Add<Output = T>
|
||||||
+ std::ops::Not<Output = T>
|
+ std::ops::Not<Output = T>
|
||||||
+ std::ops::BitAnd<Output = T>
|
+ std::ops::BitAnd<Output = T>
|
||||||
+ num_traits::One
|
+ num_traits::One
|
||||||
+ num_traits::Zero
|
+ num_traits::Zero
|
||||||
+ std::cmp::PartialEq,
|
+ std::cmp::PartialEq,
|
||||||
>(
|
>(
|
||||||
n: T,
|
n: T,
|
||||||
a: T,
|
a: T,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use bytemuck_derive::{Pod, Zeroable};
|
use bytemuck_derive::{Pod, Zeroable};
|
||||||
use cxx::{type_id, ExternType};
|
use cxx::{type_id, ExternType};
|
||||||
|
|
||||||
use crate::util::{Vec2, Vec3};
|
use crate::util::{Vec2, Vec3};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Pod, Zeroable, Default)]
|
#[derive(Debug, Copy, Clone, Pod, Zeroable, Default)]
|
||||||
|
@ -172,57 +173,21 @@ impl From<CMatrix4f> for cgmath::Matrix4<f32> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec2<f32>> for CVector2f {
|
impl From<Vec2<f32>> for CVector2f {
|
||||||
fn from(v: Vec2<f32>) -> Self {
|
fn from(v: Vec2<f32>) -> Self { Self { x: v.x, y: v.y, _p1: 0.0, _p2: 0.0 } }
|
||||||
Self {
|
|
||||||
x: v.x,
|
|
||||||
y: v.y,
|
|
||||||
_p1: 0.0,
|
|
||||||
_p2: 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl From<CVector2f> for Vec2<f32> {
|
impl From<CVector2f> for Vec2<f32> {
|
||||||
fn from(v: CVector2f) -> Self {
|
fn from(v: CVector2f) -> Self { Self { x: v.x, y: v.y } }
|
||||||
Self {
|
|
||||||
x: v.x,
|
|
||||||
y: v.y,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl From<&CVector2f> for Vec2<f32> {
|
impl From<&CVector2f> for Vec2<f32> {
|
||||||
fn from(v: &CVector2f) -> Self {
|
fn from(v: &CVector2f) -> Self { Self { x: v.x, y: v.y } }
|
||||||
Self {
|
|
||||||
x: v.x,
|
|
||||||
y: v.y,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec3<f32>> for CVector3f {
|
impl From<Vec3<f32>> for CVector3f {
|
||||||
fn from(v: Vec3<f32>) -> Self {
|
fn from(v: Vec3<f32>) -> Self { Self { x: v.x, y: v.y, z: v.z, _p: 0.0 } }
|
||||||
Self {
|
|
||||||
x: v.x,
|
|
||||||
y: v.y,
|
|
||||||
z: v.z,
|
|
||||||
_p: 0.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl From<CVector3f> for Vec3<f32> {
|
impl From<CVector3f> for Vec3<f32> {
|
||||||
fn from(v: CVector3f) -> Self {
|
fn from(v: CVector3f) -> Self { Self { x: v.x, y: v.y, z: v.z } }
|
||||||
Self {
|
|
||||||
x: v.x,
|
|
||||||
y: v.y,
|
|
||||||
z: v.z,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl From<&CVector3f> for Vec3<f32> {
|
impl From<&CVector3f> for Vec3<f32> {
|
||||||
fn from(v: &CVector3f) -> Self {
|
fn from(v: &CVector3f) -> Self { Self { x: v.x, y: v.y, z: v.z } }
|
||||||
Self {
|
|
||||||
x: v.x,
|
|
||||||
y: v.y,
|
|
||||||
z: v.z,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue