Replace vulkano by wgpu
This commit is contained in:
parent
d058c30d02
commit
9fff11fb19
25 changed files with 2561 additions and 3047 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
|||
target
|
||||
**/target
|
||||
.idea
|
||||
*.png
|
||||
target
|
||||
**/target
|
||||
.idea
|
||||
*.png
|
||||
|
|
1405
Cargo.lock
generated
1405
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
23
Cargo.toml
23
Cargo.toml
|
@ -1,12 +1,11 @@
|
|||
[package]
|
||||
name = "tuto1"
|
||||
version = "0.1.0"
|
||||
authors = ["Florian RICHER <florian.richer@unova.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
engine_utils = { path = "engine_utils" }
|
||||
engine_math = { path = "engine_math" }
|
||||
engine_core = { path = "engine_core" }
|
||||
[package]
|
||||
name = "tuto1"
|
||||
version = "0.1.0"
|
||||
authors = ["Florian RICHER <florian.richer@unova.fr>"]
|
||||
edition = "2018"
|
||||
resolver = "2"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
engine_core = { path = "engine_core" }
|
22
README.md
22
README.md
|
@ -1,12 +1,12 @@
|
|||
## USEFULL TOOLS
|
||||
|
||||
- RHAI [(Embedded Scripting for Rust)](https://github.com/rhaiscript/rhai)
|
||||
- GFX [(Low-level, cross-platform graphics and compute abstraction library)](https://github.com/gfx-rs/gfx)
|
||||
- WINIT [(Cross-platform window creation and management)](https://github.com/rust-windowing/winit)
|
||||
- RUSTTYPE [(Font lib)](https://gitlab.redox-os.org/redox-os/rusttype)
|
||||
- SPECS [(Entity-Component System)](https://github.com/amethyst/specs)
|
||||
- PAREEN [(Animation)](https://github.com/leod/pareen)
|
||||
|
||||
## USEFULL LINK
|
||||
|
||||
## USEFULL TOOLS
|
||||
|
||||
- RHAI [(Embedded Scripting for Rust)](https://github.com/rhaiscript/rhai)
|
||||
- GFX [(Low-level, cross-platform graphics and compute abstraction library)](https://github.com/gfx-rs/gfx)
|
||||
- WINIT [(Cross-platform window creation and management)](https://github.com/rust-windowing/winit)
|
||||
- RUSTTYPE [(Font lib)](https://gitlab.redox-os.org/redox-os/rusttype)
|
||||
- SPECS [(Entity-Component System)](https://github.com/amethyst/specs)
|
||||
- PAREEN [(Animation)](https://github.com/leod/pareen)
|
||||
|
||||
## USEFULL LINK
|
||||
|
||||
- https://arewegameyet.rs/
|
3624
engine_core/Cargo.lock
generated
3624
engine_core/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,16 +1,14 @@
|
|||
[package]
|
||||
name = "engine_core"
|
||||
version = "0.0.1"
|
||||
authors = ["Florian RICHER <florian.richer@unova.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
engine_utils = { path = "../engine_utils" }
|
||||
|
||||
vulkano = "0.19"
|
||||
vulkano-shaders = "0.19"
|
||||
image = "0.23"
|
||||
vulkano-win = "0.19"
|
||||
winit = "0.23"
|
||||
[package]
|
||||
name = "engine_core"
|
||||
version = "0.0.1"
|
||||
authors = ["Florian RICHER <florian.richer@unova.fr>"]
|
||||
edition = "2018"
|
||||
resolver = "2"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
image = "0.23"
|
||||
winit = "0.25"
|
||||
cgmath = "0.18"
|
||||
wgpu = "0.10.1"
|
|
@ -1,22 +0,0 @@
|
|||
#version 150 core
|
||||
|
||||
uniform sampler2D t_Awesome;
|
||||
uniform int i_Switch;
|
||||
|
||||
in vec4 v_Color;
|
||||
in vec2 v_Uv;
|
||||
out vec4 Target0;
|
||||
|
||||
void main() {
|
||||
vec3 aw = texture(t_Awesome, v_Uv).rgb;
|
||||
|
||||
if(i_Switch == 0) {
|
||||
if(aw == vec3(0.0, 0.0, 0.0)) {
|
||||
Target0 = 0.20 * v_Color;
|
||||
} else {
|
||||
Target0 = vec4(aw, 1.0);
|
||||
}
|
||||
} else {
|
||||
Target0 = v_Color;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,43 @@
|
|||
mod render;
|
||||
|
||||
pub use render::test;
|
||||
use winit::{
|
||||
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::{Window, WindowBuilder},
|
||||
};
|
||||
|
||||
pub struct Engine {
|
||||
title: &'static str
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
pub fn new(title: &'static str) -> Engine {
|
||||
Engine {
|
||||
title
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(self) {
|
||||
let event_loop = EventLoop::new();
|
||||
let window = WindowBuilder::new()
|
||||
.with_title(self.title)
|
||||
.build(&event_loop).unwrap();
|
||||
event_loop
|
||||
.run(move |event: Event<()>, _, control_flow: &mut ControlFlow | match event {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == window.id() => match event {
|
||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||
WindowEvent::KeyboardInput { input, .. } => match input {
|
||||
KeyboardInput {
|
||||
state: ElementState::Pressed,
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
mod vulkan;
|
||||
|
||||
pub use vulkan::test;
|
|
@ -1,226 +0,0 @@
|
|||
mod physical_device;
|
||||
mod vertex;
|
||||
|
||||
use physical_device::get_physical_device;
|
||||
pub use vertex::Vertex;
|
||||
|
||||
use image::ImageBuffer;
|
||||
use image::Rgba;
|
||||
use std::sync::Arc;
|
||||
use vulkano::buffer::BufferUsage;
|
||||
use vulkano::buffer::CpuAccessibleBuffer;
|
||||
use vulkano::command_buffer::AutoCommandBufferBuilder;
|
||||
use vulkano::command_buffer::CommandBuffer;
|
||||
use vulkano::command_buffer::DynamicState;
|
||||
use vulkano::device::DeviceExtensions;
|
||||
use vulkano::device::Features;
|
||||
use vulkano::device::{Device, Queue, QueuesIter};
|
||||
use vulkano::format::Format;
|
||||
use vulkano::framebuffer::Framebuffer;
|
||||
use vulkano::framebuffer::Subpass;
|
||||
use vulkano::image::Dimensions;
|
||||
use vulkano::image::StorageImage;
|
||||
use vulkano::instance::InstanceExtensions;
|
||||
use vulkano::instance::{Instance, QueueFamily};
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::sync::GpuFuture;
|
||||
|
||||
mod vs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "vertex",
|
||||
src: "
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}"
|
||||
}
|
||||
}
|
||||
|
||||
mod fs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "fragment",
|
||||
src: "
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out vec4 f_color;
|
||||
|
||||
void main() {
|
||||
f_color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}"
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VulkanInstance {
|
||||
instance: Arc<Instance>,
|
||||
device: Arc<Device>,
|
||||
queues: QueuesIter,
|
||||
}
|
||||
|
||||
impl VulkanInstance {
|
||||
fn init() -> Result<VulkanInstance, String> {
|
||||
let instance = Instance::new(None, &InstanceExtensions::none(), None)
|
||||
.map_err(|_| engine_utils::format_error!("Instance creation failed"))?;
|
||||
|
||||
let physical_device = get_physical_device(&instance)
|
||||
.ok_or(engine_utils::format_error!("No physical device found"))?;
|
||||
|
||||
let queue_family = physical_device
|
||||
.queue_families()
|
||||
.find(|&q| q.supports_graphics())
|
||||
.ok_or(engine_utils::format_error!("No queue found"))?;
|
||||
|
||||
let (device, queues) = Device::new(
|
||||
physical_device,
|
||||
&Features::none(),
|
||||
&DeviceExtensions::none(),
|
||||
[(queue_family, 0.5)].iter().cloned(),
|
||||
)
|
||||
.map_err(|_| engine_utils::format_error!("Virtual device creation failed"))?;
|
||||
|
||||
Ok(VulkanInstance {
|
||||
instance,
|
||||
device,
|
||||
queues,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_queue(&mut self) -> Option<Arc<Queue>> {
|
||||
self.queues.next()
|
||||
}
|
||||
|
||||
fn get_device(&self) -> Arc<Device> {
|
||||
self.device.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test() {
|
||||
let mut vulkan = VulkanInstance::init().unwrap();
|
||||
|
||||
let queue = vulkan.get_queue().unwrap();
|
||||
let device = vulkan.get_device();
|
||||
|
||||
let image = StorageImage::new(
|
||||
device.clone(),
|
||||
Dimensions::Dim2d {
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
},
|
||||
Format::R8G8B8A8Unorm,
|
||||
Some(queue.family()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let buf = CpuAccessibleBuffer::from_iter(
|
||||
device.clone(),
|
||||
BufferUsage::all(),
|
||||
false,
|
||||
(0..1024 * 1024 * 4).map(|_| 0u8),
|
||||
)
|
||||
.expect("failed to create buffer");
|
||||
|
||||
let vertex1 = Vertex {
|
||||
position: [-0.5, -0.5],
|
||||
};
|
||||
let vertex2 = Vertex {
|
||||
position: [0.0, 0.5],
|
||||
};
|
||||
let vertex3 = Vertex {
|
||||
position: [0.5, -0.25],
|
||||
};
|
||||
let vertex_buffer = CpuAccessibleBuffer::from_iter(
|
||||
device.clone(),
|
||||
BufferUsage::all(),
|
||||
false,
|
||||
vec![vertex1, vertex2, vertex3].into_iter(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let render_pass = Arc::new(
|
||||
vulkano::single_pass_renderpass!(device.clone(),
|
||||
attachments: {
|
||||
color: {
|
||||
load: Clear,
|
||||
store: Store,
|
||||
format: Format::R8G8B8A8Unorm,
|
||||
samples: 1,
|
||||
}
|
||||
},
|
||||
pass: {
|
||||
color: [color],
|
||||
depth_stencil: {}
|
||||
}
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let framebuffer = Arc::new(
|
||||
Framebuffer::start(render_pass.clone())
|
||||
.add(image.clone())
|
||||
.unwrap()
|
||||
.build()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module");
|
||||
let fs = fs::Shader::load(device.clone()).expect("failed to create shader module");
|
||||
|
||||
let pipeline = Arc::new(
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<Vertex>()
|
||||
.vertex_shader(vs.main_entry_point(), ())
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.fragment_shader(fs.main_entry_point(), ())
|
||||
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
|
||||
.build(device.clone())
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let dynamic_state = DynamicState {
|
||||
viewports: Some(vec![Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: [1024.0, 1024.0],
|
||||
depth_range: 0.0..1.0,
|
||||
}]),
|
||||
..DynamicState::none()
|
||||
};
|
||||
|
||||
let mut builder =
|
||||
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
|
||||
|
||||
builder
|
||||
.begin_render_pass(
|
||||
framebuffer.clone(),
|
||||
false,
|
||||
vec![[0.0, 0.0, 1.0, 1.0].into()],
|
||||
)
|
||||
.unwrap()
|
||||
.draw(
|
||||
pipeline.clone(),
|
||||
&dynamic_state,
|
||||
vertex_buffer.clone(),
|
||||
(),
|
||||
(),
|
||||
)
|
||||
.unwrap()
|
||||
.end_render_pass()
|
||||
.unwrap()
|
||||
.copy_image_to_buffer(image.clone(), buf.clone())
|
||||
.unwrap();
|
||||
|
||||
let command_buffer = builder.build().unwrap();
|
||||
|
||||
let finished = command_buffer.execute(queue.clone()).unwrap();
|
||||
finished
|
||||
.then_signal_fence_and_flush()
|
||||
.unwrap()
|
||||
.wait(None)
|
||||
.unwrap();
|
||||
|
||||
let buffer_content = buf.read().unwrap();
|
||||
let image = ImageBuffer::<Rgba<u8>, _>::from_raw(1024, 1024, &buffer_content[..]).unwrap();
|
||||
image.save("image.png").unwrap();
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
use vulkano::instance::{Instance, PhysicalDevice, PhysicalDeviceType};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn get_physical_device(instance: &Arc<Instance>) -> Option<PhysicalDevice> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
println!("###################################### PRINT PHYSICAL DEVICES ######################################");
|
||||
for physical_device in PhysicalDevice::enumerate(instance) {
|
||||
println!(
|
||||
"Available device: {} (type: {:?})\
|
||||
\n\t\t\t\t\tDriver version: {}\
|
||||
\n\t\t\t\t\tAPI Version: {:?}\
|
||||
\n\t\t\t\t\tVendor ID: {}\
|
||||
\n\t\t\t\t\tDevice ID: {}",
|
||||
physical_device.name(),
|
||||
physical_device.ty(),
|
||||
physical_device.driver_version(),
|
||||
physical_device.api_version(),
|
||||
physical_device.pci_vendor_id(),
|
||||
physical_device.pci_device_id()
|
||||
);
|
||||
}
|
||||
}
|
||||
let physical_device = PhysicalDevice::enumerate(instance)
|
||||
.find(|physical_device| physical_device.ty() == PhysicalDeviceType::DiscreteGpu)
|
||||
.or_else(|| PhysicalDevice::enumerate(instance).next());
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
match physical_device {
|
||||
Some(physical_device) => println!(
|
||||
"--- Using device: {} (type: {:?})",
|
||||
physical_device.name(),
|
||||
physical_device.ty()
|
||||
),
|
||||
None => println!("--- Error: No device found")
|
||||
}
|
||||
println!("####################################### END PHYSICAL DEVICES #######################################");
|
||||
}
|
||||
Some(physical_device?)
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#[derive(Default, Copy, Clone)]
|
||||
pub struct Vertex {
|
||||
pub position: [f32; 2],
|
||||
}
|
||||
|
||||
vulkano::impl_vertex!(Vertex, position);
|
|
@ -38,4 +38,4 @@ macro_rules! print_info {
|
|||
($($args:tt)*) => {{
|
||||
println!("[INFO] {}", format_args!($($args)*))
|
||||
}};
|
||||
}
|
||||
}
|
5
engine_math/Cargo.lock
generated
5
engine_math/Cargo.lock
generated
|
@ -1,5 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "engine_math"
|
||||
version = "0.0.1"
|
|
@ -1,9 +0,0 @@
|
|||
[package]
|
||||
name = "engine_math"
|
||||
version = "0.0.1"
|
||||
authors = ["Florian RICHER <florian.richer@unova.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -1,5 +0,0 @@
|
|||
mod tranform;
|
||||
mod vec2;
|
||||
|
||||
pub use tranform::Transform;
|
||||
pub use vec2::Vec2;
|
|
@ -1,40 +0,0 @@
|
|||
use super::Vec2;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Transform {
|
||||
position: Vec2,
|
||||
rotation: Vec2,
|
||||
scale: Vec2
|
||||
}
|
||||
|
||||
impl Transform {
|
||||
pub fn new() -> Transform {
|
||||
Transform {
|
||||
position: Vec2::new(),
|
||||
rotation: Vec2::new(),
|
||||
scale: Vec2::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_rotation(&self) -> &Vec2 {
|
||||
&self.rotation
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> &Vec2 {
|
||||
&self.position
|
||||
}
|
||||
|
||||
pub fn get_scale(&self) -> &Vec2 {
|
||||
&self.scale
|
||||
}
|
||||
|
||||
pub fn translate(&mut self, x: f64, y: f64) {
|
||||
self.position.x += x;
|
||||
self.position.y += y;
|
||||
}
|
||||
|
||||
pub fn rotate(&mut self, x: f64, y: f64) {
|
||||
self.rotation.x += x;
|
||||
self.rotation.y += y;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
#[derive(Debug)]
|
||||
pub struct Vec2 {
|
||||
pub x: f64,
|
||||
pub y: f64
|
||||
}
|
||||
|
||||
impl Vec2 {
|
||||
pub fn new() -> Vec2 {
|
||||
Vec2 {
|
||||
x: 0.0,
|
||||
y: 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add<Vec2> for Vec2 {
|
||||
type Output = Vec2;
|
||||
|
||||
fn add(self, b: Vec2) -> Vec2 {
|
||||
Vec2 {
|
||||
x: self.x + b.x,
|
||||
y: self.y + b.y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub<Vec2> for Vec2 {
|
||||
type Output = Vec2;
|
||||
|
||||
fn sub(self, b: Vec2) -> Vec2 {
|
||||
Vec2 {
|
||||
x: self.x - b.x,
|
||||
y: self.y - b.y
|
||||
}
|
||||
}
|
||||
}
|
5
engine_utils/Cargo.lock
generated
5
engine_utils/Cargo.lock
generated
|
@ -1,5 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "engine_utils"
|
||||
version = "0.0.1"
|
|
@ -1,9 +0,0 @@
|
|||
[package]
|
||||
name = "engine_utils"
|
||||
version = "0.0.1"
|
||||
authors = ["Florian RICHER <florian.richer@unova.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -1,5 +0,0 @@
|
|||
use engine_math::Transform;
|
||||
|
||||
pub trait Entity {
|
||||
fn get_transform(&mut self) -> &mut Transform;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
mod entity;
|
||||
mod player;
|
||||
|
||||
pub use entity::Entity;
|
||||
pub use player::Player;
|
|
@ -1,21 +0,0 @@
|
|||
use crate::entities::Entity;
|
||||
use engine_math::Transform;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Player {
|
||||
transform: Transform,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub fn new() -> Player {
|
||||
Player {
|
||||
transform: Transform::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for Player {
|
||||
fn get_transform(&mut self) -> &mut Transform {
|
||||
&mut self.transform
|
||||
}
|
||||
}
|
11
src/main.rs
11
src/main.rs
|
@ -1,7 +1,4 @@
|
|||
mod entities;
|
||||
|
||||
use engine_core::test;
|
||||
|
||||
fn main() {
|
||||
test();
|
||||
}
|
||||
fn main() {
|
||||
let engine = engine_core::Engine::new("Test 123");
|
||||
engine.run();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue