From f6c2f402e245c620f8f03dcf3aa6265fca6e8dcf Mon Sep 17 00:00:00 2001 From: tcmal Date: Sun, 25 Aug 2024 17:44:20 +0100 Subject: feat(render): 3D projection --- examples/render-quad/src/main.rs | 77 ++++++---- stockton-render/Cargo.toml | 2 +- stockton-render/src/draw/buffer.rs | 2 +- stockton-render/src/draw/camera.rs | 215 ++++++++++++++++++++++++++++ stockton-render/src/draw/context.rs | 68 +++++---- stockton-render/src/draw/data/stockton.frag | 17 +-- stockton-render/src/draw/data/stockton.vert | 22 +-- stockton-render/src/draw/mod.rs | 1 + stockton-render/src/lib.rs | 1 + stockton-types/Cargo.toml | 2 +- stockton-types/src/lib.rs | 5 +- 11 files changed, 331 insertions(+), 81 deletions(-) create mode 100644 stockton-render/src/draw/camera.rs diff --git a/examples/render-quad/src/main.rs b/examples/render-quad/src/main.rs index 8d6d439..130bc5e 100644 --- a/examples/render-quad/src/main.rs +++ b/examples/render-quad/src/main.rs @@ -34,6 +34,46 @@ use winit::{ }; fn main() { + let cube_points: [UVPoint; 24] = [ + // Face 1 (front) + UVPoint(Vector3::new(0.0, 0.0, 0.0), Vector2::new(0.0, 1.0), 0), /* bottom left */ + UVPoint(Vector3::new(0.0, 1.0, 0.0), Vector2::new(0.0, 0.0), 0), /* top left */ + UVPoint(Vector3::new(1.0, 0.0, 0.0), Vector2::new(1.0, 1.0), 0), /* bottom right */ + UVPoint(Vector3::new(1.0, 1.0, 0.0), Vector2::new(1.0, 0.0), 0), /* top right */ + // Face 2 (top) + UVPoint(Vector3::new(0.0, 1.0, 0.0), Vector2::new(0.0, 1.0), 0), /* bottom left */ + UVPoint(Vector3::new(0.0, 1.0, 1.0), Vector2::new(0.0, 0.0), 0), /* top left */ + UVPoint(Vector3::new(1.0, 1.0, 0.0), Vector2::new(1.0, 1.0), 0), /* bottom right */ + UVPoint(Vector3::new(1.0, 1.0, 1.0), Vector2::new(1.0, 0.0), 0), /* top right */ + // Face 3 (back) + UVPoint(Vector3::new(0.0, 0.0, 1.0), Vector2::new(0.0, 1.0), 1), /* bottom left */ + UVPoint(Vector3::new(0.0, 1.0, 1.0), Vector2::new(0.0, 0.0), 1), /* top left */ + UVPoint(Vector3::new(1.0, 0.0, 1.0), Vector2::new(1.0, 1.0), 1), /* bottom right */ + UVPoint(Vector3::new(1.0, 1.0, 1.0), Vector2::new(1.0, 0.0), 1), /* top right */ + // Face 4 (bottom) + UVPoint(Vector3::new(0.0, 0.0, 0.0), Vector2::new(0.0, 1.0), 1), /* bottom left */ + UVPoint(Vector3::new(0.0, 0.0, 1.0), Vector2::new(0.0, 0.0), 1), /* top left */ + UVPoint(Vector3::new(1.0, 0.0, 0.0), Vector2::new(1.0, 1.0), 1), /* bottom right */ + UVPoint(Vector3::new(1.0, 0.0, 1.0), Vector2::new(1.0, 0.0), 1), /* top right */ + // Face 5 (left) + UVPoint(Vector3::new(0.0, 0.0, 1.0), Vector2::new(0.0, 1.0), 1), /* bottom left */ + UVPoint(Vector3::new(0.0, 1.0, 1.0), Vector2::new(0.0, 0.0), 1), /* top left */ + UVPoint(Vector3::new(0.0, 0.0, 0.0), Vector2::new(1.0, 1.0), 1), /* bottom right */ + UVPoint(Vector3::new(0.0, 1.0, 0.0), Vector2::new(1.0, 0.0), 1), /* top right */ + // Face 6 (right) + UVPoint(Vector3::new(1.0, 0.0, 0.0), Vector2::new(0.0, 1.0), 0), /* bottom left */ + UVPoint(Vector3::new(1.0, 1.0, 0.0), Vector2::new(0.0, 0.0), 0), /* top left */ + UVPoint(Vector3::new(1.0, 0.0, 1.0), Vector2::new(1.0, 1.0), 0), /* bottom right */ + UVPoint(Vector3::new(1.0, 1.0, 1.0), Vector2::new(1.0, 0.0), 0), /* top right */ + ]; + let cube_indices: [(u16, u16, u16); 12] = [ + (0, 1, 2), (2, 1, 3), // front + (4, 5, 6), (7, 6, 5), // top + (10, 9, 8), (9, 10, 11), // back + (12, 14, 13), (15, 13, 14), // bottom + (16, 17, 18), (19, 18, 17), // left + (20, 21, 22), (23, 22, 21), // right + ]; simple_logger::init().unwrap(); @@ -55,22 +95,13 @@ fn main() { .unwrap(); // First quad with test1 - ctx.vert_buffer[0] = UVPoint(Vector2::new(-1.0, -1.0), Vector3::new(1.0, 0.0, 0.0), Vector2::new(0.0, 0.0), 0); - ctx.vert_buffer[1] = UVPoint(Vector2::new(0.0, -1.0), Vector3::new(0.0, 1.0, 0.0), Vector2::new(1.0, 0.0), 0); - ctx.vert_buffer[2] = UVPoint(Vector2::new(0.0, 0.0), Vector3::new(0.0, 0.0, 1.0), Vector2::new(1.0, 1.0), 0); - ctx.vert_buffer[3] = UVPoint(Vector2::new(-1.0, 0.0), Vector3::new(1.0, 0.0, 1.0), Vector2::new(0.0, 1.0), 0); + for (index, point) in cube_points.iter().enumerate() { + ctx.vert_buffer[index] = *point; + } - ctx.index_buffer[0] = (0, 1, 2); - ctx.index_buffer[1] = (0, 2, 3); - - // Second quad with test2 - ctx.vert_buffer[4] = UVPoint(Vector2::new(0.0, -1.0), Vector3::new(1.0, 0.0, 0.0), Vector2::new(0.0, 0.0), 1); - ctx.vert_buffer[5] = UVPoint(Vector2::new(1.0, -1.0), Vector3::new(0.0, 1.0, 0.0), Vector2::new(1.0, 0.0), 1); - ctx.vert_buffer[6] = UVPoint(Vector2::new(1.0, 0.0), Vector3::new(0.0, 0.0, 1.0), Vector2::new(1.0, 1.0), 1); - ctx.vert_buffer[7] = UVPoint(Vector2::new(0.0, 0.0), Vector3::new(1.0, 0.0, 1.0), Vector2::new(0.0, 1.0), 1); - - ctx.index_buffer[2] = (4, 5, 6); - ctx.index_buffer[3] = (4, 7, 6); + for (index, value) in cube_indices.iter().enumerate() { + ctx.index_buffer[index] = *value; + } event_loop.run(move |event, _, flow| { *flow = ControlFlow::Poll; @@ -84,22 +115,6 @@ fn main() { *flow = ControlFlow::Exit }, - Event::WindowEvent { - event: WindowEvent::CursorMoved { - position, - .. - }, - .. - } => { - let win_size = window.inner_size(); - let mouse_x: f32 = ((position.x / win_size.width as f64) * 2.0 - 1.0) as f32; - let mouse_y: f32 = ((position.y / win_size.height as f64) * 2.0 - 1.0) as f32; - - // Move a vertex from each quad - ctx.vert_buffer[2] = UVPoint(Vector2::new(mouse_x, mouse_y), Vector3::new(1.0, 0.0, 0.0), Vector2::new(1.0, 1.0), 0); - ctx.vert_buffer[7] = UVPoint(Vector2::new(mouse_x, mouse_y), Vector3::new(1.0, 0.0, 0.0), Vector2::new(0.0, 1.0), 1); - } - Event::MainEventsCleared => { window.request_redraw() }, diff --git a/stockton-render/Cargo.toml b/stockton-render/Cargo.toml index ba186cd..e6e529c 100644 --- a/stockton-render/Cargo.toml +++ b/stockton-render/Cargo.toml @@ -8,7 +8,7 @@ stockton-types = { path = "../stockton-types" } winit = "^0.21" gfx-hal = "^0.5" arrayvec = "0.4.10" -nalgebra-glm = "0.4.0" +nalgebra-glm = "^0.6" shaderc = "0.6.1" log = "0.4.0" image = "0.23.2" diff --git a/stockton-render/src/draw/buffer.rs b/stockton-render/src/draw/buffer.rs index 7bbd7e3..f59431e 100644 --- a/stockton-render/src/draw/buffer.rs +++ b/stockton-render/src/draw/buffer.rs @@ -86,7 +86,7 @@ impl<'a, T: Sized> StagedBuffer<'a, T> { // Map it somewhere and get a slice to that memory let staged_mapped_memory = unsafe { - let ptr = device.map_memory(&staged_memory, Segment::ALL).unwrap(); + let ptr = device.map_memory(&staged_memory, Segment::ALL).unwrap(); // TODO std::slice::from_raw_parts_mut(ptr as *mut T, size.try_into().unwrap()) }; diff --git a/stockton-render/src/draw/camera.rs b/stockton-render/src/draw/camera.rs new file mode 100644 index 0000000..2cba57e --- /dev/null +++ b/stockton-render/src/draw/camera.rs @@ -0,0 +1,215 @@ +// Copyright (C) 2019 Oscar Shrimpton + +// 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 . + +//! Things related to converting 3D world space to 2D screen space + +use std::iter::once; +use hal::prelude::*; +use hal::buffer::Usage; +use na::{look_at_lh, perspective_lh_zo}; + +use core::mem::ManuallyDrop; + +use crate::error; +use crate::types::*; +use super::buffer::{StagedBuffer, ModifiableBuffer}; +use stockton_types::{Vector3, Matrix4}; + +/// Holds settings related to the projection of world space to screen space +/// Also holds maths for generating important matrices +pub struct Camera<'a> { + position: Vector3, + looking_at: Vector3, + up: Vector3, + + /// Aspect ratio as a fraction + aspect_ratio: f32, + + /// FOV in radians + fov: f32, + + /// Near clipping plane (world units) + near: f32, + + /// Far clipping plane (world units) + far: f32, + + /// Layout of the descriptor set to pass to the shader + pub descriptor_set_layout: ManuallyDrop, + + /// Buffer of memory used for passing data to shaders + // TODO: Does this need to be staged? + buffer: ManuallyDrop>, + + // TODO: Share descriptor pool with textures? + descriptor_pool: ManuallyDrop, + descriptor_set: DescriptorSet, + + /// If true, buffer needs updated + is_dirty: bool +} + +impl<'a> Camera<'a> { + /// Return a camera with default settings + // TODO + pub fn defaults(aspect_ratio: f32, device: &mut Device, adapter: &Adapter, + command_queue: &mut CommandQueue, + command_pool: &mut CommandPool) -> Result, error::CreationError> { + + let descriptor_type = { + use hal::pso::{DescriptorType, BufferDescriptorType, BufferDescriptorFormat}; + + DescriptorType::Buffer { + ty: BufferDescriptorType::Uniform, + format: BufferDescriptorFormat::Structured { + dynamic_offset: false + } + } + }; + + // Create set layout + let descriptor_set_layout = unsafe { + use hal::pso::{DescriptorSetLayoutBinding, ShaderStageFlags}; + + device.create_descriptor_set_layout( + &[ + DescriptorSetLayoutBinding { + binding: 0, + ty: descriptor_type, + count: 1, + stage_flags: ShaderStageFlags::VERTEX, + immutable_samplers: false + } + ], + &[], + ) + }.map_err(|_| error::CreationError::OutOfMemoryError)?; + + // Create pool and allocate set + let (descriptor_pool, descriptor_set) = unsafe { + use hal::pso::{DescriptorRangeDesc, DescriptorPoolCreateFlags}; + + let mut pool = device.create_descriptor_pool( + 1, + &[ + DescriptorRangeDesc { + ty: descriptor_type, + count: 1 + } + ], + DescriptorPoolCreateFlags::empty() + ).map_err(|_| error::CreationError::OutOfMemoryError)?; + + let set = pool.allocate_set(&descriptor_set_layout).map_err(|_| error::CreationError::OutOfMemoryError)?; + + (pool, set) + }; + + // Create buffer for descriptor + let mut buffer = StagedBuffer::new(device, adapter, Usage::UNIFORM, 1)?; + + // Bind our buffer to our descriptor set + unsafe { + use hal::pso::{Descriptor, DescriptorSetWrite}; + use hal::buffer::SubRange; + + device.write_descriptor_sets(once( + DescriptorSetWrite { + set: &descriptor_set, + binding: 0, + array_offset: 0, + descriptors: once( + Descriptor::Buffer(buffer.commit(device, command_queue, command_pool), SubRange::WHOLE) + ) + } + )); + } + + Ok(Camera { + position: Vector3::new(-0.5, 1.5, -1.0), + looking_at: Vector3::new(0.5, 0.5, 0.5), + up: Vector3::new(0.0, 1.0, 0.0), + + aspect_ratio, + fov: f32::to_radians(90.0), + near: 0.1, + far: 100.0, + + descriptor_set_layout: ManuallyDrop::new(descriptor_set_layout), + buffer: ManuallyDrop::new(buffer), + + descriptor_pool: ManuallyDrop::new(descriptor_pool), + descriptor_set: descriptor_set, + + is_dirty: true + }) + } + + /// Returns a matrix that transforms from world space to screen space + pub fn vp_matrix(&self) -> Matrix4 { + // Converts world space to camera space + let view_matrix = look_at_lh( + &self.position, + &self.looking_at, + &self.up + ); + + // Converts camera space to screen space + let projection_matrix = { + let mut temp = perspective_lh_zo( + self.aspect_ratio, + self.fov, + self.near, + self.far + ); + + // Vulkan's co-ord system is different from openGLs + temp[(1, 1)] *= -1.0; + + temp + }; + + // Chain them together into a single matrix + projection_matrix * view_matrix + } + + pub fn commit<'b>(&'b mut self, device: &Device, + command_queue: &mut CommandQueue, + command_pool: &mut CommandPool) -> &'b DescriptorSet { + // Update buffer if needed + if self.is_dirty { + self.buffer[0] = self.vp_matrix(); + self.buffer.commit(device, command_queue, command_pool); + + self.is_dirty = false; + } + + // Return the descriptor set for matrices + &self.descriptor_set + } + + /// This should be called before dropping + pub fn deactivate(mut self, device: &mut Device) -> () { + unsafe { + use core::ptr::read; + + ManuallyDrop::into_inner(read(&self.buffer)).deactivate(device); + + self.descriptor_pool.reset(); + device.destroy_descriptor_pool(ManuallyDrop::into_inner(read(&self.descriptor_pool))); + device.destroy_descriptor_set_layout(ManuallyDrop::into_inner(read(&self.descriptor_set_layout))); + } + } +} \ No newline at end of file diff --git a/stockton-render/src/draw/context.rs b/stockton-render/src/draw/context.rs index c179f9d..061d22c 100644 --- a/stockton-render/src/draw/context.rs +++ b/stockton-render/src/draw/context.rs @@ -19,8 +19,8 @@ use std::{ mem::{ManuallyDrop, size_of}, - iter::once, - ops::Deref + ops::Deref, + borrow::Borrow }; use winit::window::Window; use arrayvec::ArrayVec; @@ -35,6 +35,7 @@ use stockton_types::{Vector2, Vector3}; use crate::types::*; use crate::error; +use super::camera::Camera; use super::texture::TextureStore; use super::buffer::{StagedBuffer, ModifiableBuffer}; @@ -63,9 +64,9 @@ const VERTEX_SOURCE: &str = include_str!("./data/stockton.vert"); /// Source for fragment shader. TODO const FRAGMENT_SOURCE: &str = include_str!("./data/stockton.frag"); -/// Represents a point of a vertices, including RGB, UV and texture information. +/// Represents a point of a triangle, including UV and texture information. #[derive(Debug, Clone, Copy)] -pub struct UVPoint (pub Vector2, pub Vector3, pub Vector2, pub i32); +pub struct UVPoint (pub Vector3, pub Vector2, pub i32); /// Contains all the hal related stuff. /// In the end, this takes some 3D points and puts it on the screen. @@ -109,6 +110,8 @@ pub struct RenderingContext<'a> { // These are both staged pub vert_buffer: ManuallyDrop>, pub index_buffer: ManuallyDrop>, + + camera: ManuallyDrop> } impl<'a> RenderingContext<'a> { @@ -129,7 +132,7 @@ impl<'a> RenderingContext<'a> { let adapter = adapters.remove(0); // Device & Queue group - let (mut device, queue_group) = { + let (mut device, mut queue_group) = { let family = adapter .queue_families .iter() @@ -283,12 +286,12 @@ impl<'a> RenderingContext<'a> { // Command Pool, Buffers, imageviews, framebuffers & Sync objects let frames_in_flight = backbuffer.len(); - let (cmd_pool, cmd_buffers, get_image, render_complete, present_complete, imageviews, framebuffers) = { + let (mut cmd_pool, cmd_buffers, get_image, render_complete, present_complete, imageviews, framebuffers) = { use hal::pool::CommandPoolCreateFlags; use hal::command::Level; let mut cmd_pool = ManuallyDrop::new(unsafe { - device.create_command_pool(queue_group.family, CommandPoolCreateFlags::empty()) + device.create_command_pool(queue_group.family, CommandPoolCreateFlags::RESET_INDIVIDUAL) }.map_err(|_| error::CreationError::OutOfMemoryError)?); let mut cmd_buffers = Vec::with_capacity(frames_in_flight); @@ -332,8 +335,17 @@ impl<'a> RenderingContext<'a> { // Texture store let texture_store = TextureStore::new(&mut device, INITIAL_TEX_SIZE)?; + // Camera + // TODO: Settings + let ratio = extent.width as f32 / extent.height as f32; + let camera = Camera::defaults(ratio, &mut device, &adapter, &mut queue_group.queues[0], &mut cmd_pool)?; + + let mut descriptor_set_layouts: ArrayVec<[_; 2]> = ArrayVec::new(); + descriptor_set_layouts.push(camera.descriptor_set_layout.deref()); + descriptor_set_layouts.push(texture_store.descriptor_set_layout.deref()); + // Graphics pipeline - let (pipeline_layout, pipeline) = Self::create_pipeline(&mut device, extent, &subpass, &texture_store.descriptor_set_layout)?; + let (pipeline_layout, pipeline) = Self::create_pipeline(&mut device, extent, &subpass, descriptor_set_layouts)?; Ok(RenderingContext { instance: ManuallyDrop::new(instance), @@ -365,6 +377,8 @@ impl<'a> RenderingContext<'a> { vert_buffer: ManuallyDrop::new(vert_buffer), index_buffer: ManuallyDrop::new(index_buffer), + + camera: ManuallyDrop::new(camera) }) } @@ -378,11 +392,11 @@ impl<'a> RenderingContext<'a> { } #[allow(clippy::type_complexity)] - pub fn create_pipeline(device: &mut Device, extent: hal::image::Extent, subpass: &hal::pass::Subpass, set_layout: &DescriptorSetLayout) -> Result< + pub fn create_pipeline(device: &mut Device, extent: hal::image::Extent, subpass: &hal::pass::Subpass, set_layouts: T) -> Result< ( PipelineLayout, GraphicsPipeline, - ), error::CreationError> { + ), error::CreationError> where T: IntoIterator, T::Item: Borrow { use hal::pso::*; use hal::format::Format; @@ -435,44 +449,37 @@ impl<'a> RenderingContext<'a> { // Vertex buffers let vertex_buffers: Vec = vec![VertexBufferDesc { binding: 0, - stride: (size_of::() * 8) as u32, + stride: (size_of::() * 6) as u32, rate: VertexInputRate::Vertex, }]; - let attributes: Vec = vec![AttributeDesc { // XY Attribute + let attributes: Vec = vec![AttributeDesc { // XYZ Attribute location: 0, binding: 0, element: Element { - format: Format::Rg32Sfloat, + format: Format::Rgb32Sfloat, offset: 0, }, - }, AttributeDesc { // RGB Attribute - location: 1, - binding: 0, - element: Element { - format: Format::Rgb32Sfloat, - offset: (size_of::() * 2) as ElemOffset, - } }, AttributeDesc { // UV Attribute - location: 2, + location: 1, binding: 0, element: Element { format: Format::Rg32Sfloat, - offset: (size_of::() * 5) as ElemOffset, + offset: (size_of::() * 3) as ElemOffset, } }, AttributeDesc { // Tex Attribute - location: 3, + location: 2, binding: 0, element: Element { format: Format::R32Sint, - offset: (size_of::() * 7) as ElemOffset + offset: (size_of::() * 5) as ElemOffset } }]; // Rasterizer let rasterizer = Rasterizer { polygon_mode: PolygonMode::Fill, - cull_face: Face::NONE, + cull_face: Face::BACK, front_face: FrontFace::Clockwise, depth_clamping: false, depth_bias: None, @@ -489,7 +496,7 @@ impl<'a> RenderingContext<'a> { // Pipeline layout let layout = unsafe { - device.create_pipeline_layout(once(set_layout), &[]) + device.create_pipeline_layout(set_layouts, &[]) }.map_err(|_| error::CreationError::OutOfMemoryError)?; // Colour blending @@ -694,10 +701,16 @@ impl<'a> RenderingContext<'a> { ); buffer.bind_graphics_pipeline(&self.pipeline); + let mut descriptor_sets: ArrayVec<[_; 2]> = ArrayVec::new(); + descriptor_sets.push(self.camera.commit(&self.device, + &mut self.queue_group.queues[0], + &mut self.cmd_pool)); + descriptor_sets.push(&self.texture_store.descriptor_set); + buffer.bind_graphics_descriptor_sets( &self.pipeline_layout, 0, - once(self.texture_store.descriptor_set.deref()), + descriptor_sets, &[] ); @@ -765,6 +778,7 @@ impl<'a> core::ops::Drop for RenderingContext<'a> { ManuallyDrop::into_inner(read(&self.vert_buffer)).deactivate(&mut self.device); ManuallyDrop::into_inner(read(&self.index_buffer)).deactivate(&mut self.device); ManuallyDrop::into_inner(read(&self.texture_store)).deactivate(&mut self.device); + ManuallyDrop::into_inner(read(&self.camera)).deactivate(&mut self.device); self.device.destroy_command_pool( ManuallyDrop::into_inner(read(&self.cmd_pool)), diff --git a/stockton-render/src/draw/data/stockton.frag b/stockton-render/src/draw/data/stockton.frag index 09ff8a7..b558335 100644 --- a/stockton-render/src/draw/data/stockton.frag +++ b/stockton-render/src/draw/data/stockton.frag @@ -1,19 +1,16 @@ #version 450 -layout(set = 0, binding = 0) uniform texture2D tex[2]; -layout(set = 0, binding = 1) uniform sampler samp[2]; +// DescriptorSet 0 = Matrices +// DescriptorSet 1 = Textures +layout(set = 1, binding = 0) uniform texture2D tex[2]; +layout(set = 1, binding = 1) uniform sampler samp[2]; -layout (location = 1) in vec3 frag_color; -layout (location = 2) in vec2 frag_uv; -layout (location = 3) in flat int frag_tex; +layout (location = 1) in vec2 frag_uv; +layout (location = 2) in flat int frag_tex; layout (location = 0) out vec4 color; void main() { - if(frag_tex == -1) { - color = vec4(frag_color, 1.0); - } else { - color = texture(sampler2D(tex[frag_tex], samp[frag_tex]), frag_uv); - } + color = texture(sampler2D(tex[frag_tex], samp[frag_tex]), frag_uv); } \ No newline at end of file diff --git a/stockton-render/src/draw/data/stockton.vert b/stockton-render/src/draw/data/stockton.vert index f40d0b8..d3f4438 100644 --- a/stockton-render/src/draw/data/stockton.vert +++ b/stockton-render/src/draw/data/stockton.vert @@ -1,21 +1,25 @@ #version 450 -layout (location = 0) in vec2 position; -layout (location = 1) in vec3 colour; -layout (location = 2) in vec2 uv; -layout (location = 3) in int tex; +// DescriptorSet 0 = Matrices +layout (binding = 0) uniform UniformBufferObject { + mat4 vp; +} matrices; + +// DescriptorSet 1 = Textures/Samplers + +layout (location = 0) in vec3 position; +layout (location = 1) in vec2 uv; +layout (location = 2) in int tex; out gl_PerVertex { vec4 gl_Position; }; -layout (location = 1) out vec3 frag_colour; -layout (location = 2) out vec2 frag_uv; -layout (location = 3) out flat int frag_tex; +layout (location = 1) out vec2 frag_uv; +layout (location = 2) out flat int frag_tex; void main() { - gl_Position = vec4(position, 0.0, 1.0); - frag_colour = colour; + gl_Position = matrices.vp * vec4(position, 1.0); frag_uv = uv; frag_tex = tex; } \ No newline at end of file diff --git a/stockton-render/src/draw/mod.rs b/stockton-render/src/draw/mod.rs index a1a5780..00b5bb6 100644 --- a/stockton-render/src/draw/mod.rs +++ b/stockton-render/src/draw/mod.rs @@ -18,6 +18,7 @@ mod context; mod buffer; mod texture; +mod camera; pub use self::context::RenderingContext; pub use self::context::UVPoint; diff --git a/stockton-render/src/lib.rs b/stockton-render/src/lib.rs index 7f6dc1c..43c5d6a 100644 --- a/stockton-render/src/lib.rs +++ b/stockton-render/src/lib.rs @@ -24,6 +24,7 @@ extern crate gfx_hal as hal; extern crate stockton_types; extern crate shaderc; extern crate winit; +extern crate nalgebra_glm as na; extern crate arrayvec; diff --git a/stockton-types/Cargo.toml b/stockton-types/Cargo.toml index 73cfd8a..9c685e8 100644 --- a/stockton-types/Cargo.toml +++ b/stockton-types/Cargo.toml @@ -5,6 +5,6 @@ authors = ["Oscar "] edition = "2018" [dependencies] -nalgebra-glm = "0.4.0" +nalgebra-glm = "^0.6" stockton-bsp = "2.0.0" downcast-rs = "1.0.4" \ No newline at end of file diff --git a/stockton-types/src/lib.rs b/stockton-types/src/lib.rs index e6a816e..7cc5ac0 100644 --- a/stockton-types/src/lib.rs +++ b/stockton-types/src/lib.rs @@ -36,4 +36,7 @@ pub type Vector3 = na::Vec3; pub type Vector2i = na::IVec2; /// Alias for convenience -pub type Vector3i = na::IVec3; \ No newline at end of file +pub type Vector3i = na::IVec3; + +/// Alias for convenience +pub type Matrix4 = na::Mat4x4; \ No newline at end of file -- cgit v1.2.3