use hotline_rs::*;
use gfx::CmdBuf;
use gfx::Device;
use gfx::SwapChain;
use os::App;
use os::Window;
use std::fs;
#[cfg(target_os = "windows")]
use os::win32 as os_platform;
use gfx::d3d12 as gfx_platform;
#[repr(C)]
struct Vertex {
position: [f32; 3],
color: [f32; 4],
}
fn main() -> Result<(), hotline_rs::Error> {
let mut app = os_platform::App::create(os::AppInfo {
name: String::from("triangle"),
window: false,
num_buffers: 0,
dpi_aware: true,
});
let num_buffers : u32 = 2;
let mut device = gfx_platform::Device::create(&gfx::DeviceInfo {
render_target_heap_size: num_buffers as usize,
..Default::default()
});
println!("{}", device.get_adapter_info());
let mut window = app.create_window(os::WindowInfo {
title: String::from("triangle!"),
..Default::default()
});
let swap_chain_info = gfx::SwapChainInfo {
num_buffers,
format: gfx::Format::RGBA8n,
clear_colour: Some(gfx::ClearColour {
r: 0.45,
g: 0.55,
b: 0.60,
a: 1.00,
}),
};
let mut swap_chain = device.create_swap_chain::<os_platform::App>(&swap_chain_info, &window)?;
let mut cmd = device.create_cmd_buf(num_buffers);
let vertices = [
Vertex {
position: [0.0, 0.25, 0.0],
color: [1.0, 0.0, 0.0, 1.0],
},
Vertex {
position: [0.25, -0.25, 0.0],
color: [0.0, 1.0, 0.0, 1.0],
},
Vertex {
position: [-0.25, -0.25, 0.0],
color: [0.0, 0.0, 1.0, 1.0],
},
];
let info = gfx::BufferInfo {
usage: gfx::BufferUsage::VERTEX,
cpu_access: gfx::CpuAccessFlags::NONE,
format: gfx::Format::Unknown,
stride: std::mem::size_of::<Vertex>(),
num_elements: 3,
initial_state: gfx::ResourceState::VertexConstantBuffer
};
let vertex_buffer = device.create_buffer(&info, Some(gfx::as_u8_slice(&vertices)))?;
let vsc_filepath = hotline_rs::get_data_path("shaders/triangle/vs_main.vsc");
let psc_filepath = hotline_rs::get_data_path("shaders/triangle/ps_main.psc");
let vsc_data = fs::read(vsc_filepath)?;
let psc_data = fs::read(psc_filepath)?;
let vsc_info = gfx::ShaderInfo {
shader_type: gfx::ShaderType::Vertex,
compile_info: None
};
let vs = device.create_shader(&vsc_info, &vsc_data)?;
let psc_info = gfx::ShaderInfo {
shader_type: gfx::ShaderType::Vertex,
compile_info: None
};
let fs = device.create_shader(&psc_info, &psc_data)?;
let pso = device.create_render_pipeline(&gfx::RenderPipelineInfo {
vs: Some(&vs),
fs: Some(&fs),
input_layout: vec![
gfx::InputElementInfo {
semantic: String::from("POSITION"),
index: 0,
format: gfx::Format::RGB32f,
input_slot: 0,
aligned_byte_offset: 0,
input_slot_class: gfx::InputSlotClass::PerVertex,
step_rate: 0,
},
gfx::InputElementInfo {
semantic: String::from("COLOR"),
index: 0,
format: gfx::Format::RGBA32f,
input_slot: 0,
aligned_byte_offset: 12,
input_slot_class: gfx::InputSlotClass::PerVertex,
step_rate: 0,
},
],
blend_info: gfx::BlendInfo {
alpha_to_coverage_enabled: false,
independent_blend_enabled: false,
render_target: vec![gfx::RenderTargetBlendInfo::default()],
},
topology: gfx::Topology::TriangleList,
pass: Some(swap_chain.get_backbuffer_pass()),
..Default::default()
})?;
while app.run() {
window.update(&mut app);
swap_chain.update::<os_platform::App>(&mut device, &window, &mut cmd);
let window_rect = window.get_viewport_rect();
let viewport = gfx::Viewport::from(window_rect);
let scissor = gfx::ScissorRect::from(window_rect);
cmd.reset(&swap_chain);
cmd.transition_barrier(&gfx::TransitionBarrier {
texture: Some(swap_chain.get_backbuffer_texture()),
buffer: None,
state_before: gfx::ResourceState::Present,
state_after: gfx::ResourceState::RenderTarget,
});
cmd.begin_render_pass(swap_chain.get_backbuffer_pass_mut());
cmd.set_viewport(&viewport);
cmd.set_scissor_rect(&scissor);
cmd.set_render_pipeline(&pso);
cmd.set_vertex_buffer(&vertex_buffer, 0);
cmd.draw_instanced(3, 1, 0, 0);
cmd.end_render_pass();
cmd.transition_barrier(&gfx::TransitionBarrier {
texture: Some(swap_chain.get_backbuffer_texture()),
buffer: None,
state_before: gfx::ResourceState::RenderTarget,
state_after: gfx::ResourceState::Present,
});
cmd.close()?;
device.execute(&cmd);
swap_chain.swap(&device);
}
swap_chain.wait_for_last_frame();
device.cleanup_dropped_resources(&swap_chain);
Ok(())
}