Compare commits
7 Commits
28576035eb
...
vulkano20
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c8d06dba4 | |||
| d995d66f89 | |||
| 9125878840 | |||
| bee1b66b55 | |||
| 33bea8fbc8 | |||
| 668696bdca | |||
| 6ecd5b6082 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
/rust-engine-proc/target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
|
||||
@@ -20,6 +20,7 @@ gilrs = "0.7"
|
||||
gltf = "0.15"
|
||||
glyph_brush = "0.7"
|
||||
winapi = "0.3"
|
||||
rust-engine-proc = { path = "rust-engine-proc" }
|
||||
|
||||
[profile.release]
|
||||
debug = 1
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"extension": "ngfx-proj",
|
||||
"files": [
|
||||
],
|
||||
"launcher": {
|
||||
"activity/cpp/d3d/d3d12replayfencebehavior": "Default",
|
||||
"activity/cpp/d3d/enablecachedpipelinestatesupport": false,
|
||||
"activity/cpp/d3d/replaycapturedexecuteindirectbuffer": false,
|
||||
"activity/cpp/d3d/reportforcefailedqueryinterfaces": true,
|
||||
"activity/cpp/d3d/reportunknownobjects": true,
|
||||
"activity/cpp/d3d/revisionzerodatacollection": true,
|
||||
"activity/cpp/d3d/syncinterval": "0",
|
||||
"activity/cpp/d3d/syncshadercollection": false,
|
||||
"activity/cpp/forcerepaint": false,
|
||||
"activity/cpp/opengl/delimiter": "SwapBuffers",
|
||||
"activity/cpp/opengl/noerror": "Application Controlled",
|
||||
"activity/cpp/raytracing/acceleration_structure_collect_to_vidmem": false,
|
||||
"activity/cpp/raytracing/acceleration_structure_geometry_tracking_mode": "Auto",
|
||||
"activity/cpp/raytracing/acceleration_structure_report_shallow_geometry_tracking_warnings": true,
|
||||
"activity/cpp/troubleshooting/blockonfirstincompatibility": "Auto",
|
||||
"activity/cpp/troubleshooting/crashreporting": true,
|
||||
"activity/cpp/troubleshooting/ignoreincompatibilities": false,
|
||||
"activity/cpp/troubleshooting/replaythreadpausestrategy": "Auto",
|
||||
"activity/cpp/troubleshooting/serialization": true,
|
||||
"activity/cpp/troubleshooting/threading": false,
|
||||
"activity/cpp/vulkan/bufferdeviceaddresscapturereplay": true,
|
||||
"activity/cpp/vulkan/coherentbuffercollection": true,
|
||||
"activity/cpp/vulkan/forcedvalidationlayers": "VK_LAYER_LUNARG_parameter_validation; VK_LAYER_LUNARG_object_tracker; VK_LAYER_LUNARG_core_validation; VK_LAYER_KHRONOS_validation",
|
||||
"activity/cpp/vulkan/forcevalidation": false,
|
||||
"activity/cpp/vulkan/reserveheap": "0",
|
||||
"activity/cpp/vulkan/revisionzerodatacollection": true,
|
||||
"activity/cpp/vulkan/safeobjectlookup": "Auto",
|
||||
"activity/cpp/vulkan/serializationobjectset": "Only Active",
|
||||
"activity/cpp/vulkan/unsafepnext": false,
|
||||
"activity/cpp/vulkan/unweavethreads": false,
|
||||
"activity/fd/d3d/d3d12replayfencebehavior": "Default",
|
||||
"activity/fd/d3d/enablecachedpipelinestatesupport": false,
|
||||
"activity/fd/d3d/replaycapturedexecuteindirectbuffer": false,
|
||||
"activity/fd/d3d/reportforcefailedqueryinterfaces": true,
|
||||
"activity/fd/d3d/reportunknownobjects": true,
|
||||
"activity/fd/d3d/revisionzerodatacollection": true,
|
||||
"activity/fd/d3d/syncinterval": "0",
|
||||
"activity/fd/d3d/syncshadercollection": false,
|
||||
"activity/fd/forcerepaint": false,
|
||||
"activity/fd/opengl/delimiter": "SwapBuffers",
|
||||
"activity/fd/opengl/noerror": "Application Controlled",
|
||||
"activity/fd/raytracing/acceleration_structure_collect_to_vidmem": false,
|
||||
"activity/fd/raytracing/acceleration_structure_geometry_tracking_mode": "Auto",
|
||||
"activity/fd/raytracing/acceleration_structure_report_shallow_geometry_tracking_warnings": true,
|
||||
"activity/fd/targethud": true,
|
||||
"activity/fd/troubleshooting/blockonfirstincompatibility": "Auto",
|
||||
"activity/fd/troubleshooting/collectlinetables": true,
|
||||
"activity/fd/troubleshooting/collectsassassembly": true,
|
||||
"activity/fd/troubleshooting/crashreporting": true,
|
||||
"activity/fd/troubleshooting/driverinstrumentation": true,
|
||||
"activity/fd/troubleshooting/hardwarepmmetrics": true,
|
||||
"activity/fd/troubleshooting/ignoreincompatibilities": false,
|
||||
"activity/fd/troubleshooting/replaythreadpausestrategy": "Auto",
|
||||
"activity/fd/troubleshooting/serialization": true,
|
||||
"activity/fd/troubleshooting/shaderreflection": true,
|
||||
"activity/fd/troubleshooting/threading": false,
|
||||
"activity/fd/vulkan/bufferdeviceaddresscapturereplay": true,
|
||||
"activity/fd/vulkan/coherentbuffercollection": true,
|
||||
"activity/fd/vulkan/forcedvalidationlayers": "VK_LAYER_LUNARG_parameter_validation; VK_LAYER_LUNARG_object_tracker; VK_LAYER_LUNARG_core_validation; VK_LAYER_KHRONOS_validation",
|
||||
"activity/fd/vulkan/forcevalidation": false,
|
||||
"activity/fd/vulkan/reserveheap": "0",
|
||||
"activity/fd/vulkan/revisionzerodatacollection": true,
|
||||
"activity/fd/vulkan/safeobjectlookup": "Auto",
|
||||
"activity/fd/vulkan/serializationobjectset": "Only Active",
|
||||
"activity/fd/vulkan/unsafepnext": false,
|
||||
"activity/fd/vulkan/unweavethreads": false,
|
||||
"activity/fp/d3d/d3d12replayfencebehavior": "Default",
|
||||
"activity/fp/d3d/enablecachedpipelinestatesupport": false,
|
||||
"activity/fp/d3d/replaycapturedexecuteindirectbuffer": false,
|
||||
"activity/fp/d3d/reportforcefailedqueryinterfaces": true,
|
||||
"activity/fp/d3d/reportunknownobjects": true,
|
||||
"activity/fp/d3d/revisionzerodatacollection": true,
|
||||
"activity/fp/d3d/syncinterval": "0",
|
||||
"activity/fp/d3d/syncshadercollection": false,
|
||||
"activity/fp/forcerepaint": false,
|
||||
"activity/fp/opengl/delimiter": "SwapBuffers",
|
||||
"activity/fp/opengl/noerror": "Application Controlled",
|
||||
"activity/fp/raytracing/acceleration_structure_collect_to_vidmem": false,
|
||||
"activity/fp/raytracing/acceleration_structure_geometry_tracking_mode": "Auto",
|
||||
"activity/fp/raytracing/acceleration_structure_report_shallow_geometry_tracking_warnings": true,
|
||||
"activity/fp/targethud": true,
|
||||
"activity/fp/troubleshooting/blockonfirstincompatibility": "Auto",
|
||||
"activity/fp/troubleshooting/collectlinetables": true,
|
||||
"activity/fp/troubleshooting/collectsassassembly": true,
|
||||
"activity/fp/troubleshooting/crashreporting": true,
|
||||
"activity/fp/troubleshooting/driverinstrumentation": true,
|
||||
"activity/fp/troubleshooting/hardwarepmmetrics": true,
|
||||
"activity/fp/troubleshooting/ignoreincompatibilities": false,
|
||||
"activity/fp/troubleshooting/replaythreadpausestrategy": "Auto",
|
||||
"activity/fp/troubleshooting/serialization": true,
|
||||
"activity/fp/troubleshooting/shaderreflection": true,
|
||||
"activity/fp/troubleshooting/threading": false,
|
||||
"activity/fp/vulkan/bufferdeviceaddresscapturereplay": true,
|
||||
"activity/fp/vulkan/coherentbuffercollection": true,
|
||||
"activity/fp/vulkan/forcedvalidationlayers": "VK_LAYER_LUNARG_parameter_validation; VK_LAYER_LUNARG_object_tracker; VK_LAYER_LUNARG_core_validation; VK_LAYER_KHRONOS_validation",
|
||||
"activity/fp/vulkan/forcevalidation": false,
|
||||
"activity/fp/vulkan/reserveheap": "0",
|
||||
"activity/fp/vulkan/revisionzerodatacollection": true,
|
||||
"activity/fp/vulkan/safeobjectlookup": "Auto",
|
||||
"activity/fp/vulkan/serializationobjectset": "Only Active",
|
||||
"activity/fp/vulkan/unsafepnext": false,
|
||||
"activity/fp/vulkan/unweavethreads": false,
|
||||
"activity/warpviz/general/capturemode": "Frames",
|
||||
"activity/warpviz/general/framecount": "1",
|
||||
"activity/warpviz/general/lockclockstobase": true,
|
||||
"activity/warpviz/general/metricset": "Throughput Metrics",
|
||||
"activity/warpviz/general/timestampcount": "100000",
|
||||
"activity/warpviz/general/vsyncmode": "Off",
|
||||
"platform/win32/arguments": "",
|
||||
"platform/win32/autoconnect": true,
|
||||
"platform/win32/environment": "",
|
||||
"platform/win32/executable": "D:/Code/rust-engine/target/release/rust-engine.exe",
|
||||
"platform/win32/executable/history": [
|
||||
"D:/Code/rust-engine/target/release/rust-engine.exe"
|
||||
],
|
||||
"platform/win32/workingdir": "D:/Code/rust-engine",
|
||||
"platform/win32/workingdir/history": [
|
||||
"D:/Code/rust-engine"
|
||||
],
|
||||
"platform/windows/device": "localhost"
|
||||
},
|
||||
"uuid": "{880d147e-f91a-47ff-945f-b4a3c2771050}",
|
||||
"version": "1.2"
|
||||
}
|
||||
BIN
build/release.rdbg
Normal file
BIN
build/release.rdbg
Normal file
Binary file not shown.
27
build/renderdoc-release.cap
Normal file
27
build/renderdoc-release.cap
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"rdocCaptureSettings": 1,
|
||||
"settings": {
|
||||
"autoStart": false,
|
||||
"commandLine": "",
|
||||
"environment": [
|
||||
],
|
||||
"executable": "D:\\Code\\rust-engine\\target\\release\\rust-engine.exe",
|
||||
"inject": false,
|
||||
"numQueuedFrames": 0,
|
||||
"options": {
|
||||
"allowFullscreen": true,
|
||||
"allowVSync": true,
|
||||
"apiValidation": true,
|
||||
"captureAllCmdLists": false,
|
||||
"captureCallstacks": true,
|
||||
"captureCallstacksOnlyDraws": false,
|
||||
"debugOutputMute": true,
|
||||
"delayForDebugger": 0,
|
||||
"hookIntoChildren": false,
|
||||
"refAllResources": false,
|
||||
"verifyBufferAccess": true
|
||||
},
|
||||
"queuedFrameCap": 0,
|
||||
"workingDir": "D:\\Code\\rust-engine"
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
msaa_samples = 4
|
||||
msaa_samples = 4
|
||||
vsync = "Mailbox"
|
||||
@@ -97,4 +97,5 @@ name = "look_vertical"
|
||||
touch_axis = "vertical"
|
||||
|
||||
[config]
|
||||
line_height_px = 16
|
||||
line_height_px = 16
|
||||
mouse_speed = 0.01
|
||||
13
rust-engine-proc/Cargo.toml
Normal file
13
rust-engine-proc/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "rust-engine-proc"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1.0", features = ["full"] }
|
||||
quote = "1.0"
|
||||
38
rust-engine-proc/src/lib.rs
Normal file
38
rust-engine-proc/src/lib.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{AttributeArgs, ItemFn, Lit, Meta, parse_macro_input, parse_quote};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn perf(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let attrs = parse_macro_input!(attr as AttributeArgs);
|
||||
let name = match &attrs[0] {
|
||||
syn::NestedMeta::Lit(Lit::Str(l)) => l.value(),
|
||||
_ => panic!("Invalid attribute"),
|
||||
};
|
||||
let counter_type = match &attrs[1] {
|
||||
syn::NestedMeta::Meta(Meta::Path(p)) => p,
|
||||
_ => panic!("Invalid attribute"),
|
||||
};
|
||||
let mut function = parse_macro_input!(item as ItemFn);
|
||||
function.block.stmts.insert(0, parse_quote! {
|
||||
let __perf_start = std::time::Instant::now();
|
||||
});
|
||||
|
||||
let timer_end = parse_quote! {
|
||||
unsafe {
|
||||
#counter_type::write_perf(#name, __perf_start.elapsed().as_micros());
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(last_stmt) = function.block.stmts.last() {
|
||||
match last_stmt {
|
||||
syn::Stmt::Expr(_) => function.block.stmts.insert(function.block.stmts.len() - 1, timer_end),
|
||||
_ => function.block.stmts.push(timer_end),
|
||||
}
|
||||
} else {
|
||||
function.block.stmts.push(timer_end);
|
||||
}
|
||||
quote!(#function).into()
|
||||
}
|
||||
@@ -35,6 +35,7 @@ out gl_PerVertex {
|
||||
void main() {
|
||||
// Vertex position in camera
|
||||
gl_Position = ubo.projection * ubo.view * push.model * vec4(position, 1.0);
|
||||
// gl_Position.y = -gl_Position.y;
|
||||
|
||||
// Vertex position in world
|
||||
position_wld = vec3(push.model * vec4(position, 1.0));
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::{convert::TryInto, fs};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use toml;
|
||||
use vulkano::image::SampleCount;
|
||||
use vulkano::{image::SampleCount, swapchain::PresentMode};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct LogConfigInput {
|
||||
@@ -27,7 +27,8 @@ impl LogConfig {
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct RenderConfig {
|
||||
pub msaa_samples: u32
|
||||
pub msaa_samples: u32,
|
||||
pub vsync: PresentModeConfig,
|
||||
}
|
||||
|
||||
impl RenderConfig {
|
||||
@@ -38,4 +39,23 @@ impl RenderConfig {
|
||||
pub fn get_msaa(&self) -> Option<SampleCount> {
|
||||
if self.msaa_samples > 0 { self.msaa_samples.try_into().ok() } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub enum PresentModeConfig {
|
||||
Immediate,
|
||||
Mailbox,
|
||||
Fifo,
|
||||
FifoRelaxed,
|
||||
}
|
||||
|
||||
impl Into<PresentMode> for PresentModeConfig {
|
||||
fn into(self) -> PresentMode {
|
||||
match self {
|
||||
PresentModeConfig::Immediate => PresentMode::Immediate,
|
||||
PresentModeConfig::Mailbox => PresentMode::Mailbox,
|
||||
PresentModeConfig::Fifo => PresentMode::Fifo,
|
||||
PresentModeConfig::FifoRelaxed => PresentMode::Relaxed,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,18 @@
|
||||
use cgmath::{Vector4, vec4};
|
||||
|
||||
use crate::{input::InputState, text::{create_text_object, update_text}, vulkan::{MeshHandle, PERF_COUNTER_SIZE, TextVertex, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}, mesh::{CPUMesh, CPUVertexList}}};
|
||||
use crate::{input::InputState, perf::stddev, text::{create_text_object, update_text}, vulkan::{MeshHandle, TextVertex, Vertex, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}, mesh::{CPUMesh, CPUVertexList}}};
|
||||
|
||||
use super::{GameState, TestGame};
|
||||
|
||||
pub struct FpsCounter {
|
||||
pub game_object: GameObjectHandle
|
||||
pub game_object: GameObjectHandle,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
impl FpsCounter {
|
||||
pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> FpsCounter {
|
||||
let text_mesh = create_text_object(&mut game.game_state.brush, renderer, "", 30.);
|
||||
FpsCounter { game_object: game.add_game_object(renderer, text_mesh) }
|
||||
FpsCounter { game_object: game.add_game_object(renderer, text_mesh), text: String::new() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +23,56 @@ impl Updatable for FpsCounter {
|
||||
go.visible = !go.visible;
|
||||
}
|
||||
|
||||
let update_duration = renderer.game_data.update_perf_counters.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128;
|
||||
let render_duration = renderer.game_data.render_perf_counters.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128;
|
||||
let other_duration = renderer.game_data.other_perf_counters.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128;
|
||||
let other_variance = renderer.game_data.other_perf_counters.iter().fold(0, |acc, b| acc + (*b as i128 - other_duration as i128) * (*b as i128 - other_duration as i128)) / PERF_COUNTER_SIZE as i128;
|
||||
let text = format!("Update: {:.0}ms\nRender: {:.0}ms\nTotal: {:.0}ms (±{:.1})\nDelta: {:.0}ms", update_duration as f64 / 1000., render_duration as f64 / 1000., other_duration as f64 / 1000., f64::sqrt(other_variance as f64) / 1000., _delta_time * 1000.);
|
||||
update_text(self.game_object, &text, 30., renderer, &mut game_state.brush, game_objects);
|
||||
unsafe {
|
||||
let mut counters = vec![];
|
||||
self.text.clear();
|
||||
|
||||
if let Some(pcs) = &crate::perf::PERF_COUNTERS {
|
||||
for (name, pc) in pcs {
|
||||
let mean = pc.mean();
|
||||
let stddev = stddev(&pc.values, mean as i128);
|
||||
let str = format!("{}: {:.1}ms (±{:.1})\n", name, (mean as f64) / 1000., stddev / 1000.);
|
||||
counters.push((mean, str));
|
||||
}
|
||||
}
|
||||
|
||||
counters.sort_by(|a, b| a.cmp(b));
|
||||
for (_, str) in counters {
|
||||
self.text.push_str(&str);
|
||||
}
|
||||
|
||||
let frame_time_mean: u128 = renderer.fps_counter.iter().sum::<u128>() / crate::perf::PERF_COUNTER_SIZE as u128;
|
||||
let fps_mean = 1000000. / frame_time_mean as f64;
|
||||
let fps_min = 1000000. / *renderer.fps_counter.iter().max().unwrap() as f64;
|
||||
|
||||
self.text.push_str(&format!("Total FPS: {:.0} (min {:.0})", fps_mean, fps_min));
|
||||
}
|
||||
update_text(self.game_object, &self.text, 20., renderer, &mut game_state.brush, game_objects);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WorldQuad {
|
||||
pub game_object: GameObjectHandle,
|
||||
}
|
||||
|
||||
impl WorldQuad {
|
||||
pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> WorldQuad {
|
||||
let quad_verts = vec![
|
||||
Vertex { position: [0., 0., 0.], uv: [0., 0.], normal: [0., 1., 0.], tangent: [1., 0., 0., 1.], bone_index: [0, 0, 0, 0], bone_weight: [0., 0., 0., 0.] },
|
||||
Vertex { position: [1., 0., 0.], uv: [1., 0.], normal: [0., 1., 0.], tangent: [1., 0., 0., 1.], bone_index: [0, 0, 0, 0], bone_weight: [0., 0., 0., 0.] },
|
||||
Vertex { position: [0., 0., 1.], uv: [0., 1.], normal: [0., 1., 0.], tangent: [1., 0., 0., 1.], bone_index: [0, 0, 0, 0], bone_weight: [0., 0., 0., 0.] },
|
||||
Vertex { position: [1., 0., 1.], uv: [1., 1.], normal: [0., 1., 0.], tangent: [1., 0., 0., 1.], bone_index: [0, 0, 0, 0], bone_weight: [0., 0., 0., 0.] },
|
||||
];
|
||||
let cpu_mesh = CPUMesh { vertices: CPUVertexList::Vertex3D(quad_verts), indices: vec![0, 2, 1, 1, 2, 3], local_texture_index: None, local_normal_map_index: None, name: None };
|
||||
let mesh_index = renderer.upload_mesh(cpu_mesh, None);
|
||||
let mesh_handle = MeshHandle {
|
||||
index: mesh_index,
|
||||
textures: vec![1, 0],
|
||||
original_path: None,
|
||||
pipeline_index: 0
|
||||
};
|
||||
let game_object = game.add_game_object(renderer, mesh_handle);
|
||||
WorldQuad { game_object }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +89,7 @@ impl UiQuad {
|
||||
TextVertex { position: [1., 0., 0.], uv: [1., 0.] },
|
||||
TextVertex { position: [1., 1., 0.], uv: [1., 1.] },
|
||||
];
|
||||
let cpu_mesh = CPUMesh { vertices: CPUVertexList::VertexText(quad_verts), indices: vec![0, 1, 2, 1, 3, 2], local_texture_index: None, local_normal_map_index: None, name: None };
|
||||
let cpu_mesh = CPUMesh { vertices: CPUVertexList::VertexText(quad_verts), indices: vec![0, 2, 1, 1, 2, 3], local_texture_index: None, local_normal_map_index: None, name: None };
|
||||
let mesh_index = renderer.upload_mesh(cpu_mesh, None);
|
||||
let mesh_handle = MeshHandle {
|
||||
index: mesh_index,
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
use std::time::Instant;
|
||||
use cgmath::{Deg, Euler, Quaternion, vec3};
|
||||
use glyph_brush::GlyphBrush;
|
||||
use rust_engine_proc::perf;
|
||||
use winit::event::Event;
|
||||
|
||||
use level::{load_level, save_level};
|
||||
use player::Player;
|
||||
|
||||
use crate::game::entities::{FpsCounter, UiQuad};
|
||||
use crate::game::entities::{FpsCounter, UiQuad, WorldQuad};
|
||||
use crate::text::create_brush;
|
||||
use crate::vulkan::pipelines::vs;
|
||||
use crate::{config::LogConfig, vulkan};
|
||||
use crate::input::InputState;
|
||||
use crate::vulkan::{Game, MeshHandle, TextVertex, Vertex, VulkanRenderer};
|
||||
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
||||
use crate::vulkan::mesh;
|
||||
use crate::vulkan::pipelines::vs::ty::ObjectUniformData;
|
||||
|
||||
pub mod player;
|
||||
mod level;
|
||||
@@ -44,6 +45,7 @@ pub struct TestGame {
|
||||
pub last_time: f32,
|
||||
pub components: Vec<Box<dyn Updatable>>,
|
||||
pub game_state: GameState,
|
||||
pub ubo: vs::ty::ObjectUniformData,
|
||||
}
|
||||
|
||||
impl Game for TestGame {
|
||||
@@ -55,9 +57,8 @@ impl Game for TestGame {
|
||||
self.input.on_window_event(event);
|
||||
}
|
||||
|
||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> ObjectUniformData {
|
||||
let precise_start = Instant::now();
|
||||
|
||||
#[perf("update", crate::perf::PerformanceCounter)]
|
||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer) {
|
||||
// Input and timing
|
||||
self.input.frame_start();
|
||||
let time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32;
|
||||
@@ -113,10 +114,7 @@ impl Game for TestGame {
|
||||
self.last_time = time;
|
||||
self.input.frame_end();
|
||||
|
||||
let precise_duration = precise_start.elapsed().as_micros();
|
||||
renderer.game_data.update_perf_counters[renderer.game_data.performance_counter_index] = precise_duration;
|
||||
|
||||
ObjectUniformData {
|
||||
self.ubo = vs::ty::ObjectUniformData {
|
||||
view: self.player.camera.view.into(),
|
||||
projection: self.player.camera.proj.into(),
|
||||
ortho_projection: self.player.camera.ortho_proj.into(),
|
||||
@@ -127,7 +125,11 @@ impl Game for TestGame {
|
||||
_dummy0: [0; 12],
|
||||
_dummy1: [0; 4],
|
||||
_dummy2: [0; 4],
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn get_ubo(&self) -> &vs::ty::ObjectUniformData {
|
||||
&self.ubo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +143,19 @@ impl TestGame {
|
||||
texture_index_counter: 0,
|
||||
last_time: 0.0,
|
||||
components: vec![],
|
||||
game_state: GameState::new()
|
||||
game_state: GameState::new(),
|
||||
ubo: vs::ty::ObjectUniformData {
|
||||
view: [[0.; 4]; 4],
|
||||
projection: [[0.; 4]; 4],
|
||||
ortho_projection: [[0.; 4]; 4],
|
||||
time: 0.,
|
||||
light_position: [0.; 3],
|
||||
light_directional_rotation: [0.; 3],
|
||||
camera_position: [0.; 3],
|
||||
_dummy0: [0; 12],
|
||||
_dummy1: [0; 4],
|
||||
_dummy2: [0; 4],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +167,11 @@ impl TestGame {
|
||||
|
||||
let test_quad = UiQuad::new(self, renderer);
|
||||
self.components.push(Box::new(test_quad));
|
||||
|
||||
let world_quad = WorldQuad::new(self, renderer);
|
||||
let quad_go = &mut self.game_objects[world_quad.game_object];
|
||||
quad_go.position = vec3(0.0, 0.01, 0.0);
|
||||
quad_go.scale = vec3(10., 10., 10.);
|
||||
|
||||
println!("Game loaded!");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use cgmath::{Deg, InnerSpace, Matrix4, One, Quaternion, Rad, Rotation, Rotation3
|
||||
use crate::game::player::PlayerMovementMode::{FirstPerson, Flying};
|
||||
|
||||
use crate::input::InputState;
|
||||
use crate::util::{intersection_distance, print_matrix};
|
||||
use crate::util::intersection_distance;
|
||||
use crate::vulkan::gameobject::GameObject;
|
||||
use crate::vulkan::{
|
||||
gameobject::Updatable,
|
||||
@@ -143,14 +143,14 @@ impl Updatable for Player {
|
||||
}
|
||||
|
||||
// Rotation
|
||||
self.x_look += input.get_axis("look_vertical") * delta_time * self.look_sensitivity;
|
||||
self.y_look += input.get_axis("look_horizontal") * delta_time * self.look_sensitivity;
|
||||
self.x_look += input.get_axis_timescaled("look_vertical", delta_time) * self.look_sensitivity;
|
||||
self.y_look += input.get_axis_timescaled("look_horizontal", delta_time) * self.look_sensitivity;
|
||||
let x_rot = Quaternion::from_angle_x(Deg(self.x_look));
|
||||
let y_rot = Quaternion::from_angle_y(Deg(self.y_look));
|
||||
self.camera.rotation = x_rot * y_rot;
|
||||
|
||||
// Movement
|
||||
let local_input = vec3(input.get_axis("move_right"), 0.0, -input.get_axis("move_forward")) * self.movement_speed * delta_time;
|
||||
let local_input = vec3(input.get_axis_timescaled("move_right", delta_time), 0.0, -input.get_axis_timescaled("move_forward", delta_time)) * self.movement_speed;
|
||||
|
||||
if self.movement_mode == FirstPerson {
|
||||
let mut world_input = self.camera.local_to_world(local_input);
|
||||
|
||||
15
src/input.rs
15
src/input.rs
@@ -8,6 +8,7 @@ use std::iter::FromIterator;
|
||||
use cgmath::{InnerSpace, Vector2, Zero, vec2};
|
||||
use gilrs;
|
||||
use gilrs::{EventType, Gilrs};
|
||||
use rust_engine_proc::perf;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use toml;
|
||||
use winapi::shared::minwindef::UINT;
|
||||
@@ -43,6 +44,7 @@ struct InputConfig {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct InputConfigConfig {
|
||||
line_height_px: f32,
|
||||
mouse_speed: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -232,6 +234,7 @@ impl InputState {
|
||||
return state;
|
||||
}
|
||||
|
||||
#[perf("input_events", crate::perf::PerformanceCounter)]
|
||||
pub fn on_window_event(self: &mut Self, event: &Event<()>) {
|
||||
match event {
|
||||
Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input, .. }, .. } => {
|
||||
@@ -399,30 +402,30 @@ impl InputState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_axis(self: &Self, axis_code: &str) -> f32 {
|
||||
pub fn get_axis_timescaled(self: &Self, axis_code: &str, delta_time: f32) -> f32 {
|
||||
if let Some(axis) = self.virtual_axes.get(axis_code) {
|
||||
axis.axis_inputs.iter().map(|item| {
|
||||
match &item {
|
||||
AxisInput::Wheel(modifiers) => {
|
||||
if self.modifiers_are_pressed(modifiers) { self.analog_wheel_state } else { 0.0 }
|
||||
if self.modifiers_are_pressed(modifiers) { self.analog_wheel_state * delta_time } else { 0.0 }
|
||||
},
|
||||
AxisInput::MouseMove(direction, modifiers) => {
|
||||
if self.modifiers_are_pressed(modifiers) {
|
||||
match direction {
|
||||
MouseMoveDirection::X => self.mouse_delta_x as f32,
|
||||
MouseMoveDirection::Y => self.mouse_delta_y as f32,
|
||||
MouseMoveDirection::X => self.mouse_delta_x as f32 * self.config.mouse_speed,
|
||||
MouseMoveDirection::Y => self.mouse_delta_y as f32 * self.config.mouse_speed,
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
},
|
||||
AxisInput::Digital(positive_button, negative_button) => {
|
||||
self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button)
|
||||
(self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button)) * delta_time
|
||||
},
|
||||
AxisInput::Controller(controller_input) => {
|
||||
self.controller_input.gamepads()
|
||||
.map(|(_id, gamepad)| gamepad.value(controller_input.axis))
|
||||
.fold(0.0, fold_axis_value)
|
||||
.fold(0.0, fold_axis_value) * delta_time
|
||||
},
|
||||
&AxisInput::Touch(touch_axis) => {
|
||||
match touch_axis {
|
||||
|
||||
@@ -13,6 +13,7 @@ mod game;
|
||||
mod tests;
|
||||
mod text;
|
||||
mod util;
|
||||
mod perf;
|
||||
|
||||
fn main() {
|
||||
let log_config = LogConfig::from_file("config/log.toml");
|
||||
|
||||
64
src/perf.rs
Normal file
64
src/perf.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub const PERF_COUNTER_SIZE: usize = 100;
|
||||
pub static mut PERF_COUNTERS: Option<HashMap<String, PerformanceCounter>> = None;
|
||||
|
||||
pub struct PerformanceCounter {
|
||||
pub values: [u128; PERF_COUNTER_SIZE],
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
pub fn stddev(arr: &[u128; PERF_COUNTER_SIZE], mean: i128) -> f64 {
|
||||
f64::sqrt(arr.iter().fold(0, |acc, b| acc + (*b as i128 - mean) * (*b as i128 - mean)) as f64 / PERF_COUNTER_SIZE as f64)
|
||||
}
|
||||
|
||||
impl PerformanceCounter {
|
||||
pub fn mean(&self) -> u128 {
|
||||
self.values.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128
|
||||
}
|
||||
|
||||
pub fn init_perf() {
|
||||
unsafe {
|
||||
if PERF_COUNTERS.is_none() { PERF_COUNTERS = Some(HashMap::new()); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_perf(name: &str, value: u128) {
|
||||
unsafe {
|
||||
if let Some(pcs) = &mut PERF_COUNTERS {
|
||||
if let Some(pc) = pcs.get_mut(name) {
|
||||
pc.values[pc.index] = value;
|
||||
} else {
|
||||
let mut pc = PerformanceCounter { values: [0; PERF_COUNTER_SIZE], index: 0 };
|
||||
pc.values[0] = value;
|
||||
pcs.insert(name.to_string(), pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _get_perf(name: &str) -> u128 {
|
||||
unsafe {
|
||||
if let Some(pcs) = &mut PERF_COUNTERS {
|
||||
if let Some(pc) = pcs.get_mut(name) {
|
||||
pc.mean()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn perf_next_frame(name: &str) {
|
||||
unsafe {
|
||||
if let Some(pcs) = &mut PERF_COUNTERS {
|
||||
if let Some(pc) = pcs.get_mut(name) {
|
||||
pc.index = (pc.index + 1) % PERF_COUNTER_SIZE;
|
||||
pc.values[pc.index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#[cfg(test)]
|
||||
#[allow(deprecated)]
|
||||
mod tests {
|
||||
use cgmath::{vec3};
|
||||
use cgmath::vec3;
|
||||
use winit::{dpi::PhysicalPosition, event::{DeviceId, ElementState, Event, Force, KeyboardInput, ModifiersState, Touch, TouchPhase, WindowEvent}, window::WindowId};
|
||||
|
||||
use crate::{config::LogConfig, game::player::{intersect_triangle}, input::InputState};
|
||||
use crate::{config::LogConfig, input::InputState, util::intersect_triangle};
|
||||
use crate::input::vk_to_scan_code;
|
||||
|
||||
fn epsilon_eq(f1: f32, f2: f32) {
|
||||
|
||||
@@ -3,6 +3,7 @@ use vulkano::buffer::TypedBufferAccess;
|
||||
|
||||
use crate::vulkan::{Mesh, gameobject::GameObject};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn print_matrix(mat: Matrix4<f32>) {
|
||||
let cols = [
|
||||
[mat.x.x, mat.x.y, mat.x.z, mat.x.w],
|
||||
|
||||
@@ -89,12 +89,20 @@ pub fn load_mesh<V>(mesh_path: &str, print_status: bool) -> Result<(Vec<CPUMesh>
|
||||
reader.read_joints(0),
|
||||
reader.read_weights(0));
|
||||
|
||||
let verts = vertices_result?;
|
||||
let mut verts = vertices_result?;
|
||||
verts.iter_mut().for_each(|v| {
|
||||
v.position[1] = -v.position[1];
|
||||
v.normal[1] = -v.normal[1];
|
||||
});
|
||||
|
||||
let vert_count = verts.len();
|
||||
|
||||
let mut inds: Vec<u32> = indices.into_u32().collect();
|
||||
inds.reverse();
|
||||
|
||||
let cpu_mesh = CPUMesh {
|
||||
vertices: CPUVertexList::Vertex3D(verts),
|
||||
indices: indices.into_u32().collect(),
|
||||
indices: inds,
|
||||
local_texture_index: texture_index,
|
||||
local_normal_map_index: normal_map_index,
|
||||
name: mesh.name().map(|n| n.to_owned()),
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use std::{sync::Arc, time::Instant};
|
||||
use std::time::SystemTime;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Instant, SystemTime};
|
||||
|
||||
use cgmath::{Matrix4, SquareMatrix};
|
||||
use dds::get_block_size;
|
||||
use rust_engine_proc::perf;
|
||||
use vulkano::device::physical::PhysicalDevice;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::render_pass::{FramebufferAbstract, RenderPass};
|
||||
@@ -14,7 +15,7 @@ use vulkano::image::{ImageCreateFlags, ImageDimensions, ImmutableImage};
|
||||
use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, Version};
|
||||
use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{AcquireError, FullscreenExclusive, PresentMode, Surface, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
use vulkano::swapchain::{AcquireError, FullscreenExclusive, Surface, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
use vulkano::swapchain;
|
||||
use vulkano::sync::{FlushError, GpuFuture};
|
||||
use vulkano::sync;
|
||||
@@ -23,15 +24,16 @@ use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
|
||||
use mesh::CPUMesh;
|
||||
use pipelines::{Drawcall};
|
||||
use pipelines::Drawcall;
|
||||
use pipelines::{DefaultShader, TextShader};
|
||||
use pipelines::vs;
|
||||
use winit::window::{Window, WindowBuilder};
|
||||
|
||||
use crate::config::RenderConfig;
|
||||
use crate::perf::{self, PerformanceCounter};
|
||||
use crate::vulkan::gameobject::GameObject;
|
||||
|
||||
use self::mesh::{CPUVertexList};
|
||||
use self::mesh::CPUVertexList;
|
||||
|
||||
pub mod pipelines;
|
||||
pub mod gameobject;
|
||||
@@ -44,8 +46,6 @@ const VALIDATION_LAYERS: &[&str] = &[
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
];
|
||||
|
||||
pub const PERF_COUNTER_SIZE: usize = 1000;
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct Vertex {
|
||||
pub position: [f32; 3],
|
||||
@@ -78,9 +78,11 @@ pub trait Game {
|
||||
/// Returns true if event should be ignored by the vulkan handler
|
||||
fn on_window_event(self: &mut Self, event: &Event<()>);
|
||||
|
||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> vs::ty::ObjectUniformData;
|
||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer);
|
||||
|
||||
fn get_game_objects(&self) -> &Vec<GameObject>;
|
||||
|
||||
fn get_ubo(&self) -> &vs::ty::ObjectUniformData;
|
||||
}
|
||||
|
||||
pub struct Mesh<V> {
|
||||
@@ -112,11 +114,6 @@ pub struct GameData {
|
||||
pub meshes: Vec<Mesh<Vertex>>,
|
||||
pub meshes_text: Vec<Mesh<TextVertex>>,
|
||||
pub textures: Vec<Texture>,
|
||||
pub update_perf_counters: [u128; PERF_COUNTER_SIZE],
|
||||
pub render_perf_counters: [u128; PERF_COUNTER_SIZE],
|
||||
pub other_perf_counters: [u128; PERF_COUNTER_SIZE],
|
||||
pub other_perf_instant: Instant,
|
||||
pub performance_counter_index: usize,
|
||||
}
|
||||
|
||||
pub struct VulkanRenderer {
|
||||
@@ -133,7 +130,10 @@ pub struct VulkanRenderer {
|
||||
pub previous_frame_end: Option<Box<dyn GpuFuture>>,
|
||||
pub uniform_buffers: Vec<Arc<CpuAccessibleBuffer<vs::ty::ObjectUniformData>>>,
|
||||
pub render_config: RenderConfig,
|
||||
pub viewport: Viewport
|
||||
pub viewport: Viewport,
|
||||
pub fps_counter: [u128; perf::PERF_COUNTER_SIZE],
|
||||
pub fps_counter_index: usize,
|
||||
pub fps_counter_instant: Instant,
|
||||
}
|
||||
|
||||
impl VulkanRenderer {
|
||||
@@ -147,11 +147,6 @@ impl VulkanRenderer {
|
||||
meshes: vec![],
|
||||
meshes_text: vec![],
|
||||
textures: vec![],
|
||||
update_perf_counters: [0; PERF_COUNTER_SIZE],
|
||||
render_perf_counters: [0; PERF_COUNTER_SIZE],
|
||||
other_perf_counters: [0; PERF_COUNTER_SIZE],
|
||||
performance_counter_index: 0,
|
||||
other_perf_instant: Instant::now(),
|
||||
};
|
||||
|
||||
// Create basic vulkan instance with layers and info
|
||||
@@ -230,7 +225,7 @@ impl VulkanRenderer {
|
||||
q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
|
||||
}).unwrap();
|
||||
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, ..DeviceExtensions::none() };
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, khr_maintenance1: true, ..DeviceExtensions::none() };
|
||||
let (device, mut queues) = Device::new(physical, &Features::none(), &device_ext,
|
||||
[(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
let queue = queues.next().unwrap();
|
||||
@@ -253,7 +248,7 @@ impl VulkanRenderer {
|
||||
.sharing_mode(&queue)
|
||||
.transform(SurfaceTransform::Identity)
|
||||
.composite_alpha(alpha)
|
||||
.present_mode(PresentMode::Fifo)
|
||||
.present_mode(render_config.vsync.into())
|
||||
.fullscreen_exclusive(FullscreenExclusive::Default)
|
||||
.clipped(true)
|
||||
.color_space(color_space)
|
||||
@@ -261,11 +256,7 @@ impl VulkanRenderer {
|
||||
};
|
||||
|
||||
let size = images[0].dimensions().width_height();
|
||||
let viewport = Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: [size[0] as f32, size[1] as f32],
|
||||
depth_range: 0.0..1.0,
|
||||
};
|
||||
let viewport = create_viewport(size[0] as f32, size[1] as f32);
|
||||
|
||||
// Render pass
|
||||
let render_pass = renderpass::create_render_pass(device.clone(), &render_config, swapchain.format());
|
||||
@@ -315,14 +306,16 @@ impl VulkanRenderer {
|
||||
pipelines, uniform_buffers,
|
||||
surface, swapchain, render_pass, queue,
|
||||
recreate_swapchain: false, debug_callback, previous_frame_end,
|
||||
render_config, viewport
|
||||
render_config, viewport,
|
||||
fps_counter: [0; perf::PERF_COUNTER_SIZE], fps_counter_index: 0, fps_counter_instant: Instant::now()
|
||||
}, events_loop)
|
||||
}
|
||||
|
||||
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) -> Arc<PrimaryAutoCommandBuffer> {
|
||||
#[perf("cb", crate::perf::PerformanceCounter)]
|
||||
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: &vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) -> Arc<PrimaryAutoCommandBuffer> {
|
||||
// General setup
|
||||
let mut builder = AutoCommandBufferBuilder::primary(self.device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap();
|
||||
builder.update_buffer(self.uniform_buffers[fb_index].clone(), Arc::new(uniform_buffer_data)).unwrap();
|
||||
builder.update_buffer(self.uniform_buffers[fb_index].clone(), Arc::new(*uniform_buffer_data)).unwrap();
|
||||
if self.render_config.msaa_samples > 0 {
|
||||
builder.begin_render_pass(self.framebuffers[fb_index].clone(), SubpassContents::Inline, vec![ClearValue::None, ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||
} else {
|
||||
@@ -344,9 +337,8 @@ impl VulkanRenderer {
|
||||
Arc::new(builder.build().unwrap())
|
||||
}
|
||||
|
||||
pub fn render_loop(self: &mut Self, new_ubo: vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) {
|
||||
let precise_start = Instant::now();
|
||||
|
||||
#[perf("renderer", crate::perf::PerformanceCounter)]
|
||||
pub fn render_loop(self: &mut Self, new_ubo: &vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) {
|
||||
// cleanup previous frame
|
||||
self.previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||
|
||||
@@ -368,12 +360,7 @@ impl VulkanRenderer {
|
||||
};
|
||||
|
||||
let size = new_images[0].dimensions().width_height();
|
||||
|
||||
self.viewport = Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: [size[0] as f32, size[1] as f32],
|
||||
depth_range: 0.0..1.0,
|
||||
};
|
||||
self.viewport = create_viewport(size[0] as f32, size[1] as f32);
|
||||
|
||||
self.render_pass = renderpass::create_render_pass(self.device.clone(), &self.render_config, new_swapchain.format());
|
||||
|
||||
@@ -421,7 +408,7 @@ impl VulkanRenderer {
|
||||
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
||||
.then_swapchain_present(self.queue.clone(), self.swapchain.clone(), fb_index)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
|
||||
match future {
|
||||
Ok(future) => {
|
||||
// we're joining on the previous future but the CPU is running faster than the GPU so
|
||||
@@ -445,8 +432,6 @@ impl VulkanRenderer {
|
||||
self.previous_frame_end = Some(Box::new(sync::now(self.device.clone())) as Box<_>);
|
||||
}
|
||||
};
|
||||
|
||||
self.game_data.render_perf_counters[self.game_data.performance_counter_index] = precise_start.elapsed().as_micros();
|
||||
}
|
||||
|
||||
pub fn upload_mesh(self: &mut Self, mesh: CPUMesh, original_path: Option<String>) -> usize {
|
||||
@@ -683,6 +668,8 @@ impl VulkanRenderer {
|
||||
}
|
||||
|
||||
pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box<dyn Game>, event_loop: EventLoop<()>) {
|
||||
PerformanceCounter::init_perf();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
game.on_window_event(&event);
|
||||
|
||||
@@ -694,15 +681,37 @@ pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box<dyn Game>, e
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
},
|
||||
Event::RedrawEventsCleared => {
|
||||
let ubo = game.update(&mut renderer);
|
||||
renderer.render_loop(ubo, &game.get_game_objects());
|
||||
renderer.game_data.other_perf_counters[renderer.game_data.performance_counter_index] = renderer.game_data.other_perf_instant.elapsed().as_micros();
|
||||
renderer.game_data.other_perf_instant = Instant::now();
|
||||
renderer.game_data.performance_counter_index = (renderer.game_data.performance_counter_index + 1) % PERF_COUNTER_SIZE;
|
||||
Event::WindowEvent { event: WindowEvent::Resized(..), .. } => {
|
||||
renderer.recreate_swapchain = true;
|
||||
},
|
||||
Event::RedrawRequested(..) => {
|
||||
PerformanceCounter::perf_next_frame("renderer");
|
||||
PerformanceCounter::perf_next_frame("cb");
|
||||
renderer.fps_counter[renderer.fps_counter_index] = renderer.fps_counter_instant.elapsed().as_micros();
|
||||
renderer.fps_counter_instant = Instant::now();
|
||||
renderer.fps_counter_index = (renderer.fps_counter_index + 1) % perf::PERF_COUNTER_SIZE;
|
||||
renderer.render_loop(game.get_ubo(), &game.get_game_objects());
|
||||
},
|
||||
Event::MainEventsCleared => {
|
||||
PerformanceCounter::perf_next_frame("update");
|
||||
PerformanceCounter::perf_next_frame("input_events");
|
||||
game.update(&mut renderer);
|
||||
renderer.surface.window().request_redraw();
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn create_viewport(width: f32, height: f32) -> Viewport {
|
||||
Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: [width, height],
|
||||
depth_range: 0.0..1.0,
|
||||
}
|
||||
// Viewport {
|
||||
// origin: [0.0, height],
|
||||
// dimensions: [width, -height],
|
||||
// depth_range: 0.0..1.0,
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user