Created
April 3, 2019 08:35
-
-
Save XavilPergis/1f6c2733eabe0ff4c0e4c9dc3cb1487b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use rendy::command::QueueId; | |
use rendy::factory::Config; | |
use rendy::graph::{render::*, NodeBuffer, NodeImage}; | |
use rendy::hal::buffer::Usage; | |
use rendy::memory::MemoryUsageValue; | |
use rendy::mesh::{AsVertex, PosColor}; | |
use rendy::shader::{Shader, ShaderKind, SourceLanguage, StaticShaderInfo}; | |
use winit::{ControlFlow, Event, WindowEvent}; | |
use winit::{EventsLoop, WindowBuilder}; | |
pub mod types { | |
#[cfg(feature = "dx12")] | |
pub type Backend = rendy::dx12::Backend; | |
#[cfg(feature = "metal")] | |
pub type Backend = rendy::metal::Backend; | |
#[cfg(feature = "vulkan")] | |
pub type Backend = rendy::vulkan::Backend; | |
pub type Factory = rendy::factory::Factory<Backend>; | |
pub type Buffer = rendy::resource::buffer::Buffer<Backend>; | |
// pub type DescriptorSetLayout = rendy::descriptor::DescriptorSetLayout<Backend>; | |
pub type DescriptorSetLayout = rendy::resource::set::DescriptorSetLayout<Backend>; | |
pub type GraphContext = rendy::graph::GraphContext<Backend>; | |
pub type GraphBuilder<T> = rendy::graph::GraphBuilder<Backend, T>; | |
pub type Graph<T> = rendy::graph::Graph<Backend, T>; | |
pub type PresentNode = rendy::graph::present::PresentNode<Backend>; | |
pub type PresentBuilder = rendy::graph::present::PresentBuilder<Backend>; | |
pub type RenderPassEncoder<'a> = rendy::command::RenderPassEncoder<'a, Backend>; | |
pub type HalPhysicalDevice = <Backend as rendy::hal::Backend>::PhysicalDevice; | |
pub type HalDevice = <Backend as rendy::hal::Backend>::Device; | |
pub type HalSurface = <Backend as rendy::hal::Backend>::Surface; | |
pub type HalSwapchain = <Backend as rendy::hal::Backend>::Swapchain; | |
pub type HalQueueFamily = <Backend as rendy::hal::Backend>::QueueFamily; | |
pub type HalCommandQueue = <Backend as rendy::hal::Backend>::CommandQueue; | |
pub type HalCommandBuffer = <Backend as rendy::hal::Backend>::CommandBuffer; | |
pub type HalShaderModule = <Backend as rendy::hal::Backend>::ShaderModule; | |
pub type HalRenderPass = <Backend as rendy::hal::Backend>::RenderPass; | |
pub type HalFramebuffer = <Backend as rendy::hal::Backend>::Framebuffer; | |
pub type HalMemory = <Backend as rendy::hal::Backend>::Memory; | |
pub type HalCommandPool = <Backend as rendy::hal::Backend>::CommandPool; | |
pub type HalBuffer = <Backend as rendy::hal::Backend>::Buffer; | |
pub type HalBufferView = <Backend as rendy::hal::Backend>::BufferView; | |
pub type HalImage = <Backend as rendy::hal::Backend>::Image; | |
pub type HalImageView = <Backend as rendy::hal::Backend>::ImageView; | |
pub type HalSampler = <Backend as rendy::hal::Backend>::Sampler; | |
pub type HalComputePipeline = <Backend as rendy::hal::Backend>::ComputePipeline; | |
pub type HalGraphicsPipeline = <Backend as rendy::hal::Backend>::GraphicsPipeline; | |
pub type HalPipelineCache = <Backend as rendy::hal::Backend>::PipelineCache; | |
pub type HalPipelineLayout = <Backend as rendy::hal::Backend>::PipelineLayout; | |
pub type HalDescriptorPool = <Backend as rendy::hal::Backend>::DescriptorPool; | |
pub type HalDescriptorSet = <Backend as rendy::hal::Backend>::DescriptorSet; | |
pub type HalDescriptorSetLayout = <Backend as rendy::hal::Backend>::DescriptorSetLayout; | |
pub type HalFence = <Backend as rendy::hal::Backend>::Fence; | |
pub type HalSemaphore = <Backend as rendy::hal::Backend>::Semaphore; | |
pub type HalQueryPool = <Backend as rendy::hal::Backend>::QueryPool; | |
} | |
use types::*; | |
#[cfg(any(feature = "dx12", feature = "metal", feature = "vulkan"))] | |
fn main() -> Result<(), Box<std::error::Error>> { | |
env_logger::Builder::from_default_env() | |
.filter_level(log::LevelFilter::Warn) | |
.filter_module("init", log::LevelFilter::Trace) | |
.init(); | |
let mut event_loop = EventsLoop::new(); | |
let window = WindowBuilder::new() | |
.with_title("Triangle!") | |
.build(&event_loop)?; | |
let config: Config = Default::default(); | |
let (mut factory, mut families): (Factory, _) = rendy::factory::init(config).unwrap(); | |
let surface = factory.create_surface(window.into()); | |
let mut graph_builder = GraphBuilder::<()>::new(); | |
let color_buffer = graph_builder.create_image( | |
surface.kind(), | |
1, | |
factory.get_surface_format(&surface), | |
MemoryUsageValue::Data, | |
Some(rendy::hal::command::ClearValue::Color( | |
[1.0, 1.0, 1.0, 1.0].into(), | |
)), | |
); | |
let pass = graph_builder.add_node( | |
TriangleRenderPipeline::builder() | |
.into_subpass() | |
.with_color(color_buffer) | |
.into_pass(), | |
); | |
graph_builder | |
.add_node(PresentNode::builder(&factory, surface, color_buffer).with_dependency(pass)); | |
let mut graph = graph_builder | |
.build(&mut factory, &mut families, &()) | |
.unwrap(); | |
let mut do_close = false; | |
while !do_close { | |
factory.maintain(&mut families); | |
event_loop.poll_events(|event| match event { | |
Event::WindowEvent { | |
event: WindowEvent::CloseRequested, | |
.. | |
} => { | |
do_close = true; | |
} | |
_ => (), | |
}); | |
graph.run(&mut factory, &mut families, &()); | |
} | |
Ok(()) | |
} | |
#[cfg(not(any(feature = "dx12", feature = "metal", feature = "vulkan")))] | |
fn main() { | |
panic!("Specify a backend feature: [ vulkan, dx12, metal ]"); | |
} | |
lazy_static::lazy_static! { | |
pub static ref VERTEX: StaticShaderInfo = StaticShaderInfo::new( | |
concat!(env!("CARGO_MANIFEST_DIR"), "/resources/triangle.vert"), | |
ShaderKind::Vertex, | |
SourceLanguage::GLSL, | |
"main", | |
); | |
pub static ref FRAGMENT: StaticShaderInfo = StaticShaderInfo::new( | |
concat!(env!("CARGO_MANIFEST_DIR"), "/resources/triangle.frag"), | |
ShaderKind::Fragment, | |
SourceLanguage::GLSL, | |
"main", | |
); | |
} | |
#[derive(Clone, Debug, Default)] | |
pub struct TriangleRenderPipelineDesc; | |
#[derive(Debug)] | |
pub struct TriangleRenderPipeline { | |
triangle: Buffer, | |
} | |
impl SimpleGraphicsPipelineDesc<Backend, ()> for TriangleRenderPipelineDesc { | |
type Pipeline = TriangleRenderPipeline; | |
fn vertices( | |
&self, | |
) -> Vec<( | |
Vec<rendy::hal::pso::Element<rendy::hal::format::Format>>, | |
rendy::hal::pso::ElemStride, | |
rendy::hal::pso::InstanceRate, | |
)> { | |
vec![PosColor::VERTEX.gfx_vertex_input_desc(0)] | |
} | |
fn depth_stencil(&self) -> Option<rendy::hal::pso::DepthStencilDesc> { | |
None | |
} | |
fn load_shader_set<'a>( | |
&self, | |
storage: &'a mut Vec<HalShaderModule>, | |
factory: &mut Factory, | |
_aux: &(), | |
) -> rendy::hal::pso::GraphicsShaderSet<'a, Backend> { | |
storage.clear(); | |
log::trace!("Load shader module '{:#?}'", *VERTEX); | |
storage.push(VERTEX.module(factory).unwrap()); | |
log::trace!("Load shader module '{:#?}'", *FRAGMENT); | |
storage.push(FRAGMENT.module(factory).unwrap()); | |
rendy::hal::pso::GraphicsShaderSet { | |
vertex: rendy::hal::pso::EntryPoint { | |
entry: "main", | |
module: &storage[0], | |
specialization: rendy::hal::pso::Specialization::default(), | |
}, | |
fragment: Some(rendy::hal::pso::EntryPoint { | |
entry: "main", | |
module: &storage[1], | |
specialization: rendy::hal::pso::Specialization::default(), | |
}), | |
hull: None, | |
domain: None, | |
geometry: None, | |
} | |
} | |
fn build<'a>( | |
self, | |
_ctx: &mut GraphContext, | |
factory: &mut Factory, | |
_queue: QueueId, | |
_aux: &(), | |
buffers: Vec<NodeBuffer>, | |
images: Vec<NodeImage>, | |
set_layouts: &[DescriptorSetLayout], | |
) -> Result<TriangleRenderPipeline, failure::Error> { | |
assert!(buffers.is_empty()); | |
assert!(images.is_empty()); | |
assert!(set_layouts.is_empty()); | |
let mut triangle = factory.create_buffer( | |
512, | |
PosColor::VERTEX.stride as u64 * 3, | |
(Usage::VERTEX, MemoryUsageValue::Dynamic), | |
)?; | |
unsafe { | |
// Fresh buffer. | |
factory | |
.upload_visible_buffer( | |
&mut triangle, | |
0, | |
&[ | |
PosColor { | |
position: [0.0, -0.5, 0.0].into(), | |
color: [1.0, 0.0, 0.0, 1.0].into(), | |
}, | |
PosColor { | |
position: [0.5, 0.5, 0.0].into(), | |
color: [0.0, 1.0, 0.0, 1.0].into(), | |
}, | |
PosColor { | |
position: [-0.5, 0.5, 0.0].into(), | |
color: [0.0, 0.0, 1.0, 1.0].into(), | |
}, | |
], | |
) | |
.unwrap(); | |
} | |
Ok(TriangleRenderPipeline { triangle }) | |
} | |
} | |
impl SimpleGraphicsPipeline<Backend, ()> for TriangleRenderPipeline { | |
type Desc = TriangleRenderPipelineDesc; | |
fn prepare( | |
&mut self, | |
factory: &Factory, | |
_queue: QueueId, | |
_set_layouts: &[DescriptorSetLayout], | |
_index: usize, | |
_aux: &(), | |
) -> PrepareResult { | |
PrepareResult::DrawReuse | |
} | |
fn draw( | |
&mut self, | |
_layout: &HalPipelineLayout, | |
mut encoder: RenderPassEncoder<'_>, | |
_index: usize, | |
_aux: &(), | |
) { | |
encoder.bind_vertex_buffers(0, Some((self.triangle.raw(), 0))); | |
encoder.draw(0..3, 0..1); | |
} | |
fn dispose(self, _factory: &mut Factory, _aux: &()) {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment