aboutsummaryrefslogtreecommitdiff
path: root/stockton-render/src/draw
diff options
context:
space:
mode:
Diffstat (limited to 'stockton-render/src/draw')
-rw-r--r--stockton-render/src/draw/context.rs63
-rw-r--r--stockton-render/src/draw/draw_buffers.rs8
-rw-r--r--stockton-render/src/draw/macros.rs28
-rw-r--r--stockton-render/src/draw/render.rs2
-rw-r--r--stockton-render/src/draw/target.rs8
-rw-r--r--stockton-render/src/draw/ui/data/stockton.frag11
-rw-r--r--stockton-render/src/draw/ui/data/stockton.vert27
-rw-r--r--stockton-render/src/draw/ui/mod.rs8
-rw-r--r--stockton-render/src/draw/ui/pipeline.rs18
-rw-r--r--stockton-render/src/draw/ui/render.rs55
-rwxr-xr-xstockton-render/src/draw/ui/texture.rs54
11 files changed, 234 insertions, 48 deletions
diff --git a/stockton-render/src/draw/context.rs b/stockton-render/src/draw/context.rs
index 94f1f0c..4d700e5 100644
--- a/stockton-render/src/draw/context.rs
+++ b/stockton-render/src/draw/context.rs
@@ -29,14 +29,14 @@ use winit::window::Window;
use super::{
buffer::ModifiableBuffer,
- draw_buffers::DrawBuffers,
+ draw_buffers::{DrawBuffers, UVPoint},
pipeline::CompletePipeline,
render::do_render,
target::{SwapchainProperties, TargetChain},
texture::TextureStore,
- ui::{do_render as do_render_ui, UIPipeline},
+ ui::{do_render as do_render_ui, ensure_textures as ensure_textures_ui, UIPipeline, UIPoint},
};
-use crate::{error, types::*};
+use crate::{error, types::*, window::UIState};
use stockton_levels::prelude::*;
/// Contains all the hal related stuff.
@@ -76,14 +76,19 @@ pub struct RenderingContext<'a> {
/// Texture store
texture_store: ManuallyDrop<TextureStore>,
+ /// Texture store for UI
+ ui_texture_store: ManuallyDrop<TextureStore>,
+
/// Buffers used for drawing
- draw_buffers: ManuallyDrop<DrawBuffers<'a>>,
+ draw_buffers: ManuallyDrop<DrawBuffers<'a, UVPoint>>,
/// Buffers used for drawing the UI
- ui_draw_buffers: ManuallyDrop<DrawBuffers<'a>>,
+ ui_draw_buffers: ManuallyDrop<DrawBuffers<'a, UIPoint>>,
/// View projection matrix
pub(crate) vp_matrix: Mat4,
+
+ pub(crate) pixels_per_point: f32,
}
impl<'a> RenderingContext<'a> {
@@ -156,9 +161,21 @@ impl<'a> RenderingContext<'a> {
file,
)?;
+ // Texture store for UI elements
+ let ui_texture_store = TextureStore::new_empty(
+ &mut device,
+ &mut adapter,
+ &mut queue_group.queues[0],
+ &mut cmd_pool,
+ 1, // TODO
+ )?;
+
let mut descriptor_set_layouts: ArrayVec<[_; 2]> = ArrayVec::new();
descriptor_set_layouts.push(texture_store.descriptor_set_layout.deref());
+ let mut ui_descriptor_set_layouts: ArrayVec<[_; 2]> = ArrayVec::new();
+ ui_descriptor_set_layouts.push(ui_texture_store.descriptor_set_layout.deref());
+
// Graphics pipeline
let pipeline = CompletePipeline::new(
&mut device,
@@ -172,7 +189,7 @@ impl<'a> RenderingContext<'a> {
&mut device,
swapchain_properties.extent,
&swapchain_properties,
- &[],
+ ui_descriptor_set_layouts,
)?;
// Swapchain and associated resources
@@ -207,7 +224,11 @@ impl<'a> RenderingContext<'a> {
draw_buffers: ManuallyDrop::new(draw_buffers),
ui_draw_buffers: ManuallyDrop::new(ui_draw_buffers),
+ ui_texture_store: ManuallyDrop::new(ui_texture_store),
+
vp_matrix: Mat4::identity(),
+
+ pixels_per_point: window.scale_factor() as f32,
})
}
@@ -241,7 +262,15 @@ impl<'a> RenderingContext<'a> {
// TODO: Recycle
ManuallyDrop::into_inner(read(&self.ui_pipeline)).deactivate(&mut self.device);
self.ui_pipeline = ManuallyDrop::new({
- UIPipeline::new(&mut self.device, properties.extent, &properties, &[])?
+ let mut descriptor_set_layouts: ArrayVec<[_; 1]> = ArrayVec::new();
+ descriptor_set_layouts.push(self.ui_texture_store.descriptor_set_layout.deref());
+
+ UIPipeline::new(
+ &mut self.device,
+ properties.extent,
+ &properties,
+ descriptor_set_layouts,
+ )?
});
let old_swapchain = ManuallyDrop::into_inner(read(&self.target_chain))
@@ -267,8 +296,19 @@ impl<'a> RenderingContext<'a> {
pub fn draw_vertices<M: MinBSPFeatures<VulkanSystem>>(
&mut self,
file: &M,
+ ui: &mut UIState,
faces: &[u32],
) -> Result<(), &'static str> {
+ // Ensure UI texture(s) are loaded
+ ensure_textures_ui(
+ &mut self.ui_texture_store,
+ ui,
+ &mut self.device,
+ &mut self.adapter,
+ &mut self.queue_group.queues[0],
+ &mut self.cmd_pool,
+ );
+
// 3D Pass
let cmd_buffer = self.target_chain.prep_next_target(
&mut self.device,
@@ -289,7 +329,13 @@ impl<'a> RenderingContext<'a> {
let cmd_buffer = self
.target_chain
.target_2d_pass(&mut self.ui_draw_buffers, &self.ui_pipeline)?;
- do_render_ui(cmd_buffer, &mut self.ui_draw_buffers);
+ do_render_ui(
+ cmd_buffer,
+ &self.ui_pipeline.pipeline_layout,
+ &mut self.ui_draw_buffers,
+ &mut self.ui_texture_store,
+ ui,
+ );
// Update our buffers before we actually start drawing
self.draw_buffers.vertex_buffer.commit(
@@ -334,6 +380,7 @@ impl<'a> core::ops::Drop for RenderingContext<'a> {
ManuallyDrop::into_inner(read(&self.draw_buffers)).deactivate(&mut self.device);
ManuallyDrop::into_inner(read(&self.ui_draw_buffers)).deactivate(&mut self.device);
ManuallyDrop::into_inner(read(&self.texture_store)).deactivate(&mut self.device);
+ ManuallyDrop::into_inner(read(&self.ui_texture_store)).deactivate(&mut self.device);
ManuallyDrop::into_inner(read(&self.target_chain))
.deactivate(&mut self.device, &mut self.cmd_pool);
diff --git a/stockton-render/src/draw/draw_buffers.rs b/stockton-render/src/draw/draw_buffers.rs
index a6e0996..837356a 100644
--- a/stockton-render/src/draw/draw_buffers.rs
+++ b/stockton-render/src/draw/draw_buffers.rs
@@ -31,13 +31,13 @@ pub const INITIAL_VERT_SIZE: u64 = 3 * 3000;
pub const INITIAL_INDEX_SIZE: u64 = 3000;
/// The buffers used for drawing, ie index and vertex buffer
-pub struct DrawBuffers<'a> {
- pub vertex_buffer: ManuallyDrop<StagedBuffer<'a, UVPoint>>,
+pub struct DrawBuffers<'a, T: Sized> {
+ pub vertex_buffer: ManuallyDrop<StagedBuffer<'a, T>>,
pub index_buffer: ManuallyDrop<StagedBuffer<'a, (u16, u16, u16)>>,
}
-impl<'a> DrawBuffers<'a> {
- pub fn new(device: &mut Device, adapter: &Adapter) -> Result<DrawBuffers<'a>, CreationError> {
+impl<'a, T> DrawBuffers<'a, T> {
+ pub fn new(device: &mut Device, adapter: &Adapter) -> Result<DrawBuffers<'a, T>, CreationError> {
let vert = StagedBuffer::new(device, &adapter, Usage::VERTEX, INITIAL_VERT_SIZE)?;
let index = StagedBuffer::new(device, &adapter, Usage::INDEX, INITIAL_INDEX_SIZE)?;
diff --git a/stockton-render/src/draw/macros.rs b/stockton-render/src/draw/macros.rs
index 9096958..e1ee515 100644
--- a/stockton-render/src/draw/macros.rs
+++ b/stockton-render/src/draw/macros.rs
@@ -29,6 +29,20 @@
/// ```
/// See the hal::pso::Format enum for possible types
macro_rules! pipeline_vb_attributes {
+ // Special case for single item
+ ( $binding:expr, $firstSize:expr; $firstType:ident ) => ({
+ vec![
+ AttributeDesc {
+ location: 0,
+ binding: $binding,
+ element: Element {
+ format: Format::$firstType,
+ offset: $firstSize as u32
+ }
+ }
+ ]
+ });
+
// Start of recursion
( $binding:expr,
$firstSize:expr; $firstType:ident,
@@ -55,20 +69,6 @@ macro_rules! pipeline_vb_attributes {
vec
});
- // Special case for single item
- ( $binding:expr; $firstSize:expr; $firstType:ident ) => ({
- vec![
- AttributeDesc {
- location: 0,
- binding: $binding,
- element: Element {
- format: Format::$firstType,
- offset: $firstSize as u32
- }
- }
- ]
- });
-
// Middle of recursion
( $vec:ident; $binding:expr; $location:expr; $prevSize:expr,
$firstSize:expr; $firstType:ident,
diff --git a/stockton-render/src/draw/render.rs b/stockton-render/src/draw/render.rs
index e73b569..093e257 100644
--- a/stockton-render/src/draw/render.rs
+++ b/stockton-render/src/draw/render.rs
@@ -31,7 +31,7 @@ use crate::types::*;
pub fn do_render<M: MinBSPFeatures<VulkanSystem>>(
cmd_buffer: &mut CommandBuffer,
- draw_buffers: &mut DrawBuffers,
+ draw_buffers: &mut DrawBuffers<UVPoint>,
texture_store: &TextureStore,
pipeline_layout: &PipelineLayout,
file: &M,
diff --git a/stockton-render/src/draw/target.rs b/stockton-render/src/draw/target.rs
index b47700f..daf9942 100644
--- a/stockton-render/src/draw/target.rs
+++ b/stockton-render/src/draw/target.rs
@@ -31,8 +31,8 @@ use hal::{
use na::Mat4;
use super::{
- buffer::ModifiableBuffer, draw_buffers::DrawBuffers, pipeline::CompletePipeline,
- texture::image::LoadedImage, ui::UIPipeline,
+ buffer::ModifiableBuffer, draw_buffers::{DrawBuffers, UVPoint}, pipeline::CompletePipeline,
+ texture::image::LoadedImage, ui::{UIPipeline, UIPoint},
};
use crate::types::*;
@@ -275,7 +275,7 @@ impl TargetChain {
pub fn prep_next_target<'a>(
&'a mut self,
device: &mut Device,
- draw_buffers: &mut DrawBuffers,
+ draw_buffers: &mut DrawBuffers<UVPoint>,
pipeline: &CompletePipeline,
vp: &Mat4,
) -> Result<&'a mut crate::types::CommandBuffer, &'static str> {
@@ -373,7 +373,7 @@ impl TargetChain {
pub fn target_2d_pass<'a>(
&'a mut self,
- draw_buffers: &mut DrawBuffers,
+ draw_buffers: &mut DrawBuffers<UIPoint>,
pipeline: &UIPipeline,
) -> Result<&'a mut CommandBuffer, &'static str> {
let target = &mut self.targets[self.last_image as usize];
diff --git a/stockton-render/src/draw/ui/data/stockton.frag b/stockton-render/src/draw/ui/data/stockton.frag
index 1a85ab6..e5b2b4d 100644
--- a/stockton-render/src/draw/ui/data/stockton.frag
+++ b/stockton-render/src/draw/ui/data/stockton.frag
@@ -1,8 +1,15 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
-layout(location = 0) out vec4 outColor;
+// DescriptorSet 0 = Textures
+layout(set = 0, binding = 0) uniform texture2D tex[8];
+layout(set = 0, binding = 1) uniform sampler samp[8];
+
+layout (location = 1) in vec2 frag_uv;
+layout (location = 2) in flat int frag_col;
+
+layout (location = 0) out vec4 color;
void main() {
- outColor = vec4(1.0, 0.0, 0.0, 1.0);
+ color = texture(sampler2D(tex[0], samp[0]), frag_uv);
} \ No newline at end of file
diff --git a/stockton-render/src/draw/ui/data/stockton.vert b/stockton-render/src/draw/ui/data/stockton.vert
index 1dd9477..7447fec 100644
--- a/stockton-render/src/draw/ui/data/stockton.vert
+++ b/stockton-render/src/draw/ui/data/stockton.vert
@@ -1,11 +1,26 @@
#version 450
-vec2 positions[3] = vec2[](
- vec2(0.0, -0.5),
- vec2(0.5, 0.5),
- vec2(-0.5, 0.5)
-);
+layout (push_constant) uniform PushConsts {
+ vec2 screen_size;
+} push;
+
+layout(location = 0) in vec2 pos;
+layout (location = 1) in vec2 uv;
+layout (location = 2) in int col; // rgba of u8s
+
+out gl_PerVertex {
+ vec4 gl_Position;
+};
+layout (location = 1) out vec2 frag_uv;
+layout (location = 2) out int frag_col;
void main() {
- gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
+ gl_Position = vec4(
+ ((pos.x / push.screen_size.x) * 2.0) - 1.0,
+ ((pos.y / push.screen_size.y) * 2.0) - 1.0,
+ 0.0,
+ 1.0
+ );
+ frag_uv = uv;
+ frag_col = col;
}
diff --git a/stockton-render/src/draw/ui/mod.rs b/stockton-render/src/draw/ui/mod.rs
index cd19362..bcf5f38 100644
--- a/stockton-render/src/draw/ui/mod.rs
+++ b/stockton-render/src/draw/ui/mod.rs
@@ -15,8 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+use egui::paint::color::Srgba;
+
pub mod pipeline;
pub mod render;
+pub mod texture;
pub use pipeline::UIPipeline;
pub use render::do_render;
+use stockton_types::Vector2;
+pub use texture::ensure_textures;
+
+#[derive(Debug)]
+pub struct UIPoint(pub Vector2, pub Vector2, pub Srgba);
diff --git a/stockton-render/src/draw/ui/pipeline.rs b/stockton-render/src/draw/ui/pipeline.rs
index 378c558..3b643e4 100644
--- a/stockton-render/src/draw/ui/pipeline.rs
+++ b/stockton-render/src/draw/ui/pipeline.rs
@@ -62,7 +62,7 @@ impl UIPipeline {
set_layouts: T,
) -> Result<Self, error::CreationError>
where
- T: IntoIterator,
+ T: IntoIterator + std::fmt::Debug,
T::Item: Borrow<DescriptorSetLayout>,
{
use hal::format::Format;
@@ -125,7 +125,7 @@ impl UIPipeline {
.compile_into_spirv(
VERTEX_SOURCE,
shaderc::ShaderKind::Vertex,
- "vertex.vert",
+ "vertex_ui.vert",
ENTRY_NAME,
None,
)
@@ -135,7 +135,7 @@ impl UIPipeline {
.compile_into_spirv(
FRAGMENT_SOURCE,
shaderc::ShaderKind::Fragment,
- "fragment.frag",
+ "fragment_ui.frag",
ENTRY_NAME,
None,
)
@@ -180,13 +180,14 @@ impl UIPipeline {
// Vertex buffers
let vertex_buffers: Vec<VertexBufferDesc> = vec![VertexBufferDesc {
binding: 0,
- stride: (size_of::<f32>() * 5) as u32,
+ stride: ((size_of::<f32>() * 4) + (size_of::<u8>() * 4)) as u32,
rate: VertexInputRate::Vertex,
}];
let attributes: Vec<AttributeDesc> = pipeline_vb_attributes!(0,
size_of::<f32>() * 2; Rg32Sfloat,
- size_of::<f32>() * 3; Rgb32Sfloat
+ size_of::<f32>() * 2; Rg32Sfloat,
+ size_of::<u8>() * 4; Rgba8Uint
);
// Rasterizer
@@ -207,9 +208,12 @@ impl UIPipeline {
stencil: None,
};
+ log::debug!("ui set layouts: {:?}", set_layouts);
// Pipeline layout
- let layout = unsafe { device.create_pipeline_layout(set_layouts, &[]) }
- .map_err(|_| error::CreationError::OutOfMemoryError)?;
+ let layout = unsafe {
+ device.create_pipeline_layout(set_layouts, &[(ShaderStageFlags::VERTEX, 0..8)])
+ }
+ .map_err(|_| error::CreationError::OutOfMemoryError)?;
// Colour blending
let blender = {
diff --git a/stockton-render/src/draw/ui/render.rs b/stockton-render/src/draw/ui/render.rs
index b965a80..ad23dfb 100644
--- a/stockton-render/src/draw/ui/render.rs
+++ b/stockton-render/src/draw/ui/render.rs
@@ -15,14 +15,65 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+use crate::draw::texture::TextureStore;
+use arrayvec::ArrayVec;
+use egui::Pos2;
use hal::prelude::*;
+use hal::pso::ShaderStageFlags;
+use super::UIPoint;
use crate::draw::draw_buffers::DrawBuffers;
use crate::types::*;
+use crate::UIState;
+use std::convert::TryInto;
+use std::mem::transmute;
+use stockton_types::Vector2;
-pub fn do_render(cmd_buffer: &mut CommandBuffer, _draw_buffers: &mut DrawBuffers) {
+pub fn do_render(
+ cmd_buffer: &mut CommandBuffer,
+ pipeline_layout: &PipelineLayout,
+ draw_buffers: &mut DrawBuffers<UIPoint>,
+ texture_store: &mut TextureStore,
+ ui: &mut UIState,
+) {
// TODO: Actual UI Rendering
+ let (_out, paint) = ui.end_frame();
+ let screen = ui.dimensions();
+
unsafe {
- cmd_buffer.draw(0..3, 0..1);
+ cmd_buffer.push_graphics_constants(
+ &pipeline_layout,
+ ShaderStageFlags::VERTEX,
+ 0,
+ &[transmute(screen.x), transmute(screen.y)],
+ );
+ }
+
+ for (_rect, tris) in paint.iter() {
+ // Copy triangles/indicies
+ for i in (0..tris.indices.len()).step_by(3) {
+ draw_buffers.index_buffer[i / 3] = (
+ tris.indices[i].try_into().unwrap(),
+ tris.indices[i + 1].try_into().unwrap(),
+ tris.indices[i + 2].try_into().unwrap(),
+ );
+ }
+ for (i, vertex) in tris.vertices.iter().enumerate() {
+ draw_buffers.vertex_buffer[i] = UIPoint(
+ Vector2::new(vertex.pos.x, vertex.pos.y),
+ Vector2::new(vertex.uv.x, vertex.uv.y),
+ vertex.color,
+ );
+ }
+
+ // TODO: *Properly* deal with textures
+ let mut descriptor_sets: ArrayVec<[_; 1]> = ArrayVec::new();
+ descriptor_sets.push(texture_store.get_chunk_descriptor_set(0));
+
+ unsafe {
+ cmd_buffer.bind_graphics_descriptor_sets(pipeline_layout, 0, descriptor_sets, &[]);
+ // Call draw
+ cmd_buffer.draw_indexed(0..tris.indices.len() as u32, 0, 0..1);
+ }
}
}
diff --git a/stockton-render/src/draw/ui/texture.rs b/stockton-render/src/draw/ui/texture.rs
new file mode 100755
index 0000000..ce18f02
--- /dev/null
+++ b/stockton-render/src/draw/ui/texture.rs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) Oscar Shrimpton 2020
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+use egui::Texture;
+use crate::types::*;
+use crate::draw::texture::{TextureStore, LoadableImage};
+use crate::UIState;
+
+impl LoadableImage for &Texture {
+ fn width(&self) -> u32 {
+ self.width as u32
+ }
+ fn height(&self) -> u32 {
+ self.height as u32
+ }
+ fn copy_row(&self, y: u32, ptr: *mut u8) -> () {
+ let row_size = self.width();
+ let pixels = &self.pixels[(y * row_size) as usize..((y + 1) * row_size) as usize];
+
+ for (i,x) in pixels.iter().enumerate() {
+ unsafe {
+ *ptr.offset(i as isize * 3) = *x;
+ *ptr.offset((i as isize * 3) + 1) = *x;
+ *ptr.offset((i as isize * 3) + 2) = *x;
+ }
+ }
+ }
+}
+
+pub fn ensure_textures(texture_store: &mut TextureStore, ui: &mut UIState,
+ device: &mut Device,
+ adapter: &mut Adapter,
+ command_queue: &mut CommandQueue,
+ command_pool: &mut CommandPool) {
+ let tex = ui.ctx.texture();
+
+ if tex.version != ui.last_tex_ver {
+ texture_store.put_texture(0, &*tex, device, adapter, command_queue, command_pool).unwrap(); // TODO
+ ui.last_tex_ver = tex.version;
+ }
+} \ No newline at end of file