1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
#![deny(missing_docs)] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] //! This crate wraps the [blaze library](https://github.com/razer-rbi/blaze) //! which is geared towards efficient and cross-platform 2D sprite drawing using OpenGL. //! Supported features: //! * Dynamic batched sprite drawing //! * Static batched sprite drawing //! * Immediate drawing //! * Texture loading //! * Render targets //! * Custom shaders //! * Screenshot saving #[macro_use] extern crate bitflags; extern crate bytes; #[macro_use] extern crate enum_primitive; /// Defines blending-related functionality. pub mod blend; /// Dynamic batched drawing. Designed for moving sprites. pub mod dynamic; /// Immediate-mode drawing. pub mod immediate; /// Render target support. pub mod rendertarget; /// Custom shader support. pub mod shader; /// Static batched drawing. Designed for static geometry. pub mod r#static; /// Texture loading and saving. pub mod texture; #[cfg_attr(tarpaulin, skip)] mod internal; use crate::internal::wrap_result; /// A rectangle which has it's top-left corner position, width and height expressed in floats. #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Rectangle { /// X position of top left corner pub x: f32, /// Y position of top left corner pub y: f32, /// Width pub w: f32, /// Height pub h: f32, } /// Underlying sprite quad data structure used by VAOs (vertex array objects). #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct SpriteQuad { /// Four vertices defining the quad, defined in the following order: /// 0 - top-left, 1 - bottom-left, 2 - top-right, 3 - bottom-right /// (think of N flipped horizontally, like И) pub vertices: [Vertex; 4usize], } /// Two-dimensional float vector. #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Vector2 { /// X coordinate pub x: f32, /// Y coordinate pub y: f32, } /// Four-dimensional float vector. #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Vector4 { /// X coordinate pub x: f32, /// Y coordinate pub y: f32, /// Z coordinate pub z: f32, /// W coordinate pub w: f32, } /// Underlying vertex data structure used by VAOs (vertex array objects). #[repr(C, packed)] #[derive(Debug, Copy, Clone)] pub struct Vertex { /// X position on the screen pub x: f32, /// Y position on the screen pub y: f32, /// Texture coordinate (U) pub u: f32, /// Texture coordinate (V) pub v: f32, /// Color (R) pub r: f32, /// Color (G) pub g: f32, /// Color (B) pub b: f32, /// Color (alpha) pub a: f32, } use internal::*; use std::ffi::*; use std::os::raw::*; use std::string::*; /// Represents a RGBA color. #[derive(Debug, Copy, Clone)] pub struct Color { /// Red component, defined in range from 0.0 to 1.0 pub r: f32, /// Green component, defined in range from 0.0 to 1.0 pub g: f32, /// Blue component, defined in range from 0.0 to 1.0 pub b: f32, /// Alpha component, defined in range from 0.0 to 1.0 pub a: f32, } #[cfg_attr(tarpaulin, skip)] impl From<Vector4> for Color { fn from(vector: Vector4) -> Self { Color { r: vector.x, g: vector.y, b: vector.z, a: vector.w } } } #[cfg_attr(tarpaulin, skip)] impl From<Color> for Vector4 { fn from(color: Color) -> Self { Vector4 { x: color.r, y: color.g, z: color.b, w: color.a } } } enum_from_primitive! { /// Defines supported flip modes that can be used when the sprite is drawn. #[cfg_attr(tarpaulin, skip)] #[derive(Debug, Copy, Clone)] pub enum SpriteFlip { /// Draws the sprite texture as it is None = BLZ_SpriteFlip_NONE as isize, /// Flips the texture horizontally FlipH = BLZ_SpriteFlip_FLIP_H as isize, /// Flips the texture vertically FlipV = BLZ_SpriteFlip_FLIP_V as isize, /// Flips the texture both horizontally and vertically Both = BLZ_SpriteFlip_BOTH as isize } } /// Defines a type for OpenGL procedure loader. pub type GLProcLoader = unsafe extern "C" fn(name: *const c_char) -> *mut c_void; /// Alias for `Result<(), String>`. pub type CallResult = Result<(), String>; /// Returns last API error information string. The same string is returned from /// API calls which return `Result<..., String>`. /// Note: error string may be empty even if an API call failed, the output /// `Result<..., String>` will return an `Err("Unknown error")` in that case. pub fn get_last_error() -> Option<String> { unsafe { let ptr = BLZ_GetLastError().as_ref(); ptr.map(|val| CStr::from_ptr(val).to_str().unwrap().to_owned()) } } /// Loads OpenGL functions used by this library. Requires an active window with /// an OpenGL context (version 3.0 core and above). /// # Example (using SDL2) /// ``` /// use blaze_rs::load; /// use sdl2::video::GLProfile; /// /// let context = sdl2::init().unwrap(); /// let video_sys = context.video().unwrap(); /// let gl_attr = video_sys.gl_attr(); /// gl_attr.set_context_profile(GLProfile::Core); /// gl_attr.set_context_version(3, 0); /// let window = video_sys.window("Test", 800, 600) /// .opengl() /// .build() /// .unwrap(); /// let _ctx = window.gl_create_context().unwrap(); /// /// match load(sdl2::sys::SDL_GL_GetProcAddress) { /// Ok(_) => {} /// Err(e) => panic!(e), /// } /// ``` pub fn load(loader: GLProcLoader) -> CallResult { unsafe { match BLZ_Load(Some(loader)) { x if x > 0 => Ok(()), _ => panic!(get_last_error().unwrap_or("Unknown error".to_string())), } } } /// Sets viewport dimensions. All sprite position and size calculations will be /// based on them. In most cases, you should pass the window size in pixels here, /// or a scaled value for pixel-art based games, for example. pub fn set_viewport(width: u32, height: u32) -> CallResult { unsafe { wrap_result(BLZ_SetViewport(width as i32, height as i32)) } } /// Sets the color which is used for clearing the framebuffer. pub fn set_clear_color(color: Color) { unsafe { BLZ_SetClearColor(color.into()); } } /// Clears the current framebuffer. pub fn clear() { unsafe { BLZ_Clear(); } }