Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
E
Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces Using Modern RTX Enabled GPUs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
John Hunter
Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces Using Modern RTX Enabled GPUs
Commits
fc455c91
Unverified
Commit
fc455c91
authored
2 years ago
by
John Hunter
Browse files
Options
Downloads
Patches
Plain Diff
implement ui
parent
c455bc09
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/gui.rs
+50
-0
50 additions, 0 deletions
src/gui.rs
src/main.rs
+176
-45
176 additions, 45 deletions
src/main.rs
with
226 additions
and
45 deletions
src/gui.rs
0 → 100644
+
50
−
0
View file @
fc455c91
use
egui
::{
Color32
,
Frame
,
Id
,
ScrollArea
,
TextEdit
,
TextStyle
};
use
egui_winit_vulkano
::
Gui
;
fn
sized_text
(
ui
:
&
mut
egui
::
Ui
,
text
:
impl
Into
<
String
>
,
size
:
f32
)
{
ui
.label
(
egui
::
RichText
::
new
(
text
)
.size
(
size
));
}
const
CODE
:
&
str
=
r#"
# Some markup
```
let mut gui = Gui::new(&event_loop, renderer.surface(), renderer.queue());
```
Vulkan(o) is hard, that I know...
"#
;
#[derive(Debug)]
pub
struct
GState
{
pub
cursor_sensitivity
:
f32
,
pub
move_speed
:
f32
,
}
impl
Default
for
GState
{
fn
default
()
->
Self
{
Self
{
cursor_sensitivity
:
1.0
,
move_speed
:
1.0
,
}
}
}
pub
fn
gui_up
(
gui
:
&
mut
Gui
,
state
:
&
mut
GState
)
{
let
mut
code
=
CODE
.to_owned
();
gui
.immediate_ui
(|
gui
|
{
let
ctx
=
gui
.context
();
egui
::
SidePanel
::
left
(
Id
::
new
(
"main_left"
))
.frame
(
Frame
::
default
()
.fill
(
Color32
::
from_rgba_unmultiplied
(
100
,
100
,
100
,
200
)))
.show
(
&
ctx
,
|
ui
|
{
ui
.vertical_centered
(|
ui
|
{
ui
.add
(
egui
::
widgets
::
Label
::
new
(
"Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces Using Modern RTX Enabled GPUs"
));
sized_text
(
ui
,
"Settings"
,
32.0
);
});
ui
.separator
();
ui
.vertical_centered
(|
ui
|
{
//ui.heading("Camera Control");
ui
.add
(
egui
::
Slider
::
new
(
&
mut
state
.cursor_sensitivity
,
0.0
..=
2.0
)
.text
(
"Mouse Sensitivity"
));
ui
.add
(
egui
::
Slider
::
new
(
&
mut
state
.move_speed
,
0.0
..=
2.0
)
.text
(
"Movement Speed"
));
});
});
});
}
This diff is collapsed.
Click to expand it.
src/main.rs
+
176
−
45
View file @
fc455c91
...
@@ -16,23 +16,24 @@
...
@@ -16,23 +16,24 @@
// and that you want to learn Vulkan. This means that for example it won't go into details about
// and that you want to learn Vulkan. This means that for example it won't go into details about
// what a vertex or a shader is.
// what a vertex or a shader is.
use
bytemuck
::{
Pod
,
Zeroable
};
use
bytemuck
::{
Pod
,
Zeroable
};
use
cgmath
::{
Matrix3
,
Matrix4
,
Point3
,
Rad
,
Vector3
};
use
cgmath
::{
AbsDiffEq
,
Basis3
,
Deg
,
EuclideanSpace
,
Euler
,
Matrix3
,
Matrix4
,
Point3
,
Quaternion
,
Rad
,
SquareMatrix
,
Transform
,
Vector3
,
};
use
obj
::{
LoadConfig
,
ObjData
};
use
obj
::{
LoadConfig
,
ObjData
};
use
rodio
::{
source
::
Source
,
Decoder
,
OutputStream
};
use
rodio
::{
source
::
Source
,
Decoder
,
OutputStream
};
use
std
::
io
::
Cursor
;
use
std
::
io
::
Cursor
;
use
std
::{
sync
::
Arc
,
time
::
Instant
};
use
std
::{
sync
::
Arc
,
time
::
Instant
};
use
vulkano
::
buffer
::
CpuBufferPool
;
use
vulkano
::
command_buffer
::
allocator
::
StandardCommandBufferAllocator
;
use
vulkano
::
command_buffer
::
allocator
::
StandardCommandBufferAllocator
;
use
vulkano
::
descriptor_set
::
allocator
::
StandardDescriptorSetAllocator
;
use
vulkano
::
device
::
QueueFlags
;
use
vulkano
::
format
::
Format
;
use
vulkano
::
format
::
Format
;
use
vulkano
::
image
::
AttachmentImage
;
use
vulkano
::
image
::
AttachmentImage
;
use
vulkano
::
memory
::
allocator
::
{
MemoryAllocator
,
MemoryUsage
,
StandardMemoryAllocator
}
;
use
vulkano
::
memory
::
allocator
::
StandardMemoryAllocator
;
use
vulkano
::
pipeline
::
graphics
::
depth_stencil
::
DepthStencilState
;
use
vulkano
::
pipeline
::
graphics
::
depth_stencil
::
DepthStencilState
;
use
vulkano
::
pipeline
::
graphics
::
rasterization
::
CullMode
;
use
vulkano
::
pipeline
::
graphics
::
rasterization
::
CullMode
;
use
vulkano
::
pipeline
::
graphics
::
rasterization
::
FrontFace
::
Clockwise
;
use
vulkano
::
pipeline
::
graphics
::
rasterization
::
FrontFace
::
Clockwise
;
use
vulkano
::
swapchain
::
SwapchainPresentInfo
;
use
vulkano
::
swapchain
::{
PresentMode
,
SwapchainPresentInfo
};
use
vulkano
::{
memory
,
VulkanLibrary
};
use
vulkano
::
VulkanLibrary
;
use
winit
::
event
::{
DeviceEvent
,
DeviceId
,
ElementState
,
MouseButton
,
VirtualKeyCode
};
use
egui_winit_vulkano
::
Gui
;
use
egui_winit_vulkano
::
Gui
;
use
vulkano
::
pipeline
::
StateMode
::
Fixed
;
use
vulkano
::
pipeline
::
StateMode
::
Fixed
;
...
@@ -41,7 +42,6 @@ use vulkano::{
...
@@ -41,7 +42,6 @@ use vulkano::{
command_buffer
::{
command_buffer
::{
AutoCommandBufferBuilder
,
CommandBufferUsage
,
RenderPassBeginInfo
,
SubpassContents
,
AutoCommandBufferBuilder
,
CommandBufferUsage
,
RenderPassBeginInfo
,
SubpassContents
,
},
},
descriptor_set
::{
PersistentDescriptorSet
,
WriteDescriptorSet
},
device
::{
device
::{
physical
::
PhysicalDeviceType
,
Device
,
DeviceCreateInfo
,
DeviceExtensions
,
QueueCreateInfo
,
physical
::
PhysicalDeviceType
,
Device
,
DeviceCreateInfo
,
DeviceExtensions
,
QueueCreateInfo
,
},
},
...
@@ -55,7 +55,7 @@ use vulkano::{
...
@@ -55,7 +55,7 @@ use vulkano::{
vertex_input
::
BuffersDefinition
,
vertex_input
::
BuffersDefinition
,
viewport
::{
Viewport
,
ViewportState
},
viewport
::{
Viewport
,
ViewportState
},
},
},
GraphicsPipeline
,
Pipeline
,
PipelineBindPoint
,
GraphicsPipeline
,
Pipeline
,
},
},
render_pass
::{
Framebuffer
,
FramebufferCreateInfo
,
RenderPass
,
Subpass
},
render_pass
::{
Framebuffer
,
FramebufferCreateInfo
,
RenderPass
,
Subpass
},
swapchain
::{
swapchain
::{
...
@@ -70,6 +70,9 @@ use winit::{
...
@@ -70,6 +70,9 @@ use winit::{
window
::{
Window
,
WindowBuilder
},
window
::{
Window
,
WindowBuilder
},
};
};
use
crate
::
gui
::
*
;
mod
gui
;
fn
main
()
{
fn
main
()
{
// The first step of any Vulkan program is to create an instance.
// The first step of any Vulkan program is to create an instance.
//
//
...
@@ -213,9 +216,6 @@ fn main() {
...
@@ -213,9 +216,6 @@ fn main() {
// iterator.
// iterator.
let
queue
=
queues
.next
()
.expect
(
"Unable to retrieve queues"
);
let
queue
=
queues
.next
()
.expect
(
"Unable to retrieve queues"
);
// Create an egui GUI
let
mut
gui
=
Gui
::
new
(
&
event_loop
,
surface
.clone
(),
None
,
queue
.clone
(),
false
);
// Before we can draw on the surface, we have to create what is called a swapchain. Creating
// Before we can draw on the surface, we have to create what is called a swapchain. Creating
// a swapchain allocates the color buffers that will contain the image that will ultimately
// a swapchain allocates the color buffers that will contain the image that will ultimately
// be visible on the screen. These images are returned alongside the swapchain.
// be visible on the screen. These images are returned alongside the swapchain.
...
@@ -276,6 +276,8 @@ fn main() {
...
@@ -276,6 +276,8 @@ fn main() {
.next
()
.next
()
.unwrap
(),
.unwrap
(),
present_mode
:
PresentMode
::
FifoRelaxed
,
..
Default
::
default
()
..
Default
::
default
()
},
},
)
)
...
@@ -393,7 +395,7 @@ fn main() {
...
@@ -393,7 +395,7 @@ fn main() {
// The next step is to create a *render pass*, which is an object that describes where the
// The next step is to create a *render pass*, which is an object that describes where the
// output of the graphics pipeline will go. It describes the layout of the images
// output of the graphics pipeline will go. It describes the layout of the images
// where the colors, depth and/or stencil information will be written.
// where the colors, depth and/or stencil information will be written.
let
render_pass
=
vulkano
::
single
_pass_renderpass!
(
let
render_pass
=
vulkano
::
ordered
_pass
es
_renderpass!
(
device
.clone
(),
device
.clone
(),
attachments
:
{
attachments
:
{
// `color` is a custom name we give to the first and only attachment.
// `color` is a custom name we give to the first and only attachment.
...
@@ -421,12 +423,19 @@ fn main() {
...
@@ -421,12 +423,19 @@ fn main() {
samples
:
1
,
samples
:
1
,
}
}
},
},
pass
:
{
pass
es
:
[
{
// We use the attachment named `color` as the one and only color attachment.
// We use the attachment named `color` as the one and only color attachment.
color
:
[
color
],
color
:
[
color
],
// No depth-stencil attachment is indicated with empty brackets.
// No depth-stencil attachment is indicated with empty brackets.
depth_stencil
:
{
depth
}
depth_stencil
:
{
depth
},
}
input
:
[]
},{
// We use the attachment named `color` as the one and only color attachment.
color
:
[
color
],
// No depth-stencil attachment is indicated with empty brackets.
depth_stencil
:
{
depth
},
input
:
[]
}]
)
)
.unwrap
();
.unwrap
();
...
@@ -504,6 +513,7 @@ fn main() {
...
@@ -504,6 +513,7 @@ fn main() {
// that, we store the submission of the previous frame here.
// that, we store the submission of the previous frame here.
let
mut
previous_frame_end
=
Some
(
sync
::
now
(
device
.clone
())
.boxed
());
let
mut
previous_frame_end
=
Some
(
sync
::
now
(
device
.clone
())
.boxed
());
/*
// Get a output stream handle to the default physical sound device
// Get a output stream handle to the default physical sound device
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
// Load a sound from a file, using a path relative to Cargo.toml
// Load a sound from a file, using a path relative to Cargo.toml
...
@@ -512,24 +522,101 @@ fn main() {
...
@@ -512,24 +522,101 @@ fn main() {
let source = Decoder::new(freebird).unwrap().repeat_infinite();
let source = Decoder::new(freebird).unwrap().repeat_infinite();
// Play the sound directly on the device
// Play the sound directly on the device
stream_handle.play_raw(source.convert_samples()).unwrap();
stream_handle.play_raw(source.convert_samples()).unwrap();
*/
let
rotation_start
=
Instant
::
now
();
let
rotation_start
=
Instant
::
now
();
//let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone());
//let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone());
// Create an egui GUI
let
mut
gui
=
Gui
::
new_with_subpass
(
&
event_loop
,
surface
.clone
(),
None
,
queue
.clone
(),
Subpass
::
from
(
render_pass
.clone
(),
1
)
.unwrap
(),
);
let
mut
gstate
=
GState
::
default
();
let
mut
campos
=
Point3
{
x
:
0f32
,
y
:
0f32
,
z
:
3f32
,
};
let
mut
camforward
=
Euler
::
new
(
Deg
(
0f32
),
Deg
(
0f32
),
Deg
(
0f32
));
let
mut
looking
=
false
;
struct
Keys
{
w
:
bool
,
s
:
bool
,
a
:
bool
,
d
:
bool
,
}
let
mut
keys
=
Keys
{
w
:
false
,
s
:
false
,
a
:
false
,
d
:
false
,
};
event_loop
.run
(
move
|
event
,
_
,
control_flow
|
{
event_loop
.run
(
move
|
event
,
_
,
control_flow
|
{
match
event
{
if
let
Event
::
WindowEvent
{
event
:
we
,
..
}
=
&
event
{
Event
::
WindowEvent
{
if
!
gui
.update
(
we
)
{
event
:
WindowEvent
::
CloseRequested
,
match
&
we
{
..
WindowEvent
::
CloseRequested
=>
{
}
=>
{
*
control_flow
=
ControlFlow
::
Exit
;
*
control_flow
=
ControlFlow
::
Exit
;
}
WindowEvent
::
Resized
(
_
)
=>
{
recreate_swapchain
=
true
;
}
WindowEvent
::
ScaleFactorChanged
{
..
}
=>
{
recreate_swapchain
=
true
;
}
WindowEvent
::
DroppedFile
(
file
)
=>
{
todo!
()
}
WindowEvent
::
MouseInput
{
device_id
:
d
,
state
:
s
,
button
:
b
,
..
}
=>
{
println!
(
"MOUSE {:?}, {:?}, {:?}"
,
d
,
s
,
b
);
if
b
==
&
MouseButton
::
Right
{
looking
=
s
==
&
ElementState
::
Pressed
;
}
}
WindowEvent
::
KeyboardInput
{
input
,
..
}
=>
match
input
.virtual_keycode
{
Some
(
VirtualKeyCode
::
W
)
=>
{
keys
.w
=
input
.state
==
ElementState
::
Pressed
;
}
Some
(
VirtualKeyCode
::
S
)
=>
{
keys
.s
=
input
.state
==
ElementState
::
Pressed
;
}
Some
(
VirtualKeyCode
::
A
)
=>
{
keys
.a
=
input
.state
==
ElementState
::
Pressed
;
}
Some
(
VirtualKeyCode
::
D
)
=>
{
keys
.d
=
input
.state
==
ElementState
::
Pressed
;
}
_
=>
{}
},
_
=>
{}
}
}
}
Event
::
WindowEvent
{
}
event
:
WindowEvent
::
Resized
(
_
),
match
event
{
Event
::
DeviceEvent
{
event
:
DeviceEvent
::
MouseMotion
{
delta
},
..
..
}
=>
{
}
=>
{
recreate_swapchain
=
true
;
if
looking
{
camforward
.x
-=
Deg
(
delta
.1
as
f32
)
*
gstate
.cursor_sensitivity
;
camforward
.y
+=
Deg
(
delta
.0
as
f32
)
*
gstate
.cursor_sensitivity
;
}
//println!("AXISM {:?}", delta);
}
}
Event
::
RedrawEventsCleared
=>
{
Event
::
RedrawEventsCleared
=>
{
// Do not draw frame when screen dimensions are zero.
// Do not draw frame when screen dimensions are zero.
...
@@ -575,11 +662,44 @@ fn main() {
...
@@ -575,11 +662,44 @@ fn main() {
recreate_swapchain
=
false
;
recreate_swapchain
=
false
;
}
}
//println!("{:?}", right);
let
uniform_data
=
{
let
uniform_data
=
{
let
elapsed
=
rotation_start
.elapsed
();
if
looking
{
let
rotation
=
if
keys
.w
{
elapsed
.as_secs
()
as
f64
+
elapsed
.subsec_nanos
()
as
f64
/
1_000_000_000.0
;
campos
-=
Matrix3
::
from_angle_y
(
camforward
.y
)
let
rotation
=
Matrix3
::
from_angle_y
(
Rad
(
rotation
as
f32
));
*
Matrix3
::
from_angle_x
(
camforward
.x
)
*
Vector3
::
unit_z
()
*
0.02
*
gstate
.move_speed
;
}
if
keys
.s
{
campos
+=
Matrix3
::
from_angle_y
(
camforward
.y
)
*
Matrix3
::
from_angle_x
(
camforward
.x
)
*
Vector3
::
unit_z
()
*
0.02
*
gstate
.move_speed
;
}
if
keys
.a
{
campos
+=
Matrix3
::
from_angle_y
(
camforward
.y
)
*
Matrix3
::
from_angle_x
(
camforward
.x
)
*
Vector3
::
unit_x
()
*
0.02
*
gstate
.move_speed
;
}
if
keys
.d
{
campos
-=
Matrix3
::
from_angle_y
(
camforward
.y
)
*
Matrix3
::
from_angle_x
(
camforward
.x
)
*
Vector3
::
unit_x
()
*
0.02
*
gstate
.move_speed
;
}
}
else
{
keys
.w
=
false
;
keys
.s
=
false
;
keys
.a
=
false
;
keys
.d
=
false
;
}
// note: this teapot was meant for OpenGL where the origin is at the lower left
// note: this teapot was meant for OpenGL where the origin is at the lower left
// instead the origin is at the upper left in Vulkan, so we reverse the Y axis
// instead the origin is at the upper left in Vulkan, so we reverse the Y axis
...
@@ -591,25 +711,28 @@ fn main() {
...
@@ -591,25 +711,28 @@ fn main() {
0.01
,
0.01
,
100.0
,
100.0
,
);
);
let
view
=
Matrix4
::
look_at_rh
(
let
scale
=
0.01
;
Point3
::
new
(
0.3
,
0.3
,
1.0
),
let
view
=
Matrix4
::
from
(
camforward
)
Point3
::
new
(
0.0
,
0.0
,
0.0
),
*
Matrix4
::
from_angle_z
(
Deg
(
180f32
))
Vector3
::
new
(
0.0
,
-
1.0
,
0.0
),
*
Matrix4
::
from_translation
(
Point3
::
origin
()
-
campos
)
);
*
Matrix4
::
from_scale
(
scale
);
let
scale
=
Matrix4
::
from_
scale
(
0.01
);
//*
Matrix4::from_
angle_z(Deg(180f32)
);
vs
::
ty
::
PushConstantData
{
let
pc
=
vs
::
ty
::
PushConstantData
{
world
:
Matrix4
::
from
(
rotation
)
.into
(),
world
:
Matrix4
::
identity
(
)
.into
(),
view
:
(
view
*
scale
)
.into
(),
view
:
view
.into
(),
proj
:
proj
.into
(),
proj
:
proj
.into
(),
}
}
;
/*println!(
if
looking
{
"world: {:?} view: {:?} proj: {:?}",
/*println!(
uniform_data.world, uniform_data.view, uniform_data.proj
"world: {:?} view: {:?} proj: {:?}",
);*/
pc.world, pc.view, pc.proj
);*/
println!
(
"campos: {:?} camforward: {:?}"
,
campos
,
camforward
);
}
//uniform_buffer.from_data(uniform_data).unwrap()
pc
};
};
//let layout = pipeline.layout().set_layouts().get(0).unwrap();
//let layout = pipeline.layout().set_layouts().get(0).unwrap();
...
@@ -644,6 +767,8 @@ fn main() {
...
@@ -644,6 +767,8 @@ fn main() {
recreate_swapchain
=
true
;
recreate_swapchain
=
true
;
}
}
gui_up
(
&
mut
gui
,
&
mut
gstate
);
// In order to draw, we have to build a *command buffer*. The command buffer object holds
// In order to draw, we have to build a *command buffer*. The command buffer object holds
// the list of commands that are going to be executed.
// the list of commands that are going to be executed.
//
//
...
@@ -660,6 +785,8 @@ fn main() {
...
@@ -660,6 +785,8 @@ fn main() {
)
)
.unwrap
();
.unwrap
();
let
cb
=
gui
.draw_on_subpass_image
(
dimensions
.into
());
builder
builder
// Before we can draw, we have to *enter a render pass*.
// Before we can draw, we have to *enter a render pass*.
.begin_render_pass
(
.begin_render_pass
(
...
@@ -702,6 +829,10 @@ fn main() {
...
@@ -702,6 +829,10 @@ fn main() {
.unwrap
()
.unwrap
()
// We leave the render pass. Note that if we had multiple
// We leave the render pass. Note that if we had multiple
// subpasses we could have called `next_subpass` to jump to the next subpass.
// subpasses we could have called `next_subpass` to jump to the next subpass.
.next_subpass
(
SubpassContents
::
SecondaryCommandBuffers
)
.unwrap
()
.execute_commands
(
cb
)
.unwrap
()
.end_render_pass
()
.end_render_pass
()
.unwrap
();
.unwrap
();
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment