2023-01-13 13:29:42 +11:00
|
|
|
const WIDTH: i32 = 800;
|
|
|
|
const HEIGHT: i32 = 600;
|
2022-11-22 17:56:39 +11:00
|
|
|
const TITLE: &str = "librashader DirectX 11";
|
|
|
|
|
2023-02-16 16:39:36 +11:00
|
|
|
mod texture;
|
|
|
|
|
2022-11-22 17:56:39 +11:00
|
|
|
use windows::{
|
|
|
|
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
|
|
|
|
Win32::Graphics::Direct3D11::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
|
2022-11-30 17:38:05 +11:00
|
|
|
Win32::System::LibraryLoader::*, Win32::UI::WindowsAndMessaging::*,
|
2022-11-22 17:56:39 +11:00
|
|
|
};
|
|
|
|
|
2022-11-30 17:38:05 +11:00
|
|
|
static VERTEX_SHADER: &[u8] = b"
|
2022-11-22 17:56:39 +11:00
|
|
|
cbuffer cb : register(b0)
|
|
|
|
{
|
|
|
|
row_major float4x4 projectionMatrix : packoffset(c0);
|
|
|
|
row_major float4x4 modelMatrix : packoffset(c4);
|
|
|
|
row_major float4x4 viewMatrix : packoffset(c8);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct VertexInput
|
|
|
|
{
|
|
|
|
float3 inPos : POSITION;
|
|
|
|
float3 inColor : COLOR;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct VertexOutput
|
|
|
|
{
|
|
|
|
float3 color : COLOR;
|
|
|
|
float4 position : SV_Position;
|
|
|
|
};
|
|
|
|
|
|
|
|
VertexOutput main(VertexInput vertexInput)
|
|
|
|
{
|
|
|
|
float3 inColor = vertexInput.inColor;
|
|
|
|
float3 inPos = vertexInput.inPos;
|
|
|
|
float3 outColor = inColor;
|
|
|
|
float4 position = mul(float4(inPos, 1.0), mul(modelMatrix, mul(viewMatrix, projectionMatrix)));
|
|
|
|
|
|
|
|
VertexOutput output;
|
|
|
|
output.position = position;
|
|
|
|
output.color = outColor;
|
|
|
|
return output;
|
|
|
|
}\0";
|
|
|
|
|
2022-11-30 17:38:05 +11:00
|
|
|
static PIXEL_SHADER: &[u8] = b"
|
2022-11-22 17:56:39 +11:00
|
|
|
struct PixelInput
|
|
|
|
{
|
|
|
|
float3 color : COLOR;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PixelOutput
|
|
|
|
{
|
|
|
|
float4 attachment0 : SV_Target0;
|
|
|
|
};
|
|
|
|
|
|
|
|
PixelOutput main(PixelInput pixelInput)
|
|
|
|
{
|
|
|
|
float3 inColor = pixelInput.color;
|
|
|
|
PixelOutput output;
|
|
|
|
output.attachment0 = float4(inColor, 1.0f);
|
|
|
|
return output;
|
|
|
|
}\0";
|
|
|
|
|
|
|
|
use gfx_maths::Mat4;
|
2022-11-26 18:38:15 +11:00
|
|
|
use std::mem::transmute;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
pub trait DXSample {
|
2022-11-22 17:56:39 +11:00
|
|
|
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()>;
|
|
|
|
|
|
|
|
fn update(&mut self) {}
|
2022-11-26 18:38:15 +11:00
|
|
|
fn render(&mut self) -> Result<()> {
|
|
|
|
Ok(())
|
|
|
|
}
|
2022-11-22 17:56:39 +11:00
|
|
|
fn on_key_up(&mut self, _key: u8) {}
|
|
|
|
fn on_key_down(&mut self, _key: u8) {}
|
|
|
|
|
|
|
|
fn title(&self) -> String {
|
|
|
|
TITLE.into()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn window_size(&self) -> (i32, i32) {
|
|
|
|
(WIDTH, HEIGHT)
|
|
|
|
}
|
2023-01-30 11:04:34 +11:00
|
|
|
fn resize(&mut self, w: u32, h: u32) -> Result<()>;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2023-02-10 13:03:55 +11:00
|
|
|
pub fn loword(l: usize) -> u32 {
|
2023-01-30 11:04:34 +11:00
|
|
|
(l & 0xffff) as u32
|
|
|
|
}
|
|
|
|
#[inline]
|
2023-02-10 13:03:55 +11:00
|
|
|
pub fn hiword(l: usize) -> u32 {
|
2023-01-30 11:04:34 +11:00
|
|
|
((l >> 16) & 0xffff) as u32
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
fn run_sample<S>(mut sample: S) -> Result<()>
|
|
|
|
where
|
|
|
|
S: DXSample,
|
2022-11-22 17:56:39 +11:00
|
|
|
{
|
|
|
|
let instance = unsafe { GetModuleHandleA(None)? };
|
|
|
|
|
|
|
|
let wc = WNDCLASSEXA {
|
|
|
|
cbSize: std::mem::size_of::<WNDCLASSEXA>() as u32,
|
|
|
|
style: CS_HREDRAW | CS_VREDRAW,
|
|
|
|
lpfnWndProc: Some(wndproc::<S>),
|
|
|
|
hInstance: instance,
|
|
|
|
hCursor: unsafe { LoadCursorW(None, IDC_ARROW)? },
|
|
|
|
lpszClassName: s!("RustWindowClass"),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
|
|
|
|
let size = sample.window_size();
|
|
|
|
|
|
|
|
let atom = unsafe { RegisterClassExA(&wc) };
|
|
|
|
debug_assert_ne!(atom, 0);
|
|
|
|
|
|
|
|
let mut window_rect = RECT {
|
|
|
|
left: 0,
|
|
|
|
top: 0,
|
|
|
|
right: size.0,
|
|
|
|
bottom: size.1,
|
|
|
|
};
|
|
|
|
unsafe { AdjustWindowRect(&mut window_rect, WS_OVERLAPPEDWINDOW, false) };
|
|
|
|
|
|
|
|
let mut title = sample.title();
|
|
|
|
|
|
|
|
title.push('\0');
|
|
|
|
|
|
|
|
let hwnd = unsafe {
|
|
|
|
CreateWindowExA(
|
|
|
|
WINDOW_EX_STYLE::default(),
|
|
|
|
s!("RustWindowClass"),
|
|
|
|
PCSTR(title.as_ptr()),
|
|
|
|
WS_OVERLAPPEDWINDOW,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
window_rect.right - window_rect.left,
|
|
|
|
window_rect.bottom - window_rect.top,
|
|
|
|
None, // no parent window
|
|
|
|
None, // no menus
|
|
|
|
instance,
|
2023-01-13 15:02:38 +11:00
|
|
|
Some(&sample as *const _ as _),
|
2022-11-22 17:56:39 +11:00
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2023-01-13 15:02:38 +11:00
|
|
|
sample.bind_to_window(&hwnd).unwrap();
|
2022-11-22 17:56:39 +11:00
|
|
|
unsafe { ShowWindow(hwnd, SW_SHOW) };
|
|
|
|
|
|
|
|
loop {
|
|
|
|
let mut message = MSG::default();
|
|
|
|
|
|
|
|
if unsafe { PeekMessageA(&mut message, None, 0, 0, PM_REMOVE) }.into() {
|
|
|
|
unsafe {
|
|
|
|
TranslateMessage(&message);
|
|
|
|
DispatchMessageA(&message);
|
|
|
|
}
|
|
|
|
|
|
|
|
if message.message == WM_QUIT {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sample_wndproc<S: DXSample>(sample: &mut S, message: u32, wparam: WPARAM) -> bool {
|
|
|
|
match message {
|
|
|
|
WM_KEYDOWN => {
|
|
|
|
sample.on_key_down(wparam.0 as u8);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
WM_KEYUP => {
|
|
|
|
sample.on_key_up(wparam.0 as u8);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
WM_PAINT => {
|
|
|
|
sample.update();
|
|
|
|
sample.render().unwrap();
|
|
|
|
true
|
|
|
|
}
|
2023-01-30 11:04:34 +11:00
|
|
|
WM_SIZE => {
|
2023-02-10 13:03:55 +11:00
|
|
|
sample.resize(loword(wparam.0), hiword(wparam.0)).unwrap();
|
2023-01-30 13:26:34 +11:00
|
|
|
true
|
|
|
|
}
|
2022-11-22 17:56:39 +11:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "system" fn wndproc<S: DXSample>(
|
|
|
|
window: HWND,
|
|
|
|
message: u32,
|
|
|
|
wparam: WPARAM,
|
|
|
|
lparam: LPARAM,
|
|
|
|
) -> LRESULT {
|
|
|
|
match message {
|
|
|
|
WM_CREATE => {
|
|
|
|
unsafe {
|
|
|
|
let create_struct: &CREATESTRUCTA = transmute(lparam);
|
|
|
|
SetWindowLongPtrA(window, GWLP_USERDATA, create_struct.lpCreateParams as _);
|
|
|
|
}
|
|
|
|
LRESULT::default()
|
|
|
|
}
|
|
|
|
WM_DESTROY => {
|
|
|
|
unsafe { PostQuitMessage(0) };
|
|
|
|
LRESULT::default()
|
|
|
|
}
|
2023-01-30 11:04:34 +11:00
|
|
|
|
2022-11-22 17:56:39 +11:00
|
|
|
_ => {
|
|
|
|
let user_data = unsafe { GetWindowLongPtrA(window, GWLP_USERDATA) };
|
|
|
|
let sample = std::ptr::NonNull::<S>::new(user_data as _);
|
|
|
|
let handled = sample.map_or(false, |mut s| {
|
|
|
|
sample_wndproc(unsafe { s.as_mut() }, message, wparam)
|
|
|
|
});
|
|
|
|
|
|
|
|
if handled {
|
|
|
|
LRESULT::default()
|
|
|
|
} else {
|
|
|
|
unsafe { DefWindowProcA(window, message, wparam, lparam) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
struct Vertex {
|
|
|
|
position: [f32; 3],
|
|
|
|
color: [f32; 3],
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Default)]
|
|
|
|
struct TriangleUniforms {
|
|
|
|
projection_matrix: Mat4,
|
|
|
|
model_matrix: Mat4,
|
2022-11-26 18:38:15 +11:00
|
|
|
view_matrix: Mat4,
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
pub mod d3d11_hello_triangle {
|
2022-12-01 14:50:57 +11:00
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
use super::*;
|
2022-11-30 17:38:05 +11:00
|
|
|
use std::path::Path;
|
|
|
|
|
2023-01-30 13:19:18 +11:00
|
|
|
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode};
|
2023-01-30 13:26:34 +11:00
|
|
|
use librashader_runtime::image::Image;
|
2023-02-17 09:33:47 +11:00
|
|
|
use librashader_runtime_d3d11::options::FilterChainOptionsD3D11;
|
|
|
|
use librashader_runtime_d3d11::FilterChainD3D11;
|
|
|
|
use librashader_runtime_d3d11::{D3D11InputView, D3D11OutputView};
|
2022-11-30 17:38:05 +11:00
|
|
|
use std::slice;
|
|
|
|
use std::time::Instant;
|
2023-02-17 09:33:47 +11:00
|
|
|
use texture::ExampleTexture;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
pub struct Sample {
|
2022-11-26 18:38:15 +11:00
|
|
|
pub dxgi_factory: IDXGIFactory4,
|
|
|
|
pub device: ID3D11Device,
|
|
|
|
pub context: ID3D11DeviceContext,
|
|
|
|
pub resources: Option<Resources>,
|
2023-01-14 08:55:50 +11:00
|
|
|
pub filter: FilterChainD3D11,
|
2023-01-30 13:26:34 +11:00
|
|
|
pub lut: Option<ID3D11Texture2D>,
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Resources {
|
2022-11-26 18:38:15 +11:00
|
|
|
pub swapchain: IDXGISwapChain,
|
|
|
|
pub depth_buffer: ID3D11Texture2D,
|
|
|
|
pub depth_stencil_view: ID3D11DepthStencilView,
|
|
|
|
pub triangle_vertices: ID3D11Buffer,
|
|
|
|
pub triangle_indices: ID3D11Buffer,
|
|
|
|
pub triangle_uniforms: ID3D11Buffer,
|
|
|
|
pub vs: ID3D11VertexShader,
|
|
|
|
pub ps: ID3D11PixelShader,
|
|
|
|
pub input_layout: ID3D11InputLayout,
|
|
|
|
pub frame_start: Instant,
|
|
|
|
pub frame_end: Instant,
|
|
|
|
pub elapsed: f32,
|
2022-11-22 17:56:39 +11:00
|
|
|
triangle_uniform_values: TriangleUniforms,
|
2023-01-30 11:04:34 +11:00
|
|
|
pub renderbuffer: ID3D11Texture2D,
|
|
|
|
pub renderbufffer_rtv: ID3D11RenderTargetView,
|
|
|
|
pub backbuffer: Option<ID3D11Texture2D>,
|
|
|
|
pub backbuffer_rtv: Option<ID3D11RenderTargetView>,
|
2022-11-22 17:56:39 +11:00
|
|
|
pub viewport: D3D11_VIEWPORT,
|
2022-11-30 17:35:20 +11:00
|
|
|
pub shader_output: Option<ID3D11Texture2D>,
|
|
|
|
pub frame_count: usize,
|
2023-02-11 10:08:11 +11:00
|
|
|
pub deferred_context: ID3D11DeviceContext,
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
|
2022-11-29 13:00:54 +11:00
|
|
|
impl Sample {
|
2022-12-01 11:05:12 +11:00
|
|
|
pub(crate) fn new(
|
|
|
|
filter: impl AsRef<Path>,
|
2023-01-14 08:55:50 +11:00
|
|
|
filter_options: Option<&FilterChainOptionsD3D11>,
|
2023-01-30 13:19:18 +11:00
|
|
|
image: Option<Image>,
|
2022-12-01 11:05:12 +11:00
|
|
|
) -> Result<Self> {
|
2022-11-29 13:00:54 +11:00
|
|
|
let (dxgi_factory, device, context) = create_device()?;
|
2023-02-17 09:38:00 +11:00
|
|
|
let filter = unsafe {
|
|
|
|
FilterChainD3D11::load_from_path(filter, &device, filter_options).unwrap()
|
|
|
|
};
|
2023-01-30 13:19:18 +11:00
|
|
|
let lut = if let Some(image) = image {
|
2023-02-16 16:39:36 +11:00
|
|
|
let lut = ExampleTexture::new(
|
2023-01-30 13:26:34 +11:00
|
|
|
&device,
|
|
|
|
&context,
|
|
|
|
&image,
|
|
|
|
D3D11_TEXTURE2D_DESC {
|
|
|
|
Width: image.size.width,
|
|
|
|
Height: image.size.height,
|
|
|
|
MipLevels: 1,
|
|
|
|
ArraySize: 0,
|
|
|
|
Format: ImageFormat::R8G8B8A8Unorm.into(),
|
|
|
|
SampleDesc: DXGI_SAMPLE_DESC {
|
|
|
|
Count: 1,
|
|
|
|
Quality: 0,
|
|
|
|
},
|
|
|
|
Usage: D3D11_USAGE_DYNAMIC,
|
|
|
|
BindFlags: D3D11_BIND_SHADER_RESOURCE,
|
|
|
|
CPUAccessFlags: Default::default(),
|
|
|
|
MiscFlags: Default::default(),
|
|
|
|
},
|
|
|
|
FilterMode::Linear,
|
|
|
|
WrapMode::ClampToEdge,
|
|
|
|
)
|
|
|
|
.unwrap();
|
2023-01-30 13:19:18 +11:00
|
|
|
Some(lut.handle)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
2022-11-22 17:56:39 +11:00
|
|
|
Ok(Sample {
|
2022-11-29 13:00:54 +11:00
|
|
|
filter,
|
2022-11-22 17:56:39 +11:00
|
|
|
dxgi_factory,
|
|
|
|
device,
|
|
|
|
context,
|
2022-11-26 18:38:15 +11:00
|
|
|
resources: None,
|
2023-01-30 13:19:18 +11:00
|
|
|
lut,
|
2022-11-22 17:56:39 +11:00
|
|
|
})
|
|
|
|
}
|
2022-11-29 13:00:54 +11:00
|
|
|
}
|
|
|
|
impl DXSample for Sample {
|
2022-11-22 17:56:39 +11:00
|
|
|
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()> {
|
|
|
|
let swapchain = create_swapchain(&self.dxgi_factory, &self.device, *hwnd)?;
|
|
|
|
let (rtv, backbuffer) = create_rtv(&self.device, &swapchain)?;
|
|
|
|
let (depth_buffer, depth_stencil_view) = create_depth_buffer(&self.device)?;
|
|
|
|
let (triangle_vbo, triangle_indices) = create_triangle_buffers(&self.device)?;
|
2023-01-13 15:02:38 +11:00
|
|
|
let triangle_uniforms = create_triangle_uniforms(&self.device).unwrap();
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2023-01-13 15:02:38 +11:00
|
|
|
let vs_blob = compile_shader(VERTEX_SHADER, b"main\0", b"vs_5_0\0")?;
|
|
|
|
let ps_blob = compile_shader(PIXEL_SHADER, b"main\0", b"ps_5_0\0")?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
let vs_compiled = unsafe {
|
|
|
|
// SAFETY: slice as valid for as long as vs_blob is alive.
|
2022-11-26 18:38:15 +11:00
|
|
|
slice::from_raw_parts(
|
|
|
|
vs_blob.GetBufferPointer().cast::<u8>(),
|
|
|
|
vs_blob.GetBufferSize(),
|
|
|
|
)
|
2022-11-22 17:56:39 +11:00
|
|
|
};
|
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
let vs = unsafe {
|
|
|
|
let mut vso = None;
|
|
|
|
self.device
|
|
|
|
.CreateVertexShader(vs_compiled, None, Some(&mut vso))?;
|
|
|
|
vso.unwrap()
|
|
|
|
};
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
let ps = unsafe {
|
2022-11-26 18:38:15 +11:00
|
|
|
let ps = slice::from_raw_parts(
|
|
|
|
ps_blob.GetBufferPointer().cast::<u8>(),
|
|
|
|
ps_blob.GetBufferSize(),
|
|
|
|
);
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut pso = None;
|
|
|
|
self.device.CreatePixelShader(ps, None, Some(&mut pso))?;
|
|
|
|
pso.unwrap()
|
|
|
|
};
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
let (input_layout, stencil_state, raster_state) =
|
|
|
|
create_pipeline_state(&self.device, vs_compiled)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
self.context.OMSetDepthStencilState(&stencil_state, 1);
|
|
|
|
self.context.RSSetState(&raster_state);
|
|
|
|
}
|
|
|
|
|
2023-01-30 11:04:34 +11:00
|
|
|
let (renderbuffer, render_rtv) = unsafe {
|
|
|
|
let mut renderbuffer = None;
|
|
|
|
let mut rtv = None;
|
|
|
|
let mut desc = Default::default();
|
|
|
|
|
|
|
|
backbuffer.GetDesc(&mut desc);
|
|
|
|
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
|
|
|
|
2023-01-30 13:26:34 +11:00
|
|
|
self.device
|
|
|
|
.CreateTexture2D(&desc, None, Some(&mut renderbuffer))?;
|
2023-01-30 11:04:34 +11:00
|
|
|
let renderbuffer = renderbuffer.unwrap();
|
2023-01-30 13:26:34 +11:00
|
|
|
self.device
|
|
|
|
.CreateRenderTargetView(&renderbuffer, None, Some(&mut rtv))?;
|
2023-01-30 11:04:34 +11:00
|
|
|
(renderbuffer, rtv.unwrap())
|
|
|
|
};
|
2023-02-11 10:08:11 +11:00
|
|
|
|
|
|
|
let mut context = None;
|
|
|
|
unsafe { self.device.CreateDeferredContext(0, Some(&mut context))? };
|
|
|
|
let context = context.expect("Could not create deferred context");
|
|
|
|
|
2022-11-22 17:56:39 +11:00
|
|
|
self.resources = Some(Resources {
|
|
|
|
swapchain,
|
2023-01-30 11:04:34 +11:00
|
|
|
backbuffer_rtv: Some(rtv),
|
|
|
|
backbuffer: Some(backbuffer),
|
2022-11-22 17:56:39 +11:00
|
|
|
depth_buffer,
|
|
|
|
depth_stencil_view,
|
|
|
|
triangle_vertices: triangle_vbo,
|
|
|
|
triangle_indices,
|
|
|
|
triangle_uniforms,
|
|
|
|
vs,
|
|
|
|
ps,
|
|
|
|
input_layout,
|
|
|
|
frame_end: Instant::now(),
|
|
|
|
frame_start: Instant::now(),
|
|
|
|
elapsed: 0f32,
|
|
|
|
triangle_uniform_values: Default::default(),
|
2023-01-30 11:04:34 +11:00
|
|
|
renderbuffer,
|
|
|
|
renderbufffer_rtv: render_rtv,
|
2023-02-11 10:08:11 +11:00
|
|
|
deferred_context: context,
|
2022-11-22 17:56:39 +11:00
|
|
|
viewport: D3D11_VIEWPORT {
|
|
|
|
TopLeftX: 0.0,
|
|
|
|
TopLeftY: 0.0,
|
|
|
|
Width: WIDTH as f32,
|
|
|
|
Height: HEIGHT as f32,
|
|
|
|
MinDepth: D3D11_MIN_DEPTH,
|
|
|
|
MaxDepth: D3D11_MAX_DEPTH,
|
2022-11-26 18:38:15 +11:00
|
|
|
},
|
2022-11-29 13:00:54 +11:00
|
|
|
shader_output: None,
|
2022-11-30 17:38:05 +11:00
|
|
|
frame_count: 0usize,
|
2022-11-22 17:56:39 +11:00
|
|
|
});
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-01-30 13:26:34 +11:00
|
|
|
fn resize(&mut self, _w: u32, _h: u32) -> Result<()> {
|
2023-01-30 11:04:34 +11:00
|
|
|
unsafe {
|
|
|
|
if let Some(resources) = self.resources.as_mut() {
|
|
|
|
drop(resources.backbuffer_rtv.take());
|
|
|
|
drop(resources.backbuffer.take());
|
2023-01-30 13:26:34 +11:00
|
|
|
resources
|
|
|
|
.swapchain
|
|
|
|
.ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0)
|
|
|
|
.unwrap_or_else(|f| eprintln!("{f:?}"));
|
2023-01-30 11:04:34 +11:00
|
|
|
let (rtv, backbuffer) = create_rtv(&self.device, &resources.swapchain)?;
|
|
|
|
|
|
|
|
resources.backbuffer = Some(backbuffer);
|
|
|
|
resources.backbuffer_rtv = Some(rtv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2022-11-22 17:56:39 +11:00
|
|
|
fn render(&mut self) -> Result<()> {
|
|
|
|
let Some(resources) = &mut self.resources else {
|
|
|
|
return Ok(());
|
|
|
|
};
|
|
|
|
|
|
|
|
resources.frame_end = Instant::now();
|
|
|
|
let time = resources.frame_end - resources.frame_start;
|
|
|
|
let time = time.as_secs() as f32 * 1000.0;
|
|
|
|
|
|
|
|
// framelimit set to 60fps
|
2022-11-26 18:38:15 +11:00
|
|
|
if time < (1000.0f32 / 60.0f32) {
|
2022-11-22 17:56:39 +11:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
resources.elapsed += 0.0000001 * time;
|
2022-11-30 17:38:05 +11:00
|
|
|
resources.elapsed %= 6.283_185_5_f32;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
// resources.triangle_uniform_values.model_matrix = Mat4::rotate(Quaternion::axis_angle(Vec3::new(0.0, 0.0, 1.0), resources.elapsed));
|
|
|
|
resources.triangle_uniform_values.model_matrix = Mat4::identity();
|
|
|
|
|
|
|
|
let buffer_number = 0;
|
|
|
|
|
|
|
|
unsafe {
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut mapped_resource = Default::default();
|
|
|
|
self.context.Map(
|
2022-11-26 18:38:15 +11:00
|
|
|
&resources.triangle_uniforms,
|
|
|
|
0,
|
|
|
|
D3D11_MAP_WRITE_DISCARD,
|
|
|
|
0,
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut mapped_resource),
|
2022-11-26 18:38:15 +11:00
|
|
|
)?;
|
|
|
|
std::ptr::copy_nonoverlapping(
|
|
|
|
&resources.triangle_uniform_values,
|
|
|
|
mapped_resource.pData.cast(),
|
|
|
|
1,
|
|
|
|
);
|
2022-11-22 17:56:39 +11:00
|
|
|
self.context.Unmap(&resources.triangle_uniforms, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
2022-11-26 18:38:15 +11:00
|
|
|
self.context.VSSetConstantBuffers(
|
|
|
|
buffer_number,
|
2023-04-23 15:13:31 +10:00
|
|
|
Some(&[Some(resources.triangle_uniforms.clone())]),
|
2022-11-26 18:38:15 +11:00
|
|
|
);
|
|
|
|
self.context.OMSetRenderTargets(
|
2023-04-23 15:13:31 +10:00
|
|
|
Some(&[Some(resources.renderbufffer_rtv.clone())]),
|
2022-11-26 18:38:15 +11:00
|
|
|
&resources.depth_stencil_view,
|
|
|
|
);
|
2022-11-22 17:56:39 +11:00
|
|
|
self.context.RSSetViewports(Some(&[resources.viewport]))
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let color = [0.3, 0.4, 0.6, 1.0];
|
2022-11-26 18:38:15 +11:00
|
|
|
self.context
|
2023-01-30 11:04:34 +11:00
|
|
|
.ClearRenderTargetView(&resources.renderbufffer_rtv, color.as_ptr());
|
2022-11-26 18:38:15 +11:00
|
|
|
self.context.ClearDepthStencilView(
|
|
|
|
&resources.depth_stencil_view,
|
2023-01-29 18:30:58 +11:00
|
|
|
D3D11_CLEAR_DEPTH.0,
|
2022-11-26 18:38:15 +11:00
|
|
|
1.0,
|
|
|
|
0,
|
|
|
|
);
|
2022-11-22 17:56:39 +11:00
|
|
|
self.context.IASetInputLayout(&resources.input_layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
self.context.VSSetShader(&resources.vs, None);
|
|
|
|
self.context.PSSetShader(&resources.ps, None);
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
let stride = std::mem::size_of::<Vertex>() as u32;
|
2022-11-22 17:56:39 +11:00
|
|
|
let offset = 0;
|
2022-11-26 18:38:15 +11:00
|
|
|
self.context.IASetVertexBuffers(
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
Some(&Some(resources.triangle_vertices.clone())),
|
|
|
|
Some(&stride),
|
|
|
|
Some(&offset),
|
|
|
|
);
|
|
|
|
self.context
|
|
|
|
.IASetIndexBuffer(&resources.triangle_indices, DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
self.context
|
|
|
|
.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
self.context.DrawIndexed(3, 0, 0);
|
2023-01-30 13:19:18 +11:00
|
|
|
self.context.OMSetRenderTargets(None, None);
|
2022-11-24 17:37:16 +11:00
|
|
|
}
|
|
|
|
|
2022-11-29 13:00:54 +11:00
|
|
|
unsafe {
|
2023-01-30 13:19:18 +11:00
|
|
|
let input = if let Some(lut) = &self.lut {
|
|
|
|
lut.clone()
|
|
|
|
} else {
|
|
|
|
resources.renderbuffer.clone()
|
|
|
|
};
|
|
|
|
|
2022-11-29 13:00:54 +11:00
|
|
|
let mut tex2d_desc = Default::default();
|
2023-01-30 13:19:18 +11:00
|
|
|
input.GetDesc(&mut tex2d_desc);
|
2023-01-30 11:04:34 +11:00
|
|
|
let mut backbuffer_desc = Default::default();
|
2023-01-30 13:26:34 +11:00
|
|
|
resources
|
|
|
|
.backbuffer
|
|
|
|
.as_ref()
|
|
|
|
.unwrap()
|
|
|
|
.GetDesc(&mut backbuffer_desc);
|
2023-01-30 11:04:34 +11:00
|
|
|
|
2023-01-30 13:19:18 +11:00
|
|
|
let mut input_srv = None;
|
2023-01-17 10:45:02 +11:00
|
|
|
self.device.CreateShaderResourceView(
|
2023-01-30 13:19:18 +11:00
|
|
|
&input,
|
2022-11-30 17:38:05 +11:00
|
|
|
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
|
|
|
Format: tex2d_desc.Format,
|
|
|
|
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
|
|
|
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
|
|
|
Texture2D: D3D11_TEX2D_SRV {
|
|
|
|
MostDetailedMip: 0,
|
|
|
|
MipLevels: u32::MAX,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
2023-01-30 13:19:18 +11:00
|
|
|
Some(&mut input_srv),
|
2022-11-30 17:38:05 +11:00
|
|
|
)?;
|
2023-01-30 13:19:18 +11:00
|
|
|
let srv = input_srv.unwrap();
|
2022-11-30 17:38:05 +11:00
|
|
|
|
2023-01-30 11:04:34 +11:00
|
|
|
// eprintln!("w: {} h: {}", backbuffer_desc.Width, backbuffer_desc.Height);
|
2022-11-30 17:38:05 +11:00
|
|
|
self.filter
|
|
|
|
.frame(
|
2023-02-11 16:20:35 +11:00
|
|
|
None,
|
2023-01-13 18:54:16 +11:00
|
|
|
D3D11InputView {
|
2022-11-30 17:38:05 +11:00
|
|
|
handle: srv,
|
|
|
|
size: Size {
|
|
|
|
width: tex2d_desc.Width,
|
|
|
|
height: tex2d_desc.Height,
|
|
|
|
},
|
|
|
|
},
|
2022-12-01 11:05:12 +11:00
|
|
|
&Viewport {
|
2023-01-30 13:19:18 +11:00
|
|
|
x: 0f32,
|
|
|
|
y: 0f32,
|
2023-01-13 18:54:16 +11:00
|
|
|
output: D3D11OutputView {
|
|
|
|
size: Size {
|
2023-01-30 11:04:34 +11:00
|
|
|
width: backbuffer_desc.Width,
|
|
|
|
height: backbuffer_desc.Height,
|
2023-01-13 18:54:16 +11:00
|
|
|
},
|
2023-01-30 11:04:34 +11:00
|
|
|
handle: resources.backbuffer_rtv.as_ref().unwrap().clone(),
|
2022-11-30 17:38:05 +11:00
|
|
|
},
|
2022-12-01 11:05:12 +11:00
|
|
|
mvp: None,
|
2022-11-30 17:38:05 +11:00
|
|
|
},
|
2022-12-01 11:05:12 +11:00
|
|
|
resources.frame_count,
|
|
|
|
None,
|
2022-11-30 17:38:05 +11:00
|
|
|
)
|
|
|
|
.unwrap();
|
2022-11-29 16:39:15 +11:00
|
|
|
|
2023-02-11 16:20:35 +11:00
|
|
|
// let mut command_list = None;
|
|
|
|
// resources
|
|
|
|
// .deferred_context
|
|
|
|
// .FinishCommandList(false, Some(&mut command_list))?;
|
|
|
|
// let command_list = command_list.unwrap();
|
|
|
|
// self.context.ExecuteCommandList(&command_list, false);
|
2022-11-29 16:39:15 +11:00
|
|
|
// self.context.CopyResource(&resources.backbuffer, &backup);
|
2022-11-29 13:00:54 +11:00
|
|
|
}
|
|
|
|
|
2022-11-24 17:37:16 +11:00
|
|
|
unsafe {
|
2022-11-22 17:56:39 +11:00
|
|
|
resources.swapchain.Present(0, 0).ok()?;
|
|
|
|
}
|
2022-11-30 17:35:20 +11:00
|
|
|
resources.frame_count += 1;
|
2022-11-22 17:56:39 +11:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
fn create_rtv(
|
|
|
|
device: &ID3D11Device,
|
|
|
|
swapchain: &IDXGISwapChain,
|
|
|
|
) -> Result<(ID3D11RenderTargetView, ID3D11Texture2D)> {
|
2022-11-22 17:56:39 +11:00
|
|
|
unsafe {
|
|
|
|
let backbuffer: ID3D11Texture2D = swapchain.GetBuffer(0)?;
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut rtv = None;
|
|
|
|
device.CreateRenderTargetView(&backbuffer, None, Some(&mut rtv))?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
Ok((rtv.unwrap(), backbuffer))
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
}
|
2022-11-26 18:38:15 +11:00
|
|
|
fn create_pipeline_state(
|
|
|
|
device: &ID3D11Device,
|
|
|
|
vs_blob: &[u8],
|
|
|
|
) -> Result<(
|
|
|
|
ID3D11InputLayout,
|
|
|
|
ID3D11DepthStencilState,
|
|
|
|
ID3D11RasterizerState,
|
|
|
|
)> {
|
2022-11-22 17:56:39 +11:00
|
|
|
unsafe {
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut input_layout = None;
|
|
|
|
device.CreateInputLayout(
|
2022-11-26 18:38:15 +11:00
|
|
|
&[
|
|
|
|
D3D11_INPUT_ELEMENT_DESC {
|
|
|
|
SemanticName: s!("POSITION"),
|
|
|
|
SemanticIndex: 0,
|
|
|
|
Format: DXGI_FORMAT_R32G32B32_FLOAT,
|
|
|
|
InputSlot: 0,
|
|
|
|
AlignedByteOffset: 0,
|
|
|
|
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
|
|
InstanceDataStepRate: 0,
|
|
|
|
},
|
|
|
|
D3D11_INPUT_ELEMENT_DESC {
|
|
|
|
SemanticName: s!("COLOR"),
|
|
|
|
SemanticIndex: 0,
|
|
|
|
Format: DXGI_FORMAT_R32G32B32_FLOAT,
|
|
|
|
InputSlot: 0,
|
|
|
|
AlignedByteOffset: D3D11_APPEND_ALIGNED_ELEMENT,
|
|
|
|
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
|
|
InstanceDataStepRate: 0,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
vs_blob,
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut input_layout),
|
2022-11-26 18:38:15 +11:00
|
|
|
)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
let input_layout = input_layout.unwrap();
|
|
|
|
|
|
|
|
let mut stencil_state = None;
|
|
|
|
device.CreateDepthStencilState(
|
|
|
|
&D3D11_DEPTH_STENCIL_DESC {
|
|
|
|
DepthEnable: BOOL::from(true),
|
|
|
|
DepthWriteMask: D3D11_DEPTH_WRITE_MASK_ALL,
|
|
|
|
DepthFunc: D3D11_COMPARISON_LESS,
|
|
|
|
StencilEnable: BOOL::from(true),
|
|
|
|
StencilReadMask: 0xff,
|
|
|
|
StencilWriteMask: 0xff,
|
|
|
|
FrontFace: D3D11_DEPTH_STENCILOP_DESC {
|
|
|
|
StencilFailOp: D3D11_STENCIL_OP_KEEP,
|
|
|
|
StencilDepthFailOp: D3D11_STENCIL_OP_INCR,
|
|
|
|
StencilPassOp: D3D11_STENCIL_OP_KEEP,
|
|
|
|
StencilFunc: D3D11_COMPARISON_ALWAYS,
|
|
|
|
},
|
|
|
|
BackFace: D3D11_DEPTH_STENCILOP_DESC {
|
|
|
|
StencilFailOp: D3D11_STENCIL_OP_KEEP,
|
|
|
|
StencilDepthFailOp: D3D11_STENCIL_OP_DECR,
|
|
|
|
StencilPassOp: D3D11_STENCIL_OP_KEEP,
|
|
|
|
StencilFunc: D3D11_COMPARISON_ALWAYS,
|
|
|
|
},
|
2022-11-22 17:56:39 +11:00
|
|
|
},
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut stencil_state),
|
|
|
|
)?;
|
|
|
|
let stencil_state = stencil_state.unwrap();
|
|
|
|
|
|
|
|
let mut rasterizer_state = None;
|
|
|
|
device.CreateRasterizerState(
|
|
|
|
&D3D11_RASTERIZER_DESC {
|
|
|
|
AntialiasedLineEnable: BOOL::from(false),
|
|
|
|
CullMode: D3D11_CULL_NONE,
|
|
|
|
DepthBias: 0,
|
|
|
|
DepthBiasClamp: 0.0f32,
|
|
|
|
DepthClipEnable: BOOL::from(true),
|
|
|
|
FillMode: D3D11_FILL_SOLID,
|
|
|
|
FrontCounterClockwise: BOOL::from(false),
|
|
|
|
MultisampleEnable: BOOL::from(false),
|
|
|
|
ScissorEnable: BOOL::from(false),
|
|
|
|
SlopeScaledDepthBias: 0.0f32,
|
2022-11-26 18:38:15 +11:00
|
|
|
},
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut rasterizer_state),
|
|
|
|
)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
let rasterizer_state = rasterizer_state.unwrap();
|
2022-11-22 17:56:39 +11:00
|
|
|
Ok((input_layout, stencil_state, rasterizer_state))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
fn create_depth_buffer(
|
|
|
|
device: &ID3D11Device,
|
|
|
|
) -> Result<(ID3D11Texture2D, ID3D11DepthStencilView)> {
|
2022-11-22 17:56:39 +11:00
|
|
|
unsafe {
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut buffer = None;
|
|
|
|
device.CreateTexture2D(
|
2022-11-26 18:38:15 +11:00
|
|
|
&D3D11_TEXTURE2D_DESC {
|
|
|
|
Width: WIDTH as u32,
|
|
|
|
Height: HEIGHT as u32,
|
|
|
|
MipLevels: 1,
|
|
|
|
ArraySize: 1,
|
|
|
|
Format: DXGI_FORMAT_D24_UNORM_S8_UINT,
|
|
|
|
SampleDesc: DXGI_SAMPLE_DESC {
|
|
|
|
Count: 1,
|
|
|
|
Quality: 0,
|
2022-11-22 17:56:39 +11:00
|
|
|
},
|
2022-11-26 18:38:15 +11:00
|
|
|
Usage: D3D11_USAGE_DEFAULT,
|
|
|
|
BindFlags: D3D11_BIND_DEPTH_STENCIL,
|
|
|
|
CPUAccessFlags: Default::default(),
|
|
|
|
MiscFlags: Default::default(),
|
2022-11-22 17:56:39 +11:00
|
|
|
},
|
2022-11-26 18:38:15 +11:00
|
|
|
None,
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut buffer),
|
2022-11-26 18:38:15 +11:00
|
|
|
)?;
|
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
let buffer = buffer.unwrap();
|
|
|
|
|
|
|
|
let mut view = None;
|
|
|
|
device.CreateDepthStencilView(
|
2022-11-26 18:38:15 +11:00
|
|
|
&buffer,
|
|
|
|
Some(&D3D11_DEPTH_STENCIL_VIEW_DESC {
|
|
|
|
Format: DXGI_FORMAT_D24_UNORM_S8_UINT,
|
|
|
|
ViewDimension: D3D11_DSV_DIMENSION_TEXTURE2D,
|
|
|
|
Anonymous: D3D11_DEPTH_STENCIL_VIEW_DESC_0 {
|
|
|
|
Texture2D: D3D11_TEX2D_DSV { MipSlice: 0 },
|
|
|
|
},
|
|
|
|
..Default::default()
|
|
|
|
}),
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut view),
|
2022-11-26 18:38:15 +11:00
|
|
|
)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
let view = view.unwrap();
|
|
|
|
|
2022-11-22 17:56:39 +11:00
|
|
|
Ok((buffer, view))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_triangle_uniforms(device: &ID3D11Device) -> Result<ID3D11Buffer> {
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut buffer = None;
|
2022-11-22 17:56:39 +11:00
|
|
|
unsafe {
|
2022-11-26 18:38:15 +11:00
|
|
|
device.CreateBuffer(
|
|
|
|
&D3D11_BUFFER_DESC {
|
|
|
|
ByteWidth: (std::mem::size_of::<TriangleUniforms>()) as u32,
|
|
|
|
Usage: D3D11_USAGE_DYNAMIC,
|
|
|
|
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
|
|
|
|
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
|
|
|
|
MiscFlags: Default::default(),
|
|
|
|
StructureByteStride: 0,
|
|
|
|
},
|
|
|
|
None,
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut buffer),
|
|
|
|
)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
2023-01-17 10:45:02 +11:00
|
|
|
Ok(buffer.unwrap())
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
fn create_triangle_buffers(device: &ID3D11Device) -> Result<(ID3D11Buffer, ID3D11Buffer)> {
|
2022-11-22 17:56:39 +11:00
|
|
|
let vertices = [
|
|
|
|
Vertex {
|
|
|
|
position: [0.5f32, -0.5, 0.0],
|
|
|
|
color: [1.0, 0.0, 0.0],
|
|
|
|
},
|
|
|
|
Vertex {
|
|
|
|
position: [-0.5, -0.5, 0.0],
|
|
|
|
color: [0.0, 1.0, 0.0],
|
|
|
|
},
|
|
|
|
Vertex {
|
|
|
|
position: [0.0, 0.5, 0.0],
|
|
|
|
color: [0.0, 0.0, 1.0],
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
let indices = [0, 1, 2];
|
|
|
|
unsafe {
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut vertex_buffer = None;
|
|
|
|
device.CreateBuffer(
|
2022-11-26 18:38:15 +11:00
|
|
|
&D3D11_BUFFER_DESC {
|
|
|
|
ByteWidth: (std::mem::size_of::<Vertex>() * vertices.len()) as u32,
|
|
|
|
Usage: D3D11_USAGE_DEFAULT,
|
|
|
|
BindFlags: D3D11_BIND_VERTEX_BUFFER,
|
|
|
|
CPUAccessFlags: Default::default(),
|
|
|
|
MiscFlags: Default::default(),
|
|
|
|
StructureByteStride: 0,
|
|
|
|
},
|
|
|
|
Some(&D3D11_SUBRESOURCE_DATA {
|
|
|
|
pSysMem: vertices.as_ptr().cast(),
|
|
|
|
SysMemPitch: 0,
|
|
|
|
SysMemSlicePitch: 0,
|
|
|
|
}),
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut vertex_buffer),
|
2022-11-26 18:38:15 +11:00
|
|
|
)?;
|
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
let mut index_buffer = None;
|
|
|
|
device.CreateBuffer(
|
2022-11-26 18:38:15 +11:00
|
|
|
&D3D11_BUFFER_DESC {
|
|
|
|
ByteWidth: (std::mem::size_of::<u32>() * indices.len()) as u32,
|
|
|
|
Usage: D3D11_USAGE_DEFAULT,
|
|
|
|
BindFlags: D3D11_BIND_INDEX_BUFFER,
|
|
|
|
CPUAccessFlags: Default::default(),
|
|
|
|
MiscFlags: Default::default(),
|
|
|
|
StructureByteStride: 0,
|
|
|
|
},
|
|
|
|
Some(&D3D11_SUBRESOURCE_DATA {
|
|
|
|
pSysMem: indices.as_ptr().cast(),
|
|
|
|
SysMemPitch: 0,
|
|
|
|
SysMemSlicePitch: 0,
|
|
|
|
}),
|
2023-01-17 10:45:02 +11:00
|
|
|
Some(&mut index_buffer),
|
2022-11-26 18:38:15 +11:00
|
|
|
)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
2023-01-17 10:45:02 +11:00
|
|
|
Ok((vertex_buffer.unwrap(), index_buffer.unwrap()))
|
2022-11-22 17:56:39 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> {
|
2022-12-01 11:05:12 +11:00
|
|
|
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG) }?;
|
2022-11-22 17:56:39 +11:00
|
|
|
let feature_levels = vec![D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1];
|
|
|
|
|
|
|
|
let mut out_device = None;
|
|
|
|
let mut out_context = None;
|
|
|
|
let mut _out_feature_level = D3D_FEATURE_LEVEL_11_0;
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
unsafe {
|
|
|
|
D3D11CreateDevice(
|
|
|
|
None,
|
|
|
|
D3D_DRIVER_TYPE_HARDWARE,
|
2023-04-23 15:13:31 +10:00
|
|
|
HMODULE::default(),
|
2022-11-29 17:57:04 +11:00
|
|
|
D3D11_CREATE_DEVICE_DEBUG,
|
2022-11-26 18:38:15 +11:00
|
|
|
Some(&feature_levels),
|
|
|
|
D3D11_SDK_VERSION,
|
|
|
|
Some(&mut out_device),
|
|
|
|
Some(&mut _out_feature_level),
|
|
|
|
Some(&mut out_context),
|
|
|
|
)
|
2022-11-22 17:56:39 +11:00
|
|
|
}?;
|
|
|
|
Ok((dxgi_factory, out_device.unwrap(), out_context.unwrap()))
|
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
fn create_swapchain(
|
|
|
|
fac: &IDXGIFactory4,
|
|
|
|
device: &ID3D11Device,
|
|
|
|
hwnd: HWND,
|
|
|
|
) -> Result<IDXGISwapChain> {
|
2022-11-22 17:56:39 +11:00
|
|
|
let swapchain_desc = DXGI_SWAP_CHAIN_DESC {
|
|
|
|
BufferDesc: DXGI_MODE_DESC {
|
|
|
|
Width: WIDTH as u32,
|
|
|
|
Height: HEIGHT as u32,
|
|
|
|
RefreshRate: DXGI_RATIONAL {
|
|
|
|
Numerator: 0,
|
|
|
|
Denominator: 1,
|
|
|
|
},
|
|
|
|
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
|
|
|
|
ScanlineOrdering: DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
|
|
|
|
Scaling: DXGI_MODE_SCALING_UNSPECIFIED,
|
|
|
|
},
|
|
|
|
SampleDesc: DXGI_SAMPLE_DESC {
|
|
|
|
Count: 1,
|
|
|
|
Quality: 0,
|
|
|
|
},
|
|
|
|
BufferUsage: DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
|
|
|
BufferCount: 1,
|
|
|
|
OutputWindow: hwnd,
|
|
|
|
Windowed: BOOL(1),
|
|
|
|
SwapEffect: DXGI_SWAP_EFFECT_DISCARD,
|
|
|
|
Flags: 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut swap_chain = None;
|
|
|
|
unsafe {
|
2022-11-30 17:38:05 +11:00
|
|
|
fac.CreateSwapChain(device, &swapchain_desc, &mut swap_chain)
|
2022-11-22 17:56:39 +11:00
|
|
|
.ok()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(swap_chain.expect("[dx11] swapchain creation failed."))
|
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
fn compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result<ID3DBlob> {
|
2022-11-22 17:56:39 +11:00
|
|
|
unsafe {
|
|
|
|
let mut blob = None;
|
2022-11-26 18:38:15 +11:00
|
|
|
D3DCompile(
|
|
|
|
source.as_ptr().cast(),
|
|
|
|
source.len(),
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
PCSTR(entry.as_ptr()),
|
|
|
|
PCSTR(version.as_ptr()),
|
|
|
|
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,
|
|
|
|
0,
|
|
|
|
&mut blob,
|
|
|
|
None,
|
|
|
|
)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
Ok(blob.unwrap())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-26 18:38:15 +11:00
|
|
|
pub fn main<S: DXSample>(sample: S) -> Result<()> {
|
|
|
|
run_sample(sample)?;
|
2022-11-22 17:56:39 +11:00
|
|
|
|
|
|
|
Ok(())
|
2022-11-26 18:38:15 +11:00
|
|
|
}
|