├── .gitignore ├── bgfx-sys ├── .gitignore ├── Cargo.toml ├── Makefile ├── build.rs └── src │ └── lib.rs ├── .gitattributes ├── examples ├── assets │ ├── 00-helloworld │ │ └── logo.bin │ └── 01-cubes │ │ ├── Metal │ │ ├── fs_cubes.bin │ │ └── vs_cubes.bin │ │ ├── OpenGL │ │ ├── fs_cubes.bin │ │ └── vs_cubes.bin │ │ ├── Direct3D9 │ │ ├── fs_cubes.bin │ │ └── vs_cubes.bin │ │ ├── OpenGLES │ │ ├── fs_cubes.bin │ │ └── vs_cubes.bin │ │ └── Direct3D11 │ │ ├── fs_cubes.bin │ │ └── vs_cubes.bin ├── 00-helloworld.rs ├── common │ └── mod.rs └── 01-cubes.rs ├── rustfmt.toml ├── Makefile ├── .gitmodules ├── Cargo.toml ├── .travis.yml ├── scripts └── rust-dl.ps1 ├── LICENSE ├── appveyor.yml ├── README.md └── src ├── flags.rs └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /bgfx-sys/.gitignore: -------------------------------------------------------------------------------- 1 | rust-bindgen/ 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.rs text 3 | *.toml text 4 | *.bin binary 5 | -------------------------------------------------------------------------------- /examples/assets/00-helloworld/logo.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/00-helloworld/logo.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/Metal/fs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/Metal/fs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/Metal/vs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/Metal/vs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/OpenGL/fs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/OpenGL/fs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/OpenGL/vs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/OpenGL/vs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/Direct3D9/fs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/Direct3D9/fs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/Direct3D9/vs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/Direct3D9/vs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/OpenGLES/fs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/OpenGLES/fs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/OpenGLES/vs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/OpenGLES/vs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/Direct3D11/fs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/Direct3D11/fs_cubes.bin -------------------------------------------------------------------------------- /examples/assets/01-cubes/Direct3D11/vs_cubes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhoot/bgfx-rs/HEAD/examples/assets/01-cubes/Direct3D11/vs_cubes.bin -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | fn_call_width = 80 2 | struct_lit_width = 50 3 | report_todo = "Never" 4 | reorder_imports = true 5 | single_line_if_else = true 6 | newline_style = "Native" 7 | -------------------------------------------------------------------------------- /bgfx-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bgfx-sys" 3 | version = "0.1.0" 4 | authors = ["Johan Sköld "] 5 | build = "build.rs" 6 | 7 | [dependencies] 8 | libc = "0.2.4" 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | _PHONY: format 2 | 3 | EXAMPLES = $(shell find examples -type f -name '*.rs') 4 | SRCS = $(shell find src -type f -name '*.rs') 5 | 6 | format: $(EXAMPLES) $(SRCS) 7 | @rustfmt --write-mode=overwrite $(EXAMPLES) $(SRCS) 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "bgfx-sys/bgfx"] 2 | path = bgfx-sys/bgfx 3 | url = https://github.com/bkaradzic/bgfx.git 4 | [submodule "bgfx-sys/bx"] 5 | path = bgfx-sys/bx 6 | url = https://github.com/bkaradzic/bx.git 7 | [submodule "bgfx-sys/bimg"] 8 | path = bgfx-sys/bimg 9 | url = https://github.com/bkaradzic/bimg.git 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bgfx" 3 | version = "0.1.0" 4 | authors = ["Johan Sköld "] 5 | 6 | [dependencies] 7 | bitflags = "0.3.2" 8 | libc = "0.2.4" 9 | 10 | [dependencies.bgfx-sys] 11 | path = "bgfx-sys/" 12 | 13 | [dev-dependencies] 14 | cgmath = "0.7.0" 15 | glutin = "0.7.1" 16 | time = "0.1.33" 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | dist: trusty 3 | sudo: false 4 | 5 | rust: 6 | - stable 7 | - beta 8 | - nightly 9 | 10 | os: 11 | - linux 12 | - osx 13 | 14 | matrix: 15 | allow_failures: 16 | - rust: nightly 17 | 18 | addons: 19 | apt: 20 | packages: 21 | - build-essential 22 | - libgl1-mesa-dev 23 | - x11proto-core-dev 24 | - libx11-dev 25 | -------------------------------------------------------------------------------- /scripts/rust-dl.ps1: -------------------------------------------------------------------------------- 1 | $Channel = "http://static.rust-lang.org/dist/channel-rust-$env:CHANNEL" 2 | Write-Output "reading: $Channel" 3 | 4 | $Manifest = Invoke-WebRequest -Uri $Channel 5 | $ManifestLines = $Manifest.RawContent -Split "`n" 6 | 7 | foreach ($Line in $ManifestLines -Like "*$env:TARGET.exe") { 8 | $Url = "http://static.rust-lang.org/dist/$Line" 9 | $Path = "$PSScriptRoot\rust.exe" 10 | Write-Output "downloading:" 11 | Write-Output " source: $Url" 12 | Write-Output " target: $Path" 13 | (New-Object System.Net.WebClient).DownloadFile($Url, $Path) 14 | } 15 | -------------------------------------------------------------------------------- /bgfx-sys/Makefile: -------------------------------------------------------------------------------- 1 | rust-bindgen: 2 | git clone https://github.com/servo/rust-bindgen.git 3 | 4 | rust-bindgen/target/release/bindgen: rust-bindgen 5 | cd rust-bindgen && cargo build --release 6 | 7 | src/ffi_bgfx.rs: rust-bindgen/target/release/bindgen bgfx/include/bgfx/c99/bgfx.h bgfx/include/bgfx/c99/platform.h 8 | rust-bindgen/target/release/bindgen \ 9 | --constified-enum bgfx_renderer_type \ 10 | --constified-enum bgfx_attrib \ 11 | --constified-enum bgfx_render_frame \ 12 | -o src/ffi_bgfx.rs \ 13 | bgfx/include/bgfx/c99/platform.h \ 14 | -- \ 15 | -Ibgfx/include \ 16 | -Ibx/include \ 17 | -include bgfx/c99/bgfx.h 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2016, Johan Sköld 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - CHANNEL: stable 4 | TARGET: x86_64-pc-windows-msvc 5 | - CHANNEL: stable 6 | TARGET: x86_64-pc-windows-gnu 7 | - CHANNEL: stable 8 | TARGET: i686-pc-windows-gnu 9 | 10 | install: 11 | - git submodule update --init --recursive 12 | - ps: scripts\rust-dl.ps1 13 | - scripts\rust.exe /VERYSILENT /NORESTART /DIR=C:\Rust 14 | - call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64 15 | - set MINGW=C:/msys64/mingw64 16 | - set PATH=C:\Rust\bin;C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH% 17 | - rustc --version --verbose 18 | - cargo --version --verbose 19 | - make --version 20 | - if %TARGET:~-4%==-gnu x86_64-w64-mingw32-g++ --version 21 | 22 | build: false 23 | 24 | test_script: 25 | - cargo build --verbose 26 | - cargo test --verbose 27 | -------------------------------------------------------------------------------- /examples/00-helloworld.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | extern crate bgfx; 5 | extern crate glutin; 6 | 7 | mod common; 8 | 9 | use bgfx::*; 10 | use common::EventQueue; 11 | use std::cmp::max; 12 | 13 | const LOGO: &'static [u8] = include_bytes!("assets/00-helloworld/logo.bin"); 14 | 15 | fn example(events: EventQueue) { 16 | let mut width: u16 = 1280; 17 | let mut height: u16 = 720; 18 | let debug = DEBUG_TEXT; 19 | let reset = RESET_VSYNC; 20 | 21 | let bgfx = bgfx::init(RendererType::Default, None, None).unwrap(); 22 | bgfx.reset(width, height, reset); 23 | 24 | // Enable debug text. 25 | bgfx.set_debug(debug); 26 | 27 | // Set view 0 clear state. 28 | let clear = CLEAR_COLOR | CLEAR_DEPTH; 29 | bgfx.set_view_clear(0, clear, 0x303030ff, 1.0_f32, 0); 30 | 31 | while !events.handle_events(&bgfx, &mut width, &mut height, reset) { 32 | // Set view 0 default viewport. 33 | bgfx.set_view_rect(0, 0, 0, width, height); 34 | 35 | // This dummy draw call is here to make sure that view 0 is cleared 36 | // if no other draw calls are submitted to view 0. 37 | bgfx.touch(0); 38 | 39 | // Use debug font to print information about this example. 40 | let x: u16 = max(width / 2 / 8, 20) - 20; 41 | let y: u16 = max(height / 2 / 16, 6) - 6; 42 | bgfx.dbg_text_clear(None, None); 43 | bgfx.dbg_text_image(x, y, 40, 12, LOGO, 160); 44 | bgfx.dbg_text_print(0, 1, 0x4f, "examples/00-helloworld.rs"); 45 | bgfx.dbg_text_print(0, 2, 0x6f, "Description: Initialization and debug text."); 46 | 47 | // Advance to next frame. Rendering thread will be kicked to 48 | // process submitted rendering primitives. 49 | bgfx.frame(false); 50 | } 51 | 52 | // bgfx will automatically be shut down when the local `bgfx` binding 53 | // goes out of scope. 54 | } 55 | 56 | fn main() { 57 | common::run_example(1280, 720, example); 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | bgfx-rs [![travis-ci status](https://travis-ci.org/rhoot/bgfx-rs.svg?branch=master)](https://travis-ci.org/rhoot/bgfx-rs) [![appveyor status](https://ci.appveyor.com/api/projects/status/github/rhoot/bgfx-rs?branch=master&svg=true)](https://ci.appveyor.com/project/rhoot/bgfx-rs/branch/master) 2 | ======= 3 | 4 | Rust wrapper around [bgfx], providing a clean, safe API for rust applications. 5 | 6 | *Please read the [crate documentation][docs] for build requirements and crate 7 | limitations before using.* 8 | 9 | **Note:** I was originally using this crate as a way of learning Rust. Since I 10 | personally stopped using Rust again however, this crate has ended up more or 11 | less unmaintained. There are a couple of forks that have some more work put 12 | into it already, but if someone wants to take over the project for real, 13 | please let me know so I can direct users to your fork instead. 14 | 15 | Documentation 16 | ------------- 17 | 18 | [API Documentation][docs] 19 | 20 | ### Examples 21 | 22 | To run the examples, invoke them through cargo: 23 | 24 | ``` 25 | cargo run --example 00-helloworld 26 | cargo run --example 01-cubes 27 | ``` 28 | 29 | **OSX Note:** There is currently no really clean way to exit the examples in 30 | OSX, and closing the window may in fact cause a crash. This is due to 31 | limitations in [glutin][glutin] (specifically [#468] and [#520]). This only 32 | effects the examples, and not the crate itself. The best way of closing them 33 | is to simply `Ctrl-C` in the console. 34 | 35 | License 36 | ------- 37 | Copyright (c) 2015-2016, Johan Sköld 38 | 39 | Permission to use, copy, modify, and/or distribute this software for any 40 | purpose with or without fee is hereby granted, provided that the above 41 | copyright notice and this permission notice appear in all copies. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 44 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 45 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 46 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 47 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 48 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 49 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 50 | 51 | 52 | [#468]: https://github.com/tomaka/glutin/issues/468 "tomaka/glutin #468" 53 | [#520]: https://github.com/tomaka/glutin/issues/520 "tomaka/glutin #520" 54 | [bgfx]: https://github.com/bkaradzic/bgfx "bgfx" 55 | [docs]: https://rhoot.github.io/bgfx-rs/bgfx/ "Bindings documentation" 56 | [glutin]: https://github.com/tomaka/glutin "glutin" -------------------------------------------------------------------------------- /examples/common/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | extern crate bgfx; 5 | extern crate glutin; 6 | extern crate libc; 7 | 8 | use bgfx::{Bgfx, PlatformData, RenderFrame}; 9 | 10 | use glutin::{Api, GlRequest, Window, WindowBuilder}; 11 | 12 | use std; 13 | use std::env; 14 | use std::fs::File; 15 | use std::io::Read; 16 | use std::sync::mpsc::{Receiver, Sender, channel}; 17 | use std::thread; 18 | use std::time::Duration; 19 | 20 | /// Events received by the main thread, sent by the render thread. 21 | #[derive(PartialEq, Eq, Hash, Debug)] 22 | pub enum Event { 23 | /// Window close event. 24 | Close, 25 | 26 | /// Window size event. 27 | Size(u16, u16), 28 | } 29 | 30 | /// Event queue for communicating with the render thread. 31 | pub struct EventQueue { 32 | event_rx: Receiver, 33 | } 34 | 35 | impl EventQueue { 36 | 37 | /// Handles events received from the render thread. If there are no events to process, returns 38 | /// instantly. 39 | /// 40 | /// Returns `true` if the app should exit. 41 | pub fn handle_events(&self, 42 | bgfx: &Bgfx, 43 | width: &mut u16, 44 | height: &mut u16, 45 | reset: bgfx::ResetFlags) 46 | -> bool { 47 | let mut should_close = false; 48 | 49 | while let Ok(result) = self.event_rx.try_recv() { 50 | match result { 51 | Event::Close => should_close = true, 52 | Event::Size(w, h) => { 53 | *width = w; 54 | *height = h; 55 | bgfx.reset(w, h, reset); 56 | } 57 | } 58 | } 59 | 60 | should_close 61 | } 62 | 63 | } 64 | 65 | /// Process window events on the render thread. 66 | fn process_events(window: &Window, event_tx: &Sender) -> bool { 67 | let mut should_close = false; 68 | 69 | for event in window.poll_events() { 70 | match event { 71 | glutin::Event::Closed => { 72 | should_close = true; 73 | event_tx.send(Event::Close).unwrap(); 74 | } 75 | glutin::Event::Resized(w, h) => { 76 | event_tx.send(Event::Size(w as u16, h as u16)).unwrap(); 77 | } 78 | _ => {} 79 | } 80 | } 81 | 82 | should_close 83 | } 84 | 85 | /// Loads the contents of a file and returns it. 86 | fn load_file(name: &str) -> Vec { 87 | let mut data = Vec::new(); 88 | let mut file = File::open(name).unwrap(); 89 | file.read_to_end(&mut data).unwrap(); 90 | data 91 | } 92 | 93 | /// Loads the two given shaders from disk, and creates a program containing the loaded shaders. 94 | #[allow(dead_code)] 95 | pub fn load_program<'a, 'b>(bgfx: &'a Bgfx, 96 | vsh_name: &'b str, 97 | fsh_name: &'b str) 98 | -> bgfx::Program<'a> { 99 | let renderer = bgfx.get_renderer_type(); 100 | let exe_path = env::current_exe().unwrap(); 101 | let exe_stem = exe_path.file_stem().unwrap(); 102 | let assets_path = format!("examples/assets/{}", exe_stem.to_str().unwrap()); 103 | let vsh_path = format!("{}/{:?}/{}.bin", assets_path, renderer, vsh_name); 104 | let fsh_path = format!("{}/{:?}/{}.bin", assets_path, renderer, fsh_name); 105 | let vsh_mem = bgfx::Memory::copy(bgfx, &load_file(&vsh_path)); 106 | let fsh_mem = bgfx::Memory::copy(bgfx, &load_file(&fsh_path)); 107 | let vsh = bgfx::Shader::new(vsh_mem); 108 | let fsh = bgfx::Shader::new(fsh_mem); 109 | 110 | bgfx::Program::new(vsh, fsh) 111 | } 112 | 113 | /// Set the platform data to be used by BGFX. 114 | #[cfg(target_os = "linux")] 115 | fn init_bgfx_platform(window: &Window) { 116 | PlatformData::new() 117 | .display(unsafe {window.platform_display() as *mut std::os::raw::c_void }) 118 | .window(unsafe {window.platform_window() as *mut std::os::raw::c_void }) 119 | .apply() 120 | .unwrap(); 121 | } 122 | 123 | /// Set the platform data to be used by BGFX. 124 | #[cfg(not(target_os = "linux"))] 125 | fn init_bgfx_platform(window: &Window) { 126 | PlatformData::new() 127 | .window(unsafe {window.platform_window() as *mut std::os::raw::c_void }) 128 | .apply() 129 | .unwrap(); 130 | } 131 | 132 | pub fn run_example(width: u16, height: u16, main: M) 133 | where M: Send + 'static + FnOnce(EventQueue) 134 | { 135 | let window = WindowBuilder::new() 136 | .with_dimensions(width as u32, height as u32) 137 | .with_gl(GlRequest::Specific(Api::OpenGl, (3, 1))) 138 | .with_title(String::from("BGFX")) 139 | .build() 140 | .expect("Failed to create window"); 141 | 142 | unsafe { 143 | window.make_current().unwrap(); 144 | } 145 | 146 | // Create the channel used for communication between the main and render threads. 147 | let (event_tx, event_rx) = channel::(); 148 | 149 | // Set the platform data for BGFX to use. 150 | init_bgfx_platform(&window); 151 | 152 | // Initialize this thread as the render thread by pumping it once *before* calling bgfx::init. 153 | bgfx::render_frame(); 154 | 155 | // Spawn a new thread to use as the main thread. 156 | let main_thread = thread::spawn(move || { 157 | main(EventQueue { event_rx: event_rx }); 158 | }); 159 | 160 | // Pump window events until the window is closed. 161 | while !process_events(&window, &event_tx) { 162 | bgfx::render_frame(); 163 | } 164 | 165 | // Pump the render thread until the main thread has shut down. 166 | while bgfx::render_frame() != RenderFrame::NoContext { 167 | thread::sleep(Duration::from_millis(1)); 168 | } 169 | 170 | main_thread.join().unwrap(); 171 | } 172 | -------------------------------------------------------------------------------- /bgfx-sys/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | use std::env; 5 | use std::io::Write; 6 | use std::path::PathBuf; 7 | use std::process::{Command, Stdio}; 8 | 9 | fn main() { 10 | let target = env::var("TARGET").unwrap(); 11 | let profile = env::var("PROFILE").unwrap(); 12 | 13 | let first_div = target.find('-').unwrap(); 14 | let last_div = target.rfind('-').unwrap(); 15 | 16 | let arch = &target[..first_div]; 17 | let platform = &target[(first_div + 1)..last_div]; 18 | let compiler = &target[(last_div + 1)..]; 19 | let bitness = if arch == "x86_64" { 64 } else { 32 }; 20 | 21 | match compiler { 22 | "msvc" => build_msvc(bitness), 23 | "gnu" | "darwin" => build_gmake(bitness, &profile, platform), 24 | _ => panic!("Unsupported compiler"), 25 | } 26 | } 27 | 28 | /// Builds the bgfx binaries for `msvc` targets. 29 | fn build_msvc(bitness: u32) { 30 | let vs_version = env::var("VisualStudioVersion").expect("Visual Studio version not detected"); 31 | let platform = if bitness == 32 { "X86" } else { "X64" }; 32 | 33 | let vs_release = match vs_version.as_ref() { 34 | "12.0" => "2013", 35 | "14.0" => "2015", 36 | "15.0" => "2017", 37 | _ => panic!(format!("Unknown Visual Studio version: {:?}", vs_version)), 38 | }; 39 | 40 | Command::new("bx/tools/bin/windows/genie.exe") 41 | .current_dir("bgfx") 42 | .arg("--with-dynamic-runtime") 43 | .arg(format!("vs{}", vs_release)) 44 | .output() 45 | .expect("Failed to generate project files"); 46 | 47 | let status = Command::new("MSBuild.exe") 48 | .current_dir("bgfx") 49 | .arg("/p:Configuration=Release") 50 | .arg(format!("/p:Platform={}", platform)) 51 | .arg(format!(".build/projects/vs{}/bgfx.sln", vs_release)) 52 | .status() 53 | .expect("Failed to build bgfx"); 54 | 55 | if status.code().unwrap() != 0 { 56 | panic!("Failed to build bgfx"); 57 | } 58 | 59 | let mut path = PathBuf::from(env::current_dir().unwrap()); 60 | path.push("bgfx"); 61 | path.push(".build"); 62 | path.push(format!("win{}_vs{}", bitness, vs_release)); 63 | path.push("bin"); 64 | 65 | println!("cargo:rustc-link-lib=static=bxRelease"); 66 | println!("cargo:rustc-link-lib=static=bimgRelease"); 67 | println!("cargo:rustc-link-lib=static=bgfxRelease"); 68 | println!("cargo:rustc-link-lib=gdi32"); 69 | println!("cargo:rustc-link-lib=user32"); 70 | println!("cargo:rustc-link-search=native={}", path.as_os_str().to_str().unwrap()); 71 | } 72 | 73 | /// Builds the bgfx binaries for makefile based targets. 74 | fn build_gmake(bitness: u32, profile: &str, platform: &str) { 75 | let project_name = match platform { 76 | "pc-windows" => "gmake-mingw-gcc", 77 | "unknown-linux" => "gmake-linux", 78 | "apple" => "gmake-osx", 79 | _ => panic!("Unsupported OS"), 80 | }; 81 | 82 | let output_name = match platform { 83 | "pc-windows" => format!("win{}_mingw-gcc", bitness), 84 | "unknown-linux" => format!("linux{}_gcc", bitness), 85 | "apple" => format!("osx{}_clang", bitness), 86 | _ => unreachable!(), 87 | }; 88 | 89 | // Generate makefiles 90 | let status = Command::new("make") 91 | .arg("-C") 92 | .arg("bgfx") 93 | .arg(format!(".build/projects/{}", project_name)) 94 | .status() 95 | .expect("Failed to generate makefiles"); 96 | 97 | if status.code().unwrap() != 0 { 98 | panic!("Failed to generate makefiles."); 99 | } 100 | 101 | // C flags 102 | let cflags = if platform == "pc-windows" && bitness == 32 { 103 | "-fPIC -DBGFX_CONFIG_MULTITHREADED=1 -mincoming-stack-boundary=2" 104 | } else { 105 | "-fPIC -DBGFX_CONFIG_MULTITHREADED=1" 106 | }; 107 | 108 | // Build bgfx 109 | let status = Command::new("make") 110 | .env("CFLAGS", cflags) 111 | .arg("-R") 112 | .arg("-C") 113 | .arg(format!("bgfx/.build/projects/{}", project_name)) 114 | .arg(format!("config={}{}", profile, bitness)) 115 | .arg("verbose=1") 116 | .arg("bgfx") 117 | .status() 118 | .expect("Failed to build bgfx"); 119 | 120 | if status.code().unwrap() != 0 { 121 | panic!("Failed to build bgfx."); 122 | } 123 | 124 | // Build bimg 125 | let status = Command::new("make") 126 | .env("CFLAGS", cflags) 127 | .arg("-R") 128 | .arg("-C") 129 | .arg(format!("bgfx/.build/projects/{}", project_name)) 130 | .arg(format!("config={}{}", profile, bitness)) 131 | .arg("verbose=1") 132 | .arg("bimg") 133 | .status() 134 | .expect("Failed to build bimg"); 135 | 136 | if status.code().unwrap() != 0 { 137 | panic!("Failed to build bimg."); 138 | } 139 | 140 | // Output linker config 141 | let mut path = PathBuf::from(env::current_dir().unwrap()); 142 | path.push("bgfx"); 143 | path.push(".build"); 144 | path.push(output_name); 145 | path.push("bin"); 146 | 147 | let config = if profile == "debug" { "Debug" } else { "Release" }; 148 | println!("cargo:rustc-link-lib=bgfx{}", config); 149 | println!("cargo:rustc-link-lib=bimg{}", config); 150 | println!("cargo:rustc-link-lib=bx{}", config); 151 | println!("cargo:rustc-link-lib=stdc++"); 152 | println!("cargo:rustc-link-search=native={}", path.as_os_str().to_str().unwrap()); 153 | 154 | match platform { 155 | "pc-windows" => { 156 | println!("cargo:rustc-link-lib=gdi32"); 157 | println!("cargo:rustc-link-lib=opengl32"); 158 | println!("cargo:rustc-link-lib=psapi"); 159 | } 160 | "unknown-linux" => { 161 | println!("cargo:rustc-link-lib=GL"); 162 | println!("cargo:rustc-link-lib=X11"); 163 | } 164 | "apple" => { 165 | println!("cargo:rustc-link-lib=framework=Cocoa"); 166 | println!("cargo:rustc-link-lib=framework=QuartzCore"); 167 | println!("cargo:rustc-link-lib=framework=OpenGL"); 168 | 169 | if should_link_metal() { 170 | println!("cargo:rustc-link-lib=framework=Metal"); 171 | } 172 | } 173 | _ => unreachable!(), 174 | } 175 | } 176 | 177 | /// Determines whether we should link with Metal on OSX. The Metal framework 178 | /// is only included starting with OSX 10.11. We do this through the C 179 | /// compiler so we can test the same macro bgfx tests for support with. 180 | fn should_link_metal() -> bool { 181 | let test = "#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__\nv=__ENVIRONMENT_MAC_OS_X_VER\ 182 | SION_MIN_REQUIRED__\n#else\nv=1\n#endif"; 183 | 184 | let mut cc = Command::new("cc") 185 | .arg("-xc") 186 | .arg("-E") 187 | .arg("-") 188 | .stdin(Stdio::piped()) 189 | .stdout(Stdio::piped()) 190 | .spawn() 191 | .unwrap(); 192 | 193 | { 194 | let mut stdin = cc.stdin.take().unwrap(); 195 | stdin.write_fmt(format_args!("{}", test)).unwrap(); 196 | } 197 | 198 | let output = cc.wait_with_output().unwrap(); 199 | let output_str = String::from_utf8(output.stdout).unwrap(); 200 | let ver_line = output_str.lines().find(|l| l.starts_with("v=")).unwrap(); 201 | let ver_str = &ver_line[2..]; 202 | let ver = ver_str.parse::().unwrap(); 203 | 204 | ver >= 101100 205 | } -------------------------------------------------------------------------------- /examples/01-cubes.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | extern crate bgfx; 5 | extern crate cgmath; 6 | extern crate glutin; 7 | extern crate time; 8 | 9 | mod common; 10 | 11 | use bgfx::*; 12 | use cgmath::{Angle, Decomposed, Deg, Matrix4, Point3, Quaternion, Rad, Rotation3, Transform, 13 | Vector3}; 14 | use common::EventQueue; 15 | use time::PreciseTime; 16 | 17 | 18 | #[repr(packed)] 19 | struct PosColorVertex { 20 | _x: f32, 21 | _y: f32, 22 | _z: f32, 23 | _abgr: u32, 24 | } 25 | 26 | impl PosColorVertex { 27 | fn build_decl() -> VertexDecl { 28 | VertexDecl::new(None) 29 | .add(Attrib::Position, 3, AttribType::Float) 30 | .add(Attrib::Color0, 4, AttribType::Uint8(true)) 31 | .end() 32 | } 33 | } 34 | 35 | #[cfg_attr(rustfmt, rustfmt_skip)] 36 | static CUBE_VERTICES: [PosColorVertex; 8] = [ 37 | PosColorVertex { _x: -1.0, _y: 1.0, _z: 1.0, _abgr: 0xff000000 }, 38 | PosColorVertex { _x: 1.0, _y: 1.0, _z: 1.0, _abgr: 0xff0000ff }, 39 | PosColorVertex { _x: -1.0, _y: -1.0, _z: 1.0, _abgr: 0xff00ff00 }, 40 | PosColorVertex { _x: 1.0, _y: -1.0, _z: 1.0, _abgr: 0xff00ffff }, 41 | PosColorVertex { _x: -1.0, _y: 1.0, _z: -1.0, _abgr: 0xffff0000 }, 42 | PosColorVertex { _x: 1.0, _y: 1.0, _z: -1.0, _abgr: 0xffff00ff }, 43 | PosColorVertex { _x: -1.0, _y: -1.0, _z: -1.0, _abgr: 0xffffff00 }, 44 | PosColorVertex { _x: 1.0, _y: -1.0, _z: -1.0, _abgr: 0xffffffff }, 45 | ]; 46 | 47 | #[cfg_attr(rustfmt, rustfmt_skip)] 48 | static CUBE_INDICES: [u16; 36] = [ 49 | 0, 1, 2, // 0 50 | 1, 3, 2, 51 | 4, 6, 5, // 2 52 | 5, 6, 7, 53 | 0, 2, 4, // 4 54 | 4, 2, 6, 55 | 1, 5, 3, // 6 56 | 5, 7, 3, 57 | 0, 4, 1, // 8 58 | 4, 5, 1, 59 | 2, 3, 6, // 10 60 | 6, 3, 7, 61 | ]; 62 | 63 | struct Cubes<'a> { 64 | bgfx: &'a Bgfx, 65 | events: EventQueue, 66 | width: u16, 67 | height: u16, 68 | debug: DebugFlags, 69 | reset: ResetFlags, 70 | vbh: Option>, 71 | ibh: Option>, 72 | program: Option>, 73 | time: Option, 74 | last: Option, 75 | } 76 | 77 | impl<'a> Cubes<'a> { 78 | 79 | #[inline] 80 | fn new(bgfx: &'a Bgfx, events: EventQueue) -> Cubes<'a> { 81 | Cubes { 82 | bgfx: bgfx, 83 | events: events, 84 | width: 0, 85 | height: 0, 86 | debug: DEBUG_NONE, 87 | reset: RESET_NONE, 88 | vbh: None, 89 | ibh: None, 90 | program: None, 91 | time: None, 92 | last: None, 93 | } 94 | } 95 | 96 | fn init(&mut self) { 97 | self.width = 1280; 98 | self.height = 720; 99 | self.debug = DEBUG_TEXT; 100 | self.reset = RESET_VSYNC; 101 | 102 | // This is where the C++ example would call bgfx::init(). In rust we move that out of this 103 | // object due to lifetimes: The Cubes type cannot own both the Bgfx object, and guarantee 104 | // that its members are destroyed before the Bgfx object. 105 | self.bgfx.reset(self.width, self.height, self.reset); 106 | 107 | // Enable debug text. 108 | self.bgfx.set_debug(self.debug); 109 | 110 | // Set view 0 clear state. 111 | let clear_flags = CLEAR_COLOR | CLEAR_DEPTH; 112 | self.bgfx.set_view_clear(0, clear_flags, 0x303030ff, 1.0_f32, 0); 113 | 114 | // Create vertex stream declaration 115 | let decl = PosColorVertex::build_decl(); 116 | 117 | // Create static vertex buffer. 118 | self.vbh = Some(VertexBuffer::new(Memory::reference(self.bgfx, &CUBE_VERTICES), 119 | &decl, 120 | BUFFER_NONE)); 121 | 122 | // Create static index buffer. 123 | self.ibh = Some(IndexBuffer::new(Memory::reference(self.bgfx, &CUBE_INDICES), BUFFER_NONE)); 124 | 125 | // Create program from shaders. 126 | self.program = Some(common::load_program(&self.bgfx, "vs_cubes", "fs_cubes")); 127 | 128 | self.time = Some(PreciseTime::now()); 129 | } 130 | 131 | fn shutdown(&mut self) { 132 | // We don't really need to do anything here, the objects will clean themselves up once they 133 | // go out of scope. This function is really only here to keep the examples similar in 134 | // structure to the C++ examples. 135 | } 136 | 137 | fn update(&mut self) -> bool { 138 | if !self.events.handle_events(&self.bgfx, &mut self.width, &mut self.height, self.reset) { 139 | let now = PreciseTime::now(); 140 | let frame_time = self.last.unwrap_or(now).to(now); 141 | self.last = Some(now); 142 | 143 | let time = (self.time.unwrap().to(now).num_microseconds().unwrap() as f64) / 144 | 1_000_000.0_f64; 145 | 146 | // Use debug font to print information about this example. 147 | let frame_info = format!("Frame: {:7.3}[ms]", frame_time.num_milliseconds()); 148 | self.bgfx.dbg_text_clear(None, None); 149 | self.bgfx.dbg_text_print(0, 1, 0x4f, "examples/01-cubes.rs"); 150 | self.bgfx.dbg_text_print(0, 2, 0x6f, "Description: Rendering simple static mesh."); 151 | self.bgfx.dbg_text_print(0, 3, 0x0f, &frame_info); 152 | 153 | let at = Point3::new(0.0, 0.0, 0.0); 154 | let eye = Point3::new(0.0, 0.0, -35.0); 155 | let up = Vector3::new(0.0, 1.0, 0.0); 156 | 157 | // TODO: Support for HMD rendering 158 | 159 | // Set view and projection matrix for view 0. 160 | let aspect = (self.width as f32) / (self.height as f32); 161 | let view = Matrix4::look_at(eye, at, up); 162 | let proj = cgmath::perspective(Deg::new(60.0), aspect, 0.1, 100.0); 163 | self.bgfx.set_view_transform(0, view.as_ref(), proj.as_ref()); 164 | 165 | // Set view 0 default viewport. 166 | self.bgfx.set_view_rect(0, 0, 0, self.width, self.height); 167 | 168 | // This dummy draw call is here to make sure that view 0 is cleared if no other draw 169 | // calls are submitted to view 0. 170 | self.bgfx.touch(0); 171 | 172 | // Submit 11x11 cubes 173 | for yy in 0..11 { 174 | for xx in 0..11 { 175 | let mut modifier = Decomposed::one(); 176 | modifier.rot = Quaternion::from_euler(Rad::new((time / 0.21) as f32), 177 | Rad::new((time / 0.37) as f32), 178 | Rad::new(0.0)); 179 | modifier.disp = Vector3::new(-15.0 + (xx as f32) * 3.0, 180 | -15.0 + (yy as f32) * 3.0, 181 | 0.0); 182 | let mtx = Matrix4::from(modifier); 183 | 184 | // Set model matrix for rendering. 185 | self.bgfx.set_transform(mtx.as_ref()); 186 | 187 | // Set vertex and index buffer. 188 | self.bgfx.set_vertex_buffer(0, self.vbh.as_ref().unwrap()); 189 | self.bgfx.set_index_buffer(self.ibh.as_ref().unwrap()); 190 | 191 | // Set render states. 192 | self.bgfx.set_state(STATE_DEFAULT, None); 193 | 194 | // Submit primitive for rendering to view 0. 195 | self.bgfx.submit(0, self.program.as_ref().unwrap(), false); 196 | } 197 | } 198 | 199 | // Advance to next frame. Rendering thread will be kicked to process submitted 200 | // rendering primitives. 201 | self.bgfx.frame(false); 202 | 203 | true 204 | } else { 205 | false 206 | } 207 | } 208 | } 209 | 210 | fn example(events: EventQueue) { 211 | let bgfx = bgfx::init(RendererType::Default, None, None).unwrap(); 212 | let mut cubes = Cubes::new(&bgfx, events); 213 | cubes.init(); 214 | while cubes.update() {} 215 | cubes.shutdown(); 216 | } 217 | 218 | fn main() { 219 | common::run_example(1280, 720, example); 220 | } 221 | -------------------------------------------------------------------------------- /bgfx-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | //! Raw FFI bgfx bindings. 5 | 6 | #![allow(non_camel_case_types)] 7 | #![allow(non_snake_case)] 8 | #![allow(non_upper_case_globals)] 9 | 10 | extern crate libc; 11 | 12 | pub type size_t = ::libc::size_t; 13 | pub type int32_t = i32; 14 | pub type uint8_t = u8; 15 | pub type uint16_t = u16; 16 | pub type uint32_t = u32; 17 | pub type uint64_t = u64; 18 | 19 | include!("ffi_bgfx.rs"); 20 | 21 | pub const BGFX_PCI_ID_NONE: u16 = 0x0000; 22 | pub const BGFX_PCI_ID_SOFTWARE_RASTERIZER: u16 = 0x0001; 23 | pub const BGFX_PCI_ID_AMD: u16 = 0x1002; 24 | pub const BGFX_PCI_ID_INTEL: u16 = 0x8086; 25 | pub const BGFX_PCI_ID_NVIDIA: u16 = 0x10de; 26 | 27 | // Clear flags 28 | 29 | pub const BGFX_CLEAR_NONE: u16 = 0x0000; 30 | pub const BGFX_CLEAR_COLOR: u16 = 0x0001; 31 | pub const BGFX_CLEAR_DEPTH: u16 = 0x0002; 32 | pub const BGFX_CLEAR_STENCIL: u16 = 0x0004; 33 | pub const BGFX_CLEAR_DISCARD_COLOR_0: u16 = 0x0008; 34 | pub const BGFX_CLEAR_DISCARD_COLOR_1: u16 = 0x0010; 35 | pub const BGFX_CLEAR_DISCARD_COLOR_2: u16 = 0x0020; 36 | pub const BGFX_CLEAR_DISCARD_COLOR_3: u16 = 0x0040; 37 | pub const BGFX_CLEAR_DISCARD_COLOR_4: u16 = 0x0080; 38 | pub const BGFX_CLEAR_DISCARD_COLOR_5: u16 = 0x0100; 39 | pub const BGFX_CLEAR_DISCARD_COLOR_6: u16 = 0x0200; 40 | pub const BGFX_CLEAR_DISCARD_COLOR_7: u16 = 0x0400; 41 | pub const BGFX_CLEAR_DISCARD_DEPTH: u16 = 0x0800; 42 | pub const BGFX_CLEAR_DISCARD_STENCIL: u16 = 0x1000; 43 | 44 | pub const BGFX_CLEAR_DISCARD_COLOR_MASK: u16 = 45 | ( 46 | BGFX_CLEAR_DISCARD_COLOR_0 | 47 | BGFX_CLEAR_DISCARD_COLOR_1 | 48 | BGFX_CLEAR_DISCARD_COLOR_2 | 49 | BGFX_CLEAR_DISCARD_COLOR_3 | 50 | BGFX_CLEAR_DISCARD_COLOR_4 | 51 | BGFX_CLEAR_DISCARD_COLOR_5 | 52 | BGFX_CLEAR_DISCARD_COLOR_6 | 53 | BGFX_CLEAR_DISCARD_COLOR_7 54 | ); 55 | 56 | pub const BGFX_CLEAR_DISCARD_MASK: u16 = 57 | ( 58 | BGFX_CLEAR_DISCARD_COLOR_MASK | 59 | BGFX_CLEAR_DISCARD_DEPTH | 60 | BGFX_CLEAR_DISCARD_STENCIL 61 | ); 62 | 63 | // Debug flags 64 | 65 | pub const BGFX_DEBUG_NONE: u32 = 0x00000000; 66 | pub const BGFX_DEBUG_WIREFRAME: u32 = 0x00000001; 67 | pub const BGFX_DEBUG_IFH: u32 = 0x00000002; 68 | pub const BGFX_DEBUG_STATS: u32 = 0x00000004; 69 | pub const BGFX_DEBUG_TEXT: u32 = 0x00000008; 70 | 71 | // Reset flags 72 | 73 | pub const BGFX_RESET_NONE: u32 = 0x00000000; 74 | pub const BGFX_RESET_FULLSCREEN: u32 = 0x00000001; 75 | pub const BGFX_RESET_FULLSCREEN_MASK: u32 = 0x00000001; 76 | pub const BGFX_RESET_MSAA_X2: u32 = 0x00000010; 77 | pub const BGFX_RESET_MSAA_X4: u32 = 0x00000020; 78 | pub const BGFX_RESET_MSAA_X8: u32 = 0x00000030; 79 | pub const BGFX_RESET_MSAA_X16: u32 = 0x00000040; 80 | pub const BGFX_RESET_MSAA_MASK: u32 = 0x00000070; 81 | pub const BGFX_RESET_VSYNC: u32 = 0x00000080; 82 | pub const BGFX_RESET_MAXANISOTROPY: u32 = 0x00000100; 83 | pub const BGFX_RESET_CAPTURE: u32 = 0x00000200; 84 | pub const BGFX_RESET_HMD: u32 = 0x00000400; 85 | pub const BGFX_RESET_HMD_DEBUG: u32 = 0x00000800; 86 | pub const BGFX_RESET_HMD_RECENTER: u32 = 0x00001000; 87 | pub const BGFX_RESET_FLUSH_AFTER_RENDER: u32 = 0x00002000; 88 | pub const BGFX_RESET_FLIP_AFTER_RENDER: u32 = 0x00004000; 89 | pub const BGFX_RESET_SRGB_BACKBUFFER: u32 = 0x00008000; 90 | pub const BGFX_RESET_HIDPI: u32 = 0x00010000; 91 | 92 | // Buffer flags 93 | 94 | pub const BGFX_BUFFER_NONE: u16 = 0x0000; 95 | pub const BGFX_BUFFER_COMPUTE_FORMAT_8X1: u16 = 0x0001; 96 | pub const BGFX_BUFFER_COMPUTE_FORMAT_8X2: u16 = 0x0002; 97 | pub const BGFX_BUFFER_COMPUTE_FORMAT_8X4: u16 = 0x0003; 98 | pub const BGFX_BUFFER_COMPUTE_FORMAT_16X1: u16 = 0x0004; 99 | pub const BGFX_BUFFER_COMPUTE_FORMAT_16X2: u16 = 0x0005; 100 | pub const BGFX_BUFFER_COMPUTE_FORMAT_16X4: u16 = 0x0006; 101 | pub const BGFX_BUFFER_COMPUTE_FORMAT_32X1: u16 = 0x0007; 102 | pub const BGFX_BUFFER_COMPUTE_FORMAT_32X2: u16 = 0x0008; 103 | pub const BGFX_BUFFER_COMPUTE_FORMAT_32X4: u16 = 0x0009; 104 | pub const BGFX_BUFFER_COMPUTE_FORMAT_MASK: u16 = 0x000f; 105 | pub const BGFX_BUFFER_COMPUTE_TYPE_UINT: u16 = 0x0010; 106 | pub const BGFX_BUFFER_COMPUTE_TYPE_INT: u16 = 0x0020; 107 | pub const BGFX_BUFFER_COMPUTE_TYPE_FLOAT: u16 = 0x0030; 108 | pub const BGFX_BUFFER_COMPUTE_TYPE_MASK: u16 = 0x0030; 109 | pub const BGFX_BUFFER_COMPUTE_READ: u16 = 0x0100; 110 | pub const BGFX_BUFFER_COMPUTE_WRITE: u16 = 0x0200; 111 | pub const BGFX_BUFFER_DRAW_INDIRECT: u16 = 0x0400; 112 | pub const BGFX_BUFFER_ALLOW_RESIZE: u16 = 0x0800; 113 | pub const BGFX_BUFFER_INDEX32: u16 = 0x1000; 114 | 115 | pub const BGFX_BUFFER_COMPUTE_READ_WRITE: u16 = 116 | ( 117 | BGFX_BUFFER_COMPUTE_READ | 118 | BGFX_BUFFER_COMPUTE_WRITE 119 | ); 120 | 121 | // State flags 122 | 123 | pub const BGFX_STATE_RGB_WRITE: u64 = 0x0000000000000001_u64; 124 | pub const BGFX_STATE_ALPHA_WRITE: u64 = 0x0000000000000002_u64; 125 | pub const BGFX_STATE_DEPTH_WRITE: u64 = 0x0000000000000004_u64; 126 | pub const BGFX_STATE_DEPTH_TEST_LESS: u64 = 0x0000000000000010_u64; 127 | pub const BGFX_STATE_DEPTH_TEST_LEQUAL: u64 = 0x0000000000000020_u64; 128 | pub const BGFX_STATE_DEPTH_TEST_EQUAL: u64 = 0x0000000000000030_u64; 129 | pub const BGFX_STATE_DEPTH_TEST_GEQUAL: u64 = 0x0000000000000040_u64; 130 | pub const BGFX_STATE_DEPTH_TEST_GREATER: u64 = 0x0000000000000050_u64; 131 | pub const BGFX_STATE_DEPTH_TEST_NOTEQUAL: u64 = 0x0000000000000060_u64; 132 | pub const BGFX_STATE_DEPTH_TEST_NEVER: u64 = 0x0000000000000070_u64; 133 | pub const BGFX_STATE_DEPTH_TEST_ALWAYS: u64 = 0x0000000000000080_u64; 134 | pub const BGFX_STATE_DEPTH_TEST_MASK: u64 = 0x00000000000000f0_u64; 135 | pub const BGFX_STATE_BLEND_ZERO: u64 = 0x0000000000001000_u64; 136 | pub const BGFX_STATE_BLEND_ONE: u64 = 0x0000000000002000_u64; 137 | pub const BGFX_STATE_BLEND_SRC_COLOR: u64 = 0x0000000000003000_u64; 138 | pub const BGFX_STATE_BLEND_INV_SRC_COLOR: u64 = 0x0000000000004000_u64; 139 | pub const BGFX_STATE_BLEND_SRC_ALPHA: u64 = 0x0000000000005000_u64; 140 | pub const BGFX_STATE_BLEND_INV_SRC_ALPHA: u64 = 0x0000000000006000_u64; 141 | pub const BGFX_STATE_BLEND_DST_ALPHA: u64 = 0x0000000000007000_u64; 142 | pub const BGFX_STATE_BLEND_INV_DST_ALPHA: u64 = 0x0000000000008000_u64; 143 | pub const BGFX_STATE_BLEND_DST_COLOR: u64 = 0x0000000000009000_u64; 144 | pub const BGFX_STATE_BLEND_INV_DST_COLOR: u64 = 0x000000000000a000_u64; 145 | pub const BGFX_STATE_BLEND_SRC_ALPHA_SAT: u64 = 0x000000000000b000_u64; 146 | pub const BGFX_STATE_BLEND_FACTOR: u64 = 0x000000000000c000_u64; 147 | pub const BGFX_STATE_BLEND_INV_FACTOR: u64 = 0x000000000000d000_u64; 148 | pub const BGFX_STATE_BLEND_MASK: u64 = 0x000000000ffff000_u64; 149 | pub const BGFX_STATE_BLEND_EQUATION_ADD: u64 = 0x0000000000000000_u64; 150 | pub const BGFX_STATE_BLEND_EQUATION_SUB: u64 = 0x0000000010000000_u64; 151 | pub const BGFX_STATE_BLEND_EQUATION_REVSUB: u64 = 0x0000000020000000_u64; 152 | pub const BGFX_STATE_BLEND_EQUATION_MIN: u64 = 0x0000000030000000_u64; 153 | pub const BGFX_STATE_BLEND_EQUATION_MAX: u64 = 0x0000000040000000_u64; 154 | pub const BGFX_STATE_BLEND_EQUATION_MASK: u64 = 0x00000003f0000000_u64; 155 | pub const BGFX_STATE_BLEND_INDEPENDENT: u64 = 0x0000000400000000_u64; 156 | pub const BGFX_STATE_CULL_CW: u64 = 0x0000001000000000_u64; 157 | pub const BGFX_STATE_CULL_CCW: u64 = 0x0000002000000000_u64; 158 | pub const BGFX_STATE_CULL_MASK: u64 = 0x0000003000000000_u64; 159 | pub const BGFX_STATE_ALPHA_REF_MASK: u64 = 0x0000ff0000000000_u64; 160 | pub const BGFX_STATE_PT_TRISTRIP: u64 = 0x0001000000000000_u64; 161 | pub const BGFX_STATE_PT_LINES: u64 = 0x0002000000000000_u64; 162 | pub const BGFX_STATE_PT_LINESTRIP: u64 = 0x0003000000000000_u64; 163 | pub const BGFX_STATE_PT_POINTS: u64 = 0x0004000000000000_u64; 164 | pub const BGFX_STATE_PT_MASK: u64 = 0x0007000000000000_u64; 165 | pub const BGFX_STATE_POINT_SIZE_MASK: u64 = 0x0ff0000000000000_u64; 166 | pub const BGFX_STATE_MSAA: u64 = 0x1000000000000000_u64; 167 | pub const BGFX_STATE_RESERVED_MASK: u64 = 0xe000000000000000_u64; 168 | pub const BGFX_STATE_NONE: u64 = 0x0000000000000000_u64; 169 | pub const BGFX_STATE_MASK: u64 = 0xffffffffffffffff_u64; 170 | 171 | pub const BGFX_STATE_DEFAULT: u64 = 172 | ( 173 | BGFX_STATE_RGB_WRITE | 174 | BGFX_STATE_ALPHA_WRITE | 175 | BGFX_STATE_DEPTH_TEST_LESS | 176 | BGFX_STATE_DEPTH_WRITE | 177 | BGFX_STATE_CULL_CW | 178 | BGFX_STATE_MSAA 179 | ); 180 | 181 | #[macro_export] 182 | macro_rules! BGFX_STATE_ALPHA_REF { 183 | ($aref:expr) => ((($aref as u64) << bgfx_sys::BGFX_STATE_ALPHA_REF_SHIFT) & bgfx_sys::BGFX_STATE_ALPHA_REF_MASK) 184 | } 185 | 186 | #[macro_export] 187 | macro_rules! BGFX_STATE_POINT_SIZE { 188 | ($size:expr) => ((($size as u64) << bgfx_sys::BGFX_STATE_POINT_SIZE_SHIFT) & bgfx_sys::BGFX_STATE_POINT_SIZE_MASK) 189 | } 190 | 191 | #[macro_export] 192 | macro_rules! BGFX_STATE_BLEND_FUNC_SEPARATE { 193 | ($srcrgb:expr, $dstrgb:expr, $srca:expr, $dsta:expr) => ( 194 | ($srcrgb as u64) | (($dstrgb as u64) << 4) | (($srca as u64) << 8) | (($dsta as u64) << 12) 195 | ); 196 | } 197 | 198 | #[macro_export] 199 | macro_rules! BGFX_STATE_BLEND_EQUATION_SEPARATE { 200 | ($rgb:expr, $a:expr) => (($rgb as u64) | (($a as u64) << 3)) 201 | } 202 | 203 | #[macro_export] 204 | macro_rules! BGFX_STATE_BLEND_FUNC { 205 | ($src:expr, $dst:expr) => (BGFX_STATE_BLEND_FUNC_SEPARATE!($src, $dst, $src, $dst)) 206 | } 207 | 208 | #[macro_export] 209 | macro_rules! BGFX_STATE_BLEND_EQUATION { 210 | ($equation:expr) => (BGFX_STATE_BLEND_EQUATION_SEPARATE!($equation, $equation)) 211 | } 212 | 213 | pub const BGFX_STATE_BLEND_ADD: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE ) ); 214 | pub const BGFX_STATE_BLEND_ALPHA: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); 215 | pub const BGFX_STATE_BLEND_DARKEN: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE ) | BGFX_STATE_BLEND_EQUATION!(BGFX_STATE_BLEND_EQUATION_MIN) ); 216 | pub const BGFX_STATE_BLEND_LIGHTEN: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE ) | BGFX_STATE_BLEND_EQUATION!(BGFX_STATE_BLEND_EQUATION_MAX) ); 217 | pub const BGFX_STATE_BLEND_MULTIPLY: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO ) ); 218 | pub const BGFX_STATE_BLEND_NORMAL: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); 219 | pub const BGFX_STATE_BLEND_SCREEN: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_COLOR) ); 220 | pub const BGFX_STATE_BLEND_LINEAR_BURN: u64 = (BGFX_STATE_BLEND_FUNC!(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_INV_DST_COLOR) | BGFX_STATE_BLEND_EQUATION!(BGFX_STATE_BLEND_EQUATION_SUB) ); 221 | 222 | #[macro_export] 223 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_x { 224 | ($src:expr, $dst:expr) => ( 225 | (($src >> bgfx_sys::BGFX_STATE_BLEND_SHIFT) as u32) | ((($dst >> bgfx_sys::BGFX_STATE_BLEND_SHIFT) as u32) << 4) 226 | ); 227 | } 228 | 229 | #[macro_export] 230 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_xE { 231 | ($src:expr, $dst:expr, $equation:expr) => ( 232 | BGFX_STATE_BLEND_FUNC_RT_x!($src, $dst) | ((($equation >> bgfx_sys::BGFX_STATE_BLEND_EQUATION_SHIFT) as u32) << 8) 233 | ); 234 | } 235 | 236 | #[macro_export] 237 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_1 { 238 | ($src:expr, $dst:expr) => (BGFX_STATE_BLEND_FUNC_RT_x!($src, $dst)) 239 | } 240 | 241 | #[macro_export] 242 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_2 { 243 | ($src:expr, $dst:expr) => (BGFX_STATE_BLEND_FUNC_RT_x!($src, $dst) << 11) 244 | } 245 | 246 | #[macro_export] 247 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_3 { 248 | ($src:expr, $dst:expr) => (BGFX_STATE_BLEND_FUNC_RT_x!($src, $dst) << 22) 249 | } 250 | 251 | #[macro_export] 252 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_1E { 253 | ($src:expr, $dst:expr, $equation:expr) => (BGFX_STATE_BLEND_FUNC_RT_xE!($src, $dst, $equation)) 254 | } 255 | 256 | #[macro_export] 257 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_2E { 258 | ($src:expr, $dst:expr, $equation:expr) => (BGFX_STATE_BLEND_FUNC_RT_xE!($src, $dst, $equation) << 11) 259 | } 260 | 261 | #[macro_export] 262 | macro_rules! BGFX_STATE_BLEND_FUNC_RT_3E { 263 | ($src:expr, $dst:expr, $equation:expr) => (BGFX_STATE_BLEND_FUNC_RT_xE!($src, $dst, $equation) << 22) 264 | } 265 | -------------------------------------------------------------------------------- /src/flags.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | extern crate bgfx_sys; 5 | 6 | bitflags! { 7 | flags StateFlags: u64 { 8 | const STATE_RGB_WRITE = bgfx_sys::BGFX_STATE_RGB_WRITE, 9 | const STATE_ALPHA_WRITE = bgfx_sys::BGFX_STATE_ALPHA_WRITE, 10 | const STATE_DEPTH_WRITE = bgfx_sys::BGFX_STATE_DEPTH_WRITE, 11 | const STATE_DEPTH_TEST_LESS = bgfx_sys::BGFX_STATE_DEPTH_TEST_LESS, 12 | const STATE_DEPTH_TEST_LEQUAL = bgfx_sys::BGFX_STATE_DEPTH_TEST_LEQUAL, 13 | const STATE_DEPTH_TEST_EQUAL = bgfx_sys::BGFX_STATE_DEPTH_TEST_EQUAL, 14 | const STATE_DEPTH_TEST_GEQUAL = bgfx_sys::BGFX_STATE_DEPTH_TEST_GEQUAL, 15 | const STATE_DEPTH_TEST_GREATER = bgfx_sys::BGFX_STATE_DEPTH_TEST_GREATER, 16 | const STATE_DEPTH_TEST_NOTEQUAL = bgfx_sys::BGFX_STATE_DEPTH_TEST_NOTEQUAL, 17 | const STATE_DEPTH_TEST_NEVER = bgfx_sys::BGFX_STATE_DEPTH_TEST_NEVER, 18 | const STATE_DEPTH_TEST_ALWAYS = bgfx_sys::BGFX_STATE_DEPTH_TEST_ALWAYS, 19 | const STATE_DEPTH_TEST_SHIFT = bgfx_sys::BGFX_STATE_DEPTH_TEST_SHIFT as u64, 20 | const STATE_DEPTH_TEST_MASK = bgfx_sys::BGFX_STATE_DEPTH_TEST_MASK, 21 | const STATE_BLEND_ZERO = bgfx_sys::BGFX_STATE_BLEND_ZERO, 22 | const STATE_BLEND_ONE = bgfx_sys::BGFX_STATE_BLEND_ONE, 23 | const STATE_BLEND_SRC_COLOR = bgfx_sys::BGFX_STATE_BLEND_SRC_COLOR, 24 | const STATE_BLEND_INV_SRC_COLOR = bgfx_sys::BGFX_STATE_BLEND_INV_SRC_COLOR, 25 | const STATE_BLEND_SRC_ALPHA = bgfx_sys::BGFX_STATE_BLEND_SRC_ALPHA, 26 | const STATE_BLEND_INV_SRC_ALPHA = bgfx_sys::BGFX_STATE_BLEND_INV_SRC_ALPHA, 27 | const STATE_BLEND_DST_ALPHA = bgfx_sys::BGFX_STATE_BLEND_DST_ALPHA, 28 | const STATE_BLEND_INV_DST_ALPHA = bgfx_sys::BGFX_STATE_BLEND_INV_DST_ALPHA, 29 | const STATE_BLEND_DST_COLOR = bgfx_sys::BGFX_STATE_BLEND_DST_COLOR, 30 | const STATE_BLEND_INV_DST_COLOR = bgfx_sys::BGFX_STATE_BLEND_INV_DST_COLOR, 31 | const STATE_BLEND_SRC_ALPHA_SAT = bgfx_sys::BGFX_STATE_BLEND_SRC_ALPHA_SAT, 32 | const STATE_BLEND_FACTOR = bgfx_sys::BGFX_STATE_BLEND_FACTOR, 33 | const STATE_BLEND_INV_FACTOR = bgfx_sys::BGFX_STATE_BLEND_INV_FACTOR, 34 | const STATE_BLEND_SHIFT = bgfx_sys::BGFX_STATE_BLEND_SHIFT as u64, 35 | const STATE_BLEND_MASK = bgfx_sys::BGFX_STATE_BLEND_MASK, 36 | const STATE_BLEND_EQUATION_ADD = bgfx_sys::BGFX_STATE_BLEND_EQUATION_ADD, 37 | const STATE_BLEND_EQUATION_SUB = bgfx_sys::BGFX_STATE_BLEND_EQUATION_SUB, 38 | const STATE_BLEND_EQUATION_REVSUB = bgfx_sys::BGFX_STATE_BLEND_EQUATION_REVSUB, 39 | const STATE_BLEND_EQUATION_MIN = bgfx_sys::BGFX_STATE_BLEND_EQUATION_MIN, 40 | const STATE_BLEND_EQUATION_MAX = bgfx_sys::BGFX_STATE_BLEND_EQUATION_MAX, 41 | const STATE_BLEND_EQUATION_SHIFT = bgfx_sys::BGFX_STATE_BLEND_EQUATION_SHIFT as u64, 42 | const STATE_BLEND_EQUATION_MASK = bgfx_sys::BGFX_STATE_BLEND_EQUATION_MASK, 43 | const STATE_BLEND_INDEPENDENT = bgfx_sys::BGFX_STATE_BLEND_INDEPENDENT, 44 | const STATE_CULL_CW = bgfx_sys::BGFX_STATE_CULL_CW, 45 | const STATE_CULL_CCW = bgfx_sys::BGFX_STATE_CULL_CCW, 46 | const STATE_CULL_SHIFT = bgfx_sys::BGFX_STATE_CULL_SHIFT as u64, 47 | const STATE_CULL_MASK = bgfx_sys::BGFX_STATE_CULL_MASK, 48 | const STATE_ALPHA_REF_SHIFT = bgfx_sys::BGFX_STATE_ALPHA_REF_SHIFT as u64, 49 | const STATE_ALPHA_REF_MASK = bgfx_sys::BGFX_STATE_ALPHA_REF_MASK, 50 | const STATE_PT_TRISTRIP = bgfx_sys::BGFX_STATE_PT_TRISTRIP, 51 | const STATE_PT_LINES = bgfx_sys::BGFX_STATE_PT_LINES, 52 | const STATE_PT_LINESTRIP = bgfx_sys::BGFX_STATE_PT_LINESTRIP, 53 | const STATE_PT_POINTS = bgfx_sys::BGFX_STATE_PT_POINTS, 54 | const STATE_PT_SHIFT = bgfx_sys::BGFX_STATE_PT_SHIFT as u64, 55 | const STATE_PT_MASK = bgfx_sys::BGFX_STATE_PT_MASK, 56 | const STATE_POINT_SIZE_SHIFT = bgfx_sys::BGFX_STATE_POINT_SIZE_SHIFT as u64, 57 | const STATE_POINT_SIZE_MASK = bgfx_sys::BGFX_STATE_POINT_SIZE_MASK, 58 | const STATE_MSAA = bgfx_sys::BGFX_STATE_MSAA, 59 | const STATE_RESERVED_MASK = bgfx_sys::BGFX_STATE_RESERVED_MASK, 60 | const STATE_NONE = bgfx_sys::BGFX_STATE_NONE, 61 | const STATE_MASK = bgfx_sys::BGFX_STATE_MASK, 62 | const STATE_DEFAULT = bgfx_sys::BGFX_STATE_DEFAULT, 63 | const STATE_BLEND_ADD = bgfx_sys::BGFX_STATE_BLEND_ADD, 64 | const STATE_BLEND_ALPHA = bgfx_sys::BGFX_STATE_BLEND_ALPHA, 65 | const STATE_BLEND_DARKEN = bgfx_sys::BGFX_STATE_BLEND_DARKEN, 66 | const STATE_BLEND_LIGHTEN = bgfx_sys::BGFX_STATE_BLEND_LIGHTEN, 67 | const STATE_BLEND_MULTIPLY = bgfx_sys::BGFX_STATE_BLEND_MULTIPLY, 68 | const STATE_BLEND_NORMAL = bgfx_sys::BGFX_STATE_BLEND_NORMAL, 69 | const STATE_BLEND_SCREEN = bgfx_sys::BGFX_STATE_BLEND_SCREEN, 70 | const STATE_BLEND_LINEAR_BURN = bgfx_sys::BGFX_STATE_BLEND_LINEAR_BURN, 71 | } 72 | } 73 | 74 | impl Default for StateFlags { 75 | #[inline] 76 | fn default() -> StateFlags { 77 | STATE_DEFAULT 78 | } 79 | } 80 | 81 | #[inline] 82 | pub fn state_alpha_ref(aref: u8) -> StateFlags { 83 | StateFlags::from_bits(BGFX_STATE_ALPHA_REF!(aref)).unwrap() 84 | } 85 | 86 | #[inline] 87 | pub fn state_point_size(size: u8) -> StateFlags { 88 | StateFlags::from_bits(BGFX_STATE_POINT_SIZE!(size)).unwrap() 89 | } 90 | 91 | #[inline] 92 | pub fn state_blend_func_separate(srcrgb: u32, dstrgb: u32, srca: u8, dsta: u8) -> StateFlags { 93 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_SEPARATE!(srcrgb, dstrgb, srca, dsta)).unwrap() 94 | } 95 | 96 | #[inline] 97 | pub fn state_blend_equation_separate(rgb: u32, a: u8) -> StateFlags { 98 | StateFlags::from_bits(BGFX_STATE_BLEND_EQUATION_SEPARATE!(rgb, a)).unwrap() 99 | } 100 | 101 | #[inline] 102 | pub fn state_blend_func(src: u32, dst: u32) -> StateFlags { 103 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_SEPARATE!(src, dst, src, dst)).unwrap() 104 | } 105 | 106 | #[inline] 107 | pub fn state_blend_equation(equation: u32) -> StateFlags { 108 | StateFlags::from_bits(BGFX_STATE_BLEND_EQUATION_SEPARATE!(equation, equation)).unwrap() 109 | } 110 | 111 | #[inline] 112 | pub fn state_blend_func_rt_x(src: u32, dst: u32) -> StateFlags { 113 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_x!(src, dst) as u64).unwrap() 114 | } 115 | 116 | #[inline] 117 | pub fn state_blend_func_rt_xe(src: u32, dst: u32, equation: u64) -> StateFlags { 118 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_xE!(src, dst, equation) as u64).unwrap() 119 | } 120 | 121 | #[inline] 122 | pub fn state_blend_func_rt_1(src: u32, dst: u32) -> StateFlags { 123 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_1!(src, dst) as u64).unwrap() 124 | } 125 | 126 | #[inline] 127 | pub fn state_blend_func_rt_2(src: u32, dst: u32) -> StateFlags { 128 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_2!(src, dst) as u64).unwrap() 129 | } 130 | 131 | #[inline] 132 | pub fn state_blend_func_rt_3(src: u32, dst: u32) -> StateFlags { 133 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_3!(src, dst) as u64).unwrap() 134 | } 135 | 136 | #[inline] 137 | pub fn state_blend_func_rt_1e(src: u32, dst: u32, equation: u64) -> StateFlags { 138 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_1E!(src, dst, equation) as u64).unwrap() 139 | } 140 | 141 | #[inline] 142 | pub fn state_blend_func_rt_2e(src: u32, dst: u32, equation: u64) -> StateFlags { 143 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_2E!(src, dst, equation) as u64).unwrap() 144 | } 145 | 146 | #[inline] 147 | pub fn state_blend_func_rt_3e(src: u32, dst: u32, equation: u64) -> StateFlags { 148 | StateFlags::from_bits(BGFX_STATE_BLEND_FUNC_RT_3E!(src, dst, equation) as u64).unwrap() 149 | } 150 | 151 | bitflags! { 152 | flags BufferFlags: u16 { 153 | const BUFFER_NONE = bgfx_sys::BGFX_BUFFER_NONE, 154 | const BUFFER_COMPUTE_FORMAT_8X1 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_8X1, 155 | const BUFFER_COMPUTE_FORMAT_8X2 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_8X2, 156 | const BUFFER_COMPUTE_FORMAT_8X4 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_8X4, 157 | const BUFFER_COMPUTE_FORMAT_16X1 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_16X1, 158 | const BUFFER_COMPUTE_FORMAT_16X2 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_16X2, 159 | const BUFFER_COMPUTE_FORMAT_16X4 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_16X4, 160 | const BUFFER_COMPUTE_FORMAT_32X1 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_32X1, 161 | const BUFFER_COMPUTE_FORMAT_32X2 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_32X2, 162 | const BUFFER_COMPUTE_FORMAT_32X4 = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_32X4, 163 | const BUFFER_COMPUTE_FORMAT_SHIFT = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_SHIFT as u16, 164 | const BUFFER_COMPUTE_FORMAT_MASK = bgfx_sys::BGFX_BUFFER_COMPUTE_FORMAT_MASK, 165 | const BUFFER_COMPUTE_TYPE_UINT = bgfx_sys::BGFX_BUFFER_COMPUTE_TYPE_UINT, 166 | const BUFFER_COMPUTE_TYPE_INT = bgfx_sys::BGFX_BUFFER_COMPUTE_TYPE_INT, 167 | const BUFFER_COMPUTE_TYPE_FLOAT = bgfx_sys::BGFX_BUFFER_COMPUTE_TYPE_FLOAT, 168 | const BUFFER_COMPUTE_TYPE_SHIFT = bgfx_sys::BGFX_BUFFER_COMPUTE_TYPE_SHIFT as u16, 169 | const BUFFER_COMPUTE_TYPE_MASK = bgfx_sys::BGFX_BUFFER_COMPUTE_TYPE_MASK, 170 | const BUFFER_COMPUTE_READ = bgfx_sys::BGFX_BUFFER_COMPUTE_READ, 171 | const BUFFER_COMPUTE_WRITE = bgfx_sys::BGFX_BUFFER_COMPUTE_WRITE, 172 | const BUFFER_DRAW_INDIRECT = bgfx_sys::BGFX_BUFFER_DRAW_INDIRECT, 173 | const BUFFER_ALLOW_RESIZE = bgfx_sys::BGFX_BUFFER_ALLOW_RESIZE, 174 | const BUFFER_INDEX32 = bgfx_sys::BGFX_BUFFER_INDEX32, 175 | const BUFFER_COMPUTE_READ_WRITE = bgfx_sys::BGFX_BUFFER_COMPUTE_READ_WRITE, 176 | } 177 | } 178 | 179 | impl Default for BufferFlags { 180 | #[inline] 181 | fn default() -> BufferFlags { 182 | BUFFER_NONE 183 | } 184 | } 185 | 186 | bitflags! { 187 | flags ClearFlags: u16 { 188 | const CLEAR_NONE = bgfx_sys::BGFX_CLEAR_NONE, 189 | const CLEAR_COLOR = bgfx_sys::BGFX_CLEAR_COLOR, 190 | const CLEAR_DEPTH = bgfx_sys::BGFX_CLEAR_DEPTH, 191 | const CLEAR_STENCIL = bgfx_sys::BGFX_CLEAR_STENCIL, 192 | const CLEAR_DISCARD_COLOR_0 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_0, 193 | const CLEAR_DISCARD_COLOR_1 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_1, 194 | const CLEAR_DISCARD_COLOR_2 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_2, 195 | const CLEAR_DISCARD_COLOR_3 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_3, 196 | const CLEAR_DISCARD_COLOR_4 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_4, 197 | const CLEAR_DISCARD_COLOR_5 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_5, 198 | const CLEAR_DISCARD_COLOR_6 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_6, 199 | const CLEAR_DISCARD_COLOR_7 = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_7, 200 | const CLEAR_DISCARD_DEPTH = bgfx_sys::BGFX_CLEAR_DISCARD_DEPTH, 201 | const CLEAR_DISCARD_STENCIL = bgfx_sys::BGFX_CLEAR_DISCARD_STENCIL, 202 | const CLEAR_DISCARD_COLOR_MASK = bgfx_sys::BGFX_CLEAR_DISCARD_COLOR_MASK, 203 | const CLEAR_DISCARD_MASK = bgfx_sys::BGFX_CLEAR_DISCARD_MASK, 204 | } 205 | } 206 | 207 | impl Default for ClearFlags { 208 | #[inline] 209 | fn default() -> ClearFlags { 210 | CLEAR_NONE 211 | } 212 | } 213 | 214 | bitflags! { 215 | flags DebugFlags: u32 { 216 | const DEBUG_NONE = bgfx_sys::BGFX_DEBUG_NONE, 217 | const DEBUG_WIREFRAME = bgfx_sys::BGFX_DEBUG_WIREFRAME, 218 | const DEBUG_IFH = bgfx_sys::BGFX_DEBUG_IFH, 219 | const DEBUG_STATS = bgfx_sys::BGFX_DEBUG_STATS, 220 | const DEBUG_TEXT = bgfx_sys::BGFX_DEBUG_TEXT, 221 | } 222 | } 223 | 224 | impl Default for DebugFlags { 225 | #[inline] 226 | fn default() -> DebugFlags { 227 | DEBUG_NONE 228 | } 229 | } 230 | 231 | bitflags! { 232 | flags ResetFlags: u32 { 233 | const RESET_NONE = bgfx_sys::BGFX_RESET_NONE, 234 | const RESET_FULLSCREEN = bgfx_sys::BGFX_RESET_FULLSCREEN, 235 | const RESET_FULLSCREEN_SHIFT = bgfx_sys::BGFX_RESET_FULLSCREEN_SHIFT, 236 | const RESET_FULLSCREEN_MASK = bgfx_sys::BGFX_RESET_FULLSCREEN_MASK, 237 | const RESET_MSAA_X2 = bgfx_sys::BGFX_RESET_MSAA_X2, 238 | const RESET_MSAA_X4 = bgfx_sys::BGFX_RESET_MSAA_X4, 239 | const RESET_MSAA_X8 = bgfx_sys::BGFX_RESET_MSAA_X8, 240 | const RESET_MSAA_X16 = bgfx_sys::BGFX_RESET_MSAA_X16, 241 | const RESET_MSAA_SHIFT = bgfx_sys::BGFX_RESET_MSAA_SHIFT, 242 | const RESET_MSAA_MASK = bgfx_sys::BGFX_RESET_MSAA_MASK, 243 | const RESET_VSYNC = bgfx_sys::BGFX_RESET_VSYNC, 244 | const RESET_MAXANISOTROPY = bgfx_sys::BGFX_RESET_MAXANISOTROPY, 245 | const RESET_CAPTURE = bgfx_sys::BGFX_RESET_CAPTURE, 246 | const RESET_HMD = bgfx_sys::BGFX_RESET_HMD, 247 | const RESET_HMD_DEBUG = bgfx_sys::BGFX_RESET_HMD_DEBUG, 248 | const RESET_HMD_RECENTER = bgfx_sys::BGFX_RESET_HMD_RECENTER, 249 | const RESET_FLUSH_AFTER_RENDER = bgfx_sys::BGFX_RESET_FLUSH_AFTER_RENDER, 250 | const RESET_FLIP_AFTER_RENDER = bgfx_sys::BGFX_RESET_FLIP_AFTER_RENDER, 251 | const RESET_SRGB_BACKBUFFER = bgfx_sys::BGFX_RESET_SRGB_BACKBUFFER, 252 | const RESET_HIDPI = bgfx_sys::BGFX_RESET_HIDPI, 253 | } 254 | } 255 | 256 | impl Default for ResetFlags { 257 | #[inline] 258 | fn default() -> ResetFlags { 259 | RESET_NONE 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, Johan Sköld. 2 | // License: http://opensource.org/licenses/ISC 3 | 4 | //! Rust wrapper around [bgfx]. 5 | //! 6 | //! Before using this crate, ensure that you fullfill the build requirements for bgfx, as outlined 7 | //! in its [documentation][bgfx building]. If you are compiling for an `msvc` target, make sure to 8 | //! build this crate in a developer command prompt. 9 | //! 10 | //! ## Limitations 11 | //! 12 | //! - So far, only Windows, Linux, and OSX are supported. 13 | //! - Far from all bgfx functionality is exposed. As more examples get ported, more functionality 14 | //! will be as well. 15 | //! 16 | //! *This API is still unstable, and very likely to change.* 17 | //! 18 | //! ## Basic Usage 19 | //! 20 | //! Before this crate can be used, some platform data must be initialized. See [`PlatformData`]. 21 | //! 22 | //! ```should_panic 23 | //! bgfx::PlatformData::new() 24 | //! .context(std::ptr::null_mut()) 25 | //! .display(std::ptr::null_mut()) 26 | //! .window(std::ptr::null_mut()) 27 | //! .apply() 28 | //! .expect("Could not set platform data"); 29 | //! ``` 30 | //! 31 | //! Once the platform data has been initialized, a new thread should be spawned to act as the main 32 | //! thread. This thread should call [`bgfx::init`] to initialize bgfx. The object returned by that 33 | //! function should be used to access bgfx API calls. 34 | //! 35 | //! ```no_run 36 | //! std::thread::spawn(|| { 37 | //! let bgfx = bgfx::init(bgfx::RendererType::Default, None, None) 38 | //! .expect("Failed to initialize bgfx"); 39 | //! // ... 40 | //! }); 41 | //! ``` 42 | //! 43 | //! Finally, the real main thread should act as the render thread, and repeatedly be calling 44 | //! [`bgfx::render_frame`]. 45 | //! 46 | //! ```no_run 47 | //! loop { 48 | //! // This is probably also where you will want to pump the window event queue. 49 | //! bgfx::render_frame(); 50 | //! } 51 | //! ``` 52 | //! 53 | //! See the examples for more in-depth usage. 54 | //! 55 | //! [bgfx]: https://github.com/bkaradzic/bgfx 56 | //! [bgfx building]: https://bkaradzic.github.io/bgfx/build.html 57 | //! [`bgfx::init`]: fn.init.html 58 | //! [`bgfx::render_frame`]: fn.render_frame.html 59 | //! [`PlatformData`]: struct.PlatformData.html 60 | 61 | #[macro_use] 62 | extern crate bgfx_sys; 63 | #[macro_use] 64 | extern crate bitflags; 65 | extern crate libc; 66 | 67 | use std::ffi; 68 | use std::marker::PhantomData; 69 | use std::mem; 70 | use std::ptr; 71 | 72 | pub mod flags; 73 | 74 | pub use flags::*; 75 | 76 | /// Autoselect adapter. 77 | pub const PCI_ID_NONE: u16 = bgfx_sys::BGFX_PCI_ID_NONE; 78 | 79 | /// Software rasterizer. 80 | pub const PCI_ID_SOFTWARE_RASTERIZER: u16 = bgfx_sys::BGFX_PCI_ID_SOFTWARE_RASTERIZER; 81 | 82 | /// AMD adapter. 83 | pub const PCI_ID_AMD: u16 = bgfx_sys::BGFX_PCI_ID_AMD; 84 | 85 | /// Intel adapter. 86 | pub const PCI_ID_INTEL: u16 = bgfx_sys::BGFX_PCI_ID_INTEL; 87 | 88 | /// nVidia adapter. 89 | pub const PCI_ID_NVIDIA: u16 = bgfx_sys::BGFX_PCI_ID_NVIDIA; 90 | 91 | /// Renderer backend type. 92 | #[repr(u32)] 93 | #[derive(PartialEq, Eq, Debug, Copy, Clone)] 94 | pub enum RendererType { 95 | /// No rendering. 96 | Noop = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_NOOP as u32, 97 | 98 | /// Direct3D 9.0. 99 | Direct3D9 = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_DIRECT3D9 as u32, 100 | 101 | /// Direct3D 11.0. 102 | Direct3D11 = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_DIRECT3D11 as u32, 103 | 104 | /// Direct3D 12.0. 105 | Direct3D12 = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_DIRECT3D12 as u32, 106 | 107 | /// GNM. 108 | GNM = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_GNM as u32, 109 | 110 | /// Metal. 111 | Metal = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_METAL as u32, 112 | 113 | /// OpenGLES. 114 | OpenGLES = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_OPENGLES as u32, 115 | 116 | /// OpenGL. 117 | OpenGL = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_OPENGL as u32, 118 | 119 | /// Vulkan. 120 | Vulkan = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_VULKAN as u32, 121 | 122 | /// Use the most platform appropriate renderer. 123 | Default = bgfx_sys::bgfx_renderer_type_BGFX_RENDERER_TYPE_COUNT as u32, 124 | } 125 | 126 | /// `render_frame()` results. 127 | #[repr(u32)] 128 | #[derive(PartialEq, Eq, Debug, Copy, Clone)] 129 | pub enum RenderFrame { 130 | /// No context is available. This usually means the main thread has exited. 131 | NoContext = bgfx_sys::bgfx_render_frame_BGFX_RENDER_FRAME_NO_CONTEXT as u32, 132 | 133 | /// The render was performed. 134 | Render = bgfx_sys::bgfx_render_frame_BGFX_RENDER_FRAME_RENDER as u32, 135 | 136 | /// The render timed out. 137 | Timeout = bgfx_sys::bgfx_render_frame_BGFX_RENDER_FRAME_TIMEOUT as u32, 138 | 139 | /// The renderer is exiting. 140 | Exiting = bgfx_sys::bgfx_render_frame_BGFX_RENDER_FRAME_EXITING as u32, 141 | } 142 | 143 | /// Vertex attribute. 144 | #[repr(u32)] 145 | #[derive(PartialEq, Eq, Debug, Copy, Clone)] 146 | pub enum Attrib { 147 | /// Position. 148 | Position = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_POSITION as u32, 149 | 150 | /// Normal. 151 | Normal = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_NORMAL as u32, 152 | 153 | /// Tangent. 154 | Tangent = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TANGENT as u32, 155 | 156 | /// Bitangent. 157 | Bitangent = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_BITANGENT as u32, 158 | 159 | /// Color 0. 160 | Color0 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_COLOR0 as u32, 161 | 162 | /// Color 1. 163 | Color1 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_COLOR1 as u32, 164 | 165 | /// Index list. 166 | Indices = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_INDICES as u32, 167 | 168 | /// Bone weight. 169 | Weight = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_WEIGHT as u32, 170 | 171 | /// Texture coordinate 0. 172 | TexCoord0 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD0 as u32, 173 | 174 | /// Texture coordinate 1. 175 | TexCoord1 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD1 as u32, 176 | 177 | /// Texture coordinate 2. 178 | TexCoord2 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD2 as u32, 179 | 180 | /// Texture coordinate 3. 181 | TexCoord3 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD3 as u32, 182 | 183 | /// Texture coordinate 4. 184 | TexCoord4 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD4 as u32, 185 | 186 | /// Texture coordinate 5. 187 | TexCoord5 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD5 as u32, 188 | 189 | /// Texture coordinate 6. 190 | TexCoord6 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD6 as u32, 191 | 192 | /// Texture coordinate 7. 193 | TexCoord7 = bgfx_sys::bgfx_attrib_BGFX_ATTRIB_TEXCOORD7 as u32, 194 | } 195 | 196 | /// Vertex attribute type. 197 | #[derive(PartialEq, Eq, Debug, Copy, Clone)] 198 | pub enum AttribType { 199 | /// Unsigned 8-bit integer. 200 | /// 201 | /// If the parameter is `true`, the value will be normalized between 0 and 1. 202 | Uint8(bool), 203 | 204 | /// Signed 8-bit integer. 205 | /// 206 | /// If the parameter is `true`, the value will be normalized between 0 and 1. 207 | Int8(bool), 208 | 209 | /// Unsigned 10-bit integer. 210 | /// 211 | /// If the parameter is `true`, the value will be normalized between 0 and 1. 212 | Uint10(bool), 213 | 214 | /// Signed 10-bit integer. 215 | /// 216 | /// If the parameter is `true`, the value will be normalized between 0 and 1. 217 | Int10(bool), 218 | 219 | /// Unsigned 16-bit integer. 220 | /// 221 | /// If the parameter is `true`, the value will be normalized between 0 and 1. 222 | Uint16(bool), 223 | 224 | /// Signed 16-bit integer. 225 | /// 226 | /// If the parameter is `true`, the value will be normalized between 0 and 1. 227 | Int16(bool), 228 | 229 | /// 16-bit float. 230 | Half, 231 | 232 | /// 32-bit float. 233 | Float, 234 | } 235 | 236 | /// bgfx error. 237 | #[derive(Debug)] 238 | pub enum BgfxError { 239 | /// An invalid display was provided in the platform data. 240 | InvalidDisplay, 241 | 242 | /// An invalid window was provided in the platform data. 243 | InvalidWindow, 244 | 245 | /// Initialization failed. 246 | InitFailed, 247 | } 248 | 249 | /// bgfx-managed buffer of memory. 250 | /// 251 | /// It can be created by either copying existing data through [`copy(...)`], or by referencing 252 | /// existing memory directly through [`reference(...)`]. 253 | /// 254 | /// [`copy(...)`]: #method.copy 255 | /// [`reference(...)`]: #method.reference 256 | pub struct Memory<'b> { 257 | handle: *const bgfx_sys::bgfx_memory_t, 258 | _phantom: PhantomData<&'b ()>, 259 | } 260 | 261 | impl<'b> Memory<'b> { 262 | 263 | /// Copies the source data into a new bgfx-managed buffer. 264 | /// 265 | /// **IMPORTANT:** If this buffer is never passed into a bgfx call, the memory will never be 266 | /// freed, and will leak. 267 | #[inline] 268 | pub fn copy<'d, T>(_bgfx: &'b Bgfx, data: &'d [T]) -> Memory<'b> { 269 | unsafe { 270 | let handle = bgfx_sys::bgfx_copy(data.as_ptr() as *const std::os::raw::c_void, 271 | mem::size_of_val(data) as u32); 272 | Memory { handle: handle, _phantom: PhantomData } 273 | } 274 | } 275 | 276 | /// Creates a reference to the source data for passing into bgfx. When using this constructor 277 | /// over the `copy` call, no copy will be created. bgfx will read the source memory directly. 278 | /// 279 | /// *Note that this is only valid for memory that will live for longer than the bgfx object, 280 | /// as it's the only way we can guarantee that the memory will still be valid until bgfx has 281 | /// finished using it.* 282 | #[inline] 283 | pub fn reference(_bgfx: &'b Bgfx, data: &'b [T]) -> Memory<'b> { 284 | // TODO: The lifetime setup probably isn't 100% complete. Need to figure out how we can 285 | // guarantee that `data` will outlast `_bgfx`. 286 | unsafe { 287 | let handle = bgfx_sys::bgfx_make_ref(data.as_ptr() as *const std::os::raw::c_void, 288 | mem::size_of_val(data) as u32); 289 | Memory { handle: handle, _phantom: PhantomData } 290 | } 291 | } 292 | 293 | } 294 | 295 | /// Shader program. 296 | /// 297 | /// The program holds a vertex shader and a fragment shader. 298 | pub struct Program<'s> { 299 | handle: bgfx_sys::bgfx_program_handle_t, 300 | _vsh: Shader<'s>, 301 | _fsh: Shader<'s>, 302 | } 303 | 304 | impl<'s> Program<'s> { 305 | 306 | /// Creates a new program from a vertex shader and a fragment shader. Ownerships of the shaders 307 | /// are moved to the program. 308 | #[inline] 309 | pub fn new(vsh: Shader<'s>, fsh: Shader<'s>) -> Program<'s> { 310 | unsafe { 311 | let handle = bgfx_sys::bgfx_create_program(vsh.handle, fsh.handle, false); 312 | Program { handle: handle, _vsh: vsh, _fsh: fsh } 313 | } 314 | } 315 | 316 | } 317 | 318 | impl<'s> Drop for Program<'s> { 319 | 320 | #[inline] 321 | fn drop(&mut self) { 322 | unsafe { bgfx_sys::bgfx_destroy_program(self.handle) } 323 | } 324 | 325 | } 326 | 327 | /// Shader. 328 | pub struct Shader<'m> { 329 | handle: bgfx_sys::bgfx_shader_handle_t, 330 | _phantom: PhantomData<&'m ()>, 331 | } 332 | 333 | impl<'m> Shader<'m> { 334 | 335 | /// Creates a new shader from bgfx-managed memory. 336 | #[inline] 337 | pub fn new(data: Memory<'m>) -> Shader<'m> { 338 | unsafe { 339 | let handle = bgfx_sys::bgfx_create_shader(data.handle); 340 | Shader { handle: handle, _phantom: PhantomData } 341 | } 342 | } 343 | 344 | } 345 | 346 | impl<'m> Drop for Shader<'m> { 347 | 348 | #[inline] 349 | fn drop(&mut self) { 350 | unsafe { bgfx_sys::bgfx_destroy_shader(self.handle) } 351 | } 352 | 353 | } 354 | 355 | /// Vertex index buffer. 356 | pub struct IndexBuffer<'m> { 357 | handle: bgfx_sys::bgfx_index_buffer_handle_t, 358 | _phantom: PhantomData<&'m ()>, 359 | } 360 | 361 | impl<'m> IndexBuffer<'m> { 362 | 363 | /// Creates a new index buffer from bgfx-managed memory. 364 | #[inline] 365 | pub fn new(indices: Memory<'m>, flags: BufferFlags) -> IndexBuffer<'m> { 366 | unsafe { 367 | let handle = bgfx_sys::bgfx_create_index_buffer(indices.handle, flags.bits()); 368 | IndexBuffer { handle: handle, _phantom: PhantomData } 369 | } 370 | } 371 | 372 | } 373 | 374 | impl<'m> Drop for IndexBuffer<'m> { 375 | 376 | #[inline] 377 | fn drop(&mut self) { 378 | unsafe { bgfx_sys::bgfx_destroy_index_buffer(self.handle) } 379 | } 380 | 381 | } 382 | 383 | /// Vertex data buffer. 384 | pub struct VertexBuffer<'m> { 385 | handle: bgfx_sys::bgfx_vertex_buffer_handle_t, 386 | _phantom: PhantomData<&'m Bgfx>, 387 | } 388 | 389 | impl<'m> VertexBuffer<'m> { 390 | 391 | /// Creates a new vertex buffer from bgfx-managed memory. 392 | #[inline] 393 | pub fn new<'v>(verts: Memory<'m>, 394 | decl: &'v VertexDecl, 395 | flags: BufferFlags) 396 | -> VertexBuffer<'m> { 397 | unsafe { 398 | let handle = bgfx_sys::bgfx_create_vertex_buffer(verts.handle, 399 | &decl.decl, 400 | flags.bits()); 401 | VertexBuffer { handle: handle, _phantom: PhantomData } 402 | } 403 | } 404 | 405 | } 406 | 407 | impl<'m> Drop for VertexBuffer<'m> { 408 | 409 | #[inline] 410 | fn drop(&mut self) { 411 | unsafe { bgfx_sys::bgfx_destroy_vertex_buffer(self.handle) } 412 | } 413 | 414 | } 415 | 416 | /// Describes the structure of a vertex. 417 | pub struct VertexDecl { 418 | decl: bgfx_sys::bgfx_vertex_decl_t, 419 | } 420 | 421 | impl VertexDecl { 422 | 423 | /// Creates a new vertex declaration using a [`VertexDeclBuilder`]. 424 | /// 425 | /// # Example 426 | /// 427 | /// ``` 428 | /// bgfx::VertexDecl::new(None) 429 | /// .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) 430 | /// .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8(true)) 431 | /// .end(); 432 | /// ``` 433 | /// 434 | /// [`VertexDeclBuilder`]: struct.VertexDeclBuilder.html 435 | #[inline] 436 | pub fn new(renderer: Option) -> VertexDeclBuilder { 437 | unsafe { 438 | let renderer = mem::transmute(renderer.unwrap_or(RendererType::Noop)); 439 | let mut descr = VertexDeclBuilder { decl: mem::uninitialized() }; 440 | bgfx_sys::bgfx_vertex_decl_begin(&mut descr.decl, renderer); 441 | descr 442 | } 443 | } 444 | 445 | } 446 | 447 | /// Builder for `VertexDecl` instances. 448 | pub struct VertexDeclBuilder { 449 | decl: bgfx_sys::bgfx_vertex_decl_t, 450 | } 451 | 452 | impl VertexDeclBuilder { 453 | 454 | /// Adds a field to the structure descriptor. See [`VertexDecl::new`] for an example. 455 | /// 456 | /// [`VertexDecl::new`]: struct.VertexDecl.html#method.new 457 | pub fn add(&mut self, attrib: Attrib, count: u8, kind: AttribType) -> &mut Self { 458 | let mut normalized = false; 459 | let mut as_int = false; 460 | 461 | let kind = match kind { 462 | AttribType::Uint8(n) => { 463 | normalized = n; 464 | bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_UINT8 465 | } 466 | AttribType::Int8(n) => { 467 | normalized = n; 468 | as_int = true; 469 | bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_UINT8 470 | } 471 | AttribType::Uint10(n) => { 472 | normalized = n; 473 | bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_UINT10 474 | } 475 | AttribType::Int10(n) => { 476 | normalized = n; 477 | as_int = true; 478 | bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_UINT10 479 | } 480 | AttribType::Uint16(n) => { 481 | normalized = n; 482 | bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_INT16 483 | } 484 | AttribType::Int16(n) => { 485 | normalized = n; 486 | as_int = true; 487 | bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_INT16 488 | } 489 | AttribType::Half => bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_HALF, 490 | AttribType::Float => bgfx_sys::bgfx_attrib_type_t::BGFX_ATTRIB_TYPE_FLOAT, 491 | }; 492 | 493 | unsafe { 494 | bgfx_sys::bgfx_vertex_decl_add(&mut self.decl, 495 | mem::transmute(attrib), 496 | count, 497 | kind, 498 | normalized, 499 | as_int); 500 | } 501 | 502 | self 503 | } 504 | 505 | /// Finalizes the construction of the [`VertexDecl`]. 506 | /// 507 | /// [`VertexDecl`]: struct.VertexDecl.html 508 | #[inline] 509 | pub fn end(&mut self) -> VertexDecl { 510 | unsafe { 511 | bgfx_sys::bgfx_vertex_decl_end(&mut self.decl); 512 | } 513 | 514 | VertexDecl { decl: self.decl } 515 | } 516 | 517 | /// Indicates a gap in the vertex structure. 518 | #[inline] 519 | pub fn skip(&mut self, bytes: u8) -> &mut Self { 520 | unsafe { 521 | bgfx_sys::bgfx_vertex_decl_skip(&mut self.decl, bytes); 522 | } 523 | 524 | self 525 | } 526 | 527 | } 528 | 529 | /// Acts as the library wrapper for bgfx. Any calls intended to be run on the main thread are 530 | /// exposed as functions on this object. 531 | /// 532 | /// It is created through a call to [`bgfx::init`], and will shut down bgfx when dropped. 533 | /// 534 | /// [`bgfx::init`]: fn.init.html 535 | pub struct Bgfx { 536 | // This dummy field only exists so this type can't be publicly instantiated. 537 | _dummy: u32, 538 | } 539 | 540 | impl Bgfx { 541 | 542 | #[inline] 543 | fn new() -> Bgfx { 544 | Bgfx { _dummy: 0 } 545 | } 546 | 547 | /// Clears the debug text overlay. 548 | #[inline] 549 | pub fn dbg_text_clear(&self, attr: Option, small: Option) { 550 | let attr = attr.unwrap_or(0); 551 | unsafe { bgfx_sys::bgfx_dbg_text_clear(attr, small.unwrap_or(false)) } 552 | } 553 | 554 | /// Draws an image to the debug text overlay. 555 | #[inline] 556 | pub fn dbg_text_image(&self, 557 | x: u16, 558 | y: u16, 559 | width: u16, 560 | height: u16, 561 | data: &[u8], 562 | pitch: u16) { 563 | unsafe { 564 | bgfx_sys::bgfx_dbg_text_image(x, 565 | y, 566 | width, 567 | height, 568 | data.as_ptr() as *const std::os::raw::c_void, 569 | pitch) 570 | } 571 | } 572 | 573 | /// Displays text in the debug text overlay. 574 | #[inline] 575 | pub fn dbg_text_print(&self, x: u16, y: u16, attr: u8, text: &str) { 576 | let text = ffi::CString::new(text).unwrap(); 577 | unsafe { bgfx_sys::bgfx_dbg_text_printf(x, y, attr, text.as_ptr()) } 578 | } 579 | 580 | /// Finish the frame, syncing up with the render thread. Returns an incrementing frame counter. 581 | #[inline] 582 | pub fn frame(&self, capture: bool) -> u32 { 583 | unsafe { bgfx_sys::bgfx_frame(capture) } 584 | } 585 | 586 | /// Gets the type of the renderer in use. 587 | #[inline] 588 | pub fn get_renderer_type(&self) -> RendererType { 589 | unsafe { mem::transmute(bgfx_sys::bgfx_get_renderer_type()) } 590 | } 591 | 592 | /// Resets the graphics device to the given size, with the given flags. 593 | #[inline] 594 | pub fn reset(&self, width: u16, height: u16, reset: ResetFlags) { 595 | unsafe { bgfx_sys::bgfx_reset(width as u32, height as u32, reset.bits()) } 596 | } 597 | 598 | /// Sets the debug flags to use. 599 | #[inline] 600 | pub fn set_debug(&self, debug: DebugFlags) { 601 | unsafe { bgfx_sys::bgfx_set_debug(debug.bits()) } 602 | } 603 | 604 | /// Sets the index buffer to use for rendering. 605 | #[inline] 606 | pub fn set_index_buffer(&self, ibh: &IndexBuffer) { 607 | // TODO: How to solve lifetimes... 608 | unsafe { bgfx_sys::bgfx_set_index_buffer(ibh.handle, 0, std::u32::MAX) } 609 | } 610 | 611 | /// Sets the render state. 612 | #[inline] 613 | pub fn set_state(&self, state: StateFlags, rgba: Option) { 614 | unsafe { bgfx_sys::bgfx_set_state(state.bits(), rgba.unwrap_or(0)) } 615 | } 616 | 617 | /// Sets the model transform for rendering. If not called before submitting a draw, an identity 618 | /// matrix will be used. 619 | #[inline] 620 | pub fn set_transform(&self, mtx: &[f32; 16]) { 621 | unsafe { 622 | bgfx_sys::bgfx_set_transform(mtx.as_ptr() as *const std::os::raw::c_void, 1); 623 | } 624 | } 625 | 626 | /// Sets the vertex buffer to use for rendering. 627 | #[inline] 628 | pub fn set_vertex_buffer(&self, stream: u8, vbh: &VertexBuffer) { 629 | // TODO: How to solve lifetimes... 630 | unsafe { bgfx_sys::bgfx_set_vertex_buffer(stream, vbh.handle, 0, std::u32::MAX) } 631 | } 632 | 633 | /// Sets the options to use when clearing the given view. 634 | #[inline] 635 | pub fn set_view_clear(&self, id: u8, flags: ClearFlags, rgba: u32, depth: f32, stencil: u8) { 636 | unsafe { bgfx_sys::bgfx_set_view_clear(id, flags.bits(), rgba, depth, stencil) } 637 | } 638 | 639 | /// Sets the rectangle to display the given view in. 640 | #[inline] 641 | pub fn set_view_rect(&self, id: u8, x: u16, y: u16, width: u16, height: u16) { 642 | unsafe { bgfx_sys::bgfx_set_view_rect(id, x, y, width, height) } 643 | } 644 | 645 | /// Sets the view and projection matrices for the given view. 646 | #[inline] 647 | pub fn set_view_transform(&self, id: u8, view: &[f32; 16], proj: &[f32; 16]) { 648 | unsafe { 649 | bgfx_sys::bgfx_set_view_transform(id, 650 | view.as_ptr() as *const std::os::raw::c_void, 651 | proj.as_ptr() as *const std::os::raw::c_void) 652 | } 653 | } 654 | 655 | /// Submit a primitive for rendering. Returns the number of draw calls used. 656 | #[inline] 657 | pub fn submit(&self, view: u8, program: &Program, preserve_state: bool) -> u32 { 658 | unsafe { bgfx_sys::bgfx_submit(view, program.handle, 0, preserve_state) } 659 | } 660 | 661 | /// Touches a view. ( ͡° ͜ʖ ͡°) 662 | #[inline] 663 | pub fn touch(&self, id: u8) { 664 | unsafe { 665 | bgfx_sys::bgfx_touch(id); 666 | } 667 | } 668 | 669 | } 670 | 671 | impl Drop for Bgfx { 672 | 673 | #[inline] 674 | fn drop(&mut self) { 675 | unsafe { bgfx_sys::bgfx_shutdown() } 676 | } 677 | 678 | } 679 | 680 | /// Pump the render thread. 681 | /// 682 | /// This should be called repeatedly on the render thread. 683 | #[inline] 684 | pub fn render_frame() -> RenderFrame { 685 | unsafe { mem::transmute(bgfx_sys::bgfx_render_frame()) } 686 | } 687 | 688 | /// Platform data initializer. 689 | /// 690 | /// This should be applied *only once*, before bgfx is used. 691 | /// 692 | /// # Example 693 | /// 694 | /// ```should_panic 695 | /// // Note: The default value for all of these options is null. If that is what you want, you may 696 | /// // choose not to call said setter. 697 | /// bgfx::PlatformData::new() 698 | /// .context(std::ptr::null_mut()) 699 | /// .display(std::ptr::null_mut()) // Must be non-null on unix platforms 700 | /// .window(std::ptr::null_mut()) // Must be non-null 701 | /// .apply() 702 | /// .expect("Could not set platform data"); 703 | /// ``` 704 | pub struct PlatformData { 705 | data: bgfx_sys::bgfx_platform_data, 706 | } 707 | 708 | impl PlatformData { 709 | 710 | /// Creates an empty PlatformData instance. 711 | #[inline] 712 | pub fn new() -> PlatformData { 713 | PlatformData { 714 | data: bgfx_sys::bgfx_platform_data { 715 | ndt: ptr::null_mut(), 716 | nwh: ptr::null_mut(), 717 | context: ptr::null_mut(), 718 | backBuffer: ptr::null_mut(), 719 | backBufferDS: ptr::null_mut(), 720 | session: ptr::null_mut(), 721 | }, 722 | } 723 | } 724 | 725 | /// Apply the platform configuration. 726 | pub fn apply(&mut self) -> Result<(), BgfxError> { 727 | if self.data.ndt == ptr::null_mut() && cfg!(target_os = "linux") { 728 | Err(BgfxError::InvalidDisplay) 729 | } else if self.data.nwh == ptr::null_mut() { 730 | Err(BgfxError::InvalidWindow) 731 | } else { 732 | unsafe { 733 | bgfx_sys::bgfx_set_platform_data(&mut self.data); 734 | } 735 | Ok(()) 736 | } 737 | } 738 | 739 | /// Sets the GL context to use. 740 | #[inline] 741 | pub fn context(&mut self, context: *mut std::os::raw::c_void) -> &mut Self { 742 | self.data.context = context; 743 | self 744 | } 745 | 746 | /// Sets the X11 display to use on unix systems. 747 | #[inline] 748 | pub fn display(&mut self, display: *mut std::os::raw::c_void) -> &mut Self { 749 | self.data.ndt = display; 750 | self 751 | } 752 | 753 | /// Sets the handle to the window to use. 754 | #[inline] 755 | pub fn window(&mut self, window: *mut std::os::raw::c_void) -> &mut Self { 756 | self.data.nwh = window; 757 | self 758 | } 759 | 760 | } 761 | 762 | /// Initializes bgfx. 763 | /// 764 | /// This must be called on the main thread after setting the platform data. See [`PlatformData`]. 765 | /// 766 | /// [`PlatformData`]: struct.PlatformData.html 767 | pub fn init(renderer: RendererType, 768 | vendor_id: Option, 769 | device_id: Option) 770 | -> Result { 771 | let vendor = vendor_id.unwrap_or(PCI_ID_NONE); 772 | let device = device_id.unwrap_or(0); 773 | 774 | unsafe { 775 | let success = bgfx_sys::bgfx_init(mem::transmute(renderer), 776 | vendor, 777 | device, 778 | ptr::null_mut(), 779 | ptr::null_mut()); 780 | 781 | if success { Ok(Bgfx::new()) } else { Err(BgfxError::InitFailed) } 782 | } 783 | } 784 | --------------------------------------------------------------------------------