Add DirectX support behind feature flag

This commit is contained in:
Michael Tang 2019-04-21 19:41:14 -07:00
parent 616d61767f
commit d11e008aa0
8 changed files with 79 additions and 28 deletions

View File

@ -9,6 +9,11 @@ repository = "https://github.com/Gekkio/imgui-rs"
license = "MIT/Apache-2.0"
publish = false
[features]
opengl = ["imgui-gfx-renderer/opengl"]
directx = ["imgui-gfx-renderer/directx"]
default = ["opengl"]
[dev-dependencies]
gfx = "0.17"
gfx_window_glutin = "0.28"

4
imgui-examples/README.md Normal file
View File

@ -0,0 +1,4 @@
# `imgui-examples`
- Run with OpenGL backend: `cargo run --example hello_gfx`
- Run with DirectX backend: `cargo run --example hello_gfx --features directx --no-default-features`

View File

@ -5,11 +5,17 @@ mod support_gfx;
const CLEAR_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
fn main() {
support_gfx::run_dx11("hello_gfx.rs".to_owned(), CLEAR_COLOR, hello_world);
support_gfx::run("hello_gfx.rs".to_owned(), CLEAR_COLOR, hello_world);
}
fn hello_world<'a>(ui: &Ui<'a>) -> bool {
ui.window(im_str!("Hello world"))
#[cfg(feature = "opengl")]
let window_title = im_str!("Hello world (OpenGL)");
#[cfg(feature = "directx")]
let window_title = im_str!("Hello world (DirectX)");
ui.window(window_title)
.size((300.0, 100.0), ImGuiCond::FirstUseEver)
.build(|| {
ui.text(im_str!("Hello world!"));

View File

@ -3,6 +3,7 @@ use imgui_gfx_renderer::{Renderer, Shaders};
use imgui_winit_support;
use std::time::Instant;
#[cfg(feature = "opengl")]
pub fn run<F: FnMut(&Ui) -> bool>(title: String, clear_color: [f32; 4], mut run_ui: F) {
use gfx::{self, Device};
use gfx_window_glutin;
@ -146,8 +147,8 @@ pub fn run<F: FnMut(&Ui) -> bool>(title: String, clear_color: [f32; 4], mut run_
}
}
// #[cfg(windows)]
pub fn run_dx11<F: FnMut(&Ui) -> bool>(title: String, clear_color: [f32; 4], mut run_ui: F) {
#[cfg(feature = "directx")]
pub fn run<F: FnMut(&Ui) -> bool>(title: String, clear_color: [f32; 4], mut run_ui: F) {
use gfx::{self, Device};
use gfx_window_dxgi;
use glutin;

View File

@ -9,6 +9,11 @@ repository = "https://github.com/Gekkio/imgui-rs"
license = "MIT/Apache-2.0"
categories = ["gui", "rendering"]
[features]
opengl = []
directx = []
default = ["opengl"]
[badges]
travis-ci = { repository = "Gekkio/imgui-rs" }

View File

@ -21,6 +21,8 @@ mod hlsl_build {
.join("shader")
.join("sm_40.hlsl");
println!("cargo:rerun-if-changed={}", source_path.display());
let src_data = fs::read_to_string(&source_path).unwrap();
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

View File

@ -76,7 +76,21 @@ macro_rules! extended_defines {
}
}
#[cfg(not(windows))]
#[cfg(feature = "directx")]
mod constants {
use gfx::gfx_constant_struct_meta;
use gfx::gfx_impl_struct_meta;
gfx::gfx_constant_struct! {
Constants {
// `matrix` is a reserved keyword in HLSL
matrix: [[f32; 4]; 4] = "matrix_",
}
}
}
// This version of `pipe` uses a single uniform for `matrix`, used in GLSL shaders
#[cfg(not(feature = "directx"))]
extended_defines! {
pipeline pipe {
vertex_buffer: gfx::VertexBuffer<ImDrawVert> = (),
@ -91,12 +105,12 @@ extended_defines! {
}
}
// TODO need constant buffer support
#[cfg(windows)]
// This version of `pipe` uses a constant buffer containing `matrix`, used in the HLSL shader
#[cfg(feature = "directx")]
extended_defines! {
pipeline pipe {
vertex_buffer: gfx::VertexBuffer<ImDrawVert> = (),
matrix: gfx::Global<[[f32; 4]; 4]> = "transform",
constants: gfx::ConstantBuffer<constants::Constants> = "Constants",
tex: gfx::TextureSampler<[f32; 4]> = "tex",
out: gfx::BlendTarget<gfx::format::Rgba8> = (
"Target0",
@ -109,13 +123,20 @@ extended_defines! {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Shaders {
GlSl400, // OpenGL 4.0+
GlSl150, // OpenGL 3.2+
GlSl130, // OpenGL 3.0+
GlSl110, // OpenGL 2.0+
GlSlEs300, // OpenGL ES 3.0+
GlSlEs100, // OpenGL ES 2.0+
HlslSm40, // HLSL Shader Model 4.0+
/// OpenGL 4.0+
GlSl400,
/// OpenGL 3.2+
GlSl150,
/// OpenGL 3.0+
GlSl130,
/// OpenGL 2.0+
GlSl110,
/// OpenGL ES 3.0+
GlSlEs300,
/// OpenGL ES 2.0+
GlSlEs100,
/// HLSL Shader Model 4.0+
HlslSm40,
}
impl Shaders {
@ -147,13 +168,13 @@ impl Shaders {
include_bytes!("shader/glsles_100.frag"),
),
HlslSm40 => {
#[cfg(not(windows))]
#[cfg(not(feature = "directx"))]
{
// panic instead?
(&[0], &[0])
}
#[cfg(windows)]
#[cfg(feature = "directx")]
{
(
include_bytes!(concat!(env!("OUT_DIR"), "/hlsl_vertex_shader_bytecode")),
@ -174,6 +195,8 @@ pub struct Renderer<R: Resources> {
bundle: Bundle<R, pipe::Data<R>>,
index_buffer: Buffer<R, u16>,
textures: Textures<Texture<R>>,
#[cfg(feature = "directx")]
constants: Buffer<R, constants::Constants>,
}
impl<R: Resources> Renderer<R> {
@ -230,6 +253,8 @@ impl<R: Resources> Renderer<R> {
},
index_buffer,
textures,
#[cfg(feature = "directx")]
constants: factory.create_constant_buffer(1),
})
}
@ -309,9 +334,19 @@ impl<R: Resources> Renderer<R> {
.min(fb_height)
.round() as u16,
};
#[cfg(feature = "directx")]
{
let constants = constants::Constants { matrix: *matrix };
encoder.update_constant_buffer(&self.constants, &constants);
}
let data = pipe::BorrowedData {
vertex_buffer: &self.bundle.vertex_buffer,
#[cfg(not(feature = "directx"))]
matrix,
#[cfg(feature = "directx")]
constants: &self.constants,
tex,
out: &self.bundle.out,
scissor: &scissor,

View File

@ -1,16 +1,9 @@
cbuffer Constants : register(b0) {
float4x4 transform;
float4x4 matrix_;
}
Texture2D tex;
// Should be trilinear clamp
SamplerState linear_clamp_sampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
SamplerState tex_;
struct VIn {
float2 position : pos;
@ -28,7 +21,7 @@ struct VOut
VOut VertexMain(VIn vertex)
{
VOut output;
output.position = mul(transform, float4(vertex.position, 0.0, 1.0));
output.position = mul(matrix_, float4(vertex.position, 0.0, 1.0));
output.uv = vertex.uv;
output.color = vertex.color;
@ -37,5 +30,5 @@ VOut VertexMain(VIn vertex)
float4 PixelMain(VOut vout) : SV_TARGET
{
return vout.color * tex.Sample(linear_clamp_sampler, vout.uv);
return vout.color * tex.Sample(tex_, vout.uv);
}