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 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
/*! Easy to use, light OpenGL 3+ wrapper glin aims to be a mostly bindless, simple wrapper over opengl that simplifies and provides a safe api for opengl without aiming to cover every possible case but instead making it easy to use unsafe calls in combination with the safe api when one needs to use extensions or any opengl api that is not covered (yet). That means for example that in certain cases functions will take GLenums directly as parameters when the particular parameter can change or have several options not originally on the standard through extensions, while parameters that have clearly defined options in the standard will have an enum representation. # Usage The first thing needed to use glin is a Context. A context needs an instance implementing GLWindow to be able to load the Open GL or Open GL ES functions: ```no_run #[cfg(feature = "glfw")] use glfw::Context; #[cfg(feature = "glfw")] fn main(){ let mut glfw_instance = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); glfw_instance.window_hint(glfw::WindowHint::ContextVersion(4, 1)); glfw_instance.window_hint(glfw::WindowHint::OpenGlProfile( glfw::OpenGlProfileHint::Core )); glfw_instance.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); let (mut window, receiver) = glfw_instance .create_window(1280, 720, "triangle", glfw::WindowMode::Windowed).unwrap(); window.set_key_polling(true); window.make_current(); glfw_instance.set_swap_interval(glfw::SwapInterval::Sync(1)); let gl = glin::Context::new(&mut window).unwrap(); } #[cfg(feature = "egli")] use egli::Display; #[cfg(feature = "egli")] fn main(){ use std::ptr; let mut display = Display::from_default_display() .expect("failed to get EGL display"); display.initialize() .expect("failed to initialize"); let configs = display.config_filter() .choose_configs() .expect("failed to get configurations"); let config = *configs.first().unwrap(); let surface = display.create_window_surface(config, ptr::null_mut()).unwrap(); let context = display .create_context_with_client_version(config, egli::ContextClientVersion::OpenGlEs2) .unwrap(); display.make_current(&surface, &surface, &context).unwrap(); let gl = glin::Context::new(&mut display).unwrap(); } #[cfg(feature = "glutin")] use glutin::GlContext; #[cfg(feature = "glutin")] fn main(){ let mut events_loop = glutin::EventsLoop::new(); let window = glutin::WindowBuilder::new() .with_title("Hello, world!") .with_dimensions(1024, 768); let context = glutin::ContextBuilder::new() .with_vsync(true); let mut gl_window = glutin::GlWindow::new(window, context, &events_loop).unwrap(); unsafe { gl_window.make_current().unwrap(); } let gl = glin::Context::new(&mut gl_window).unwrap(); } #[cfg(not(any(feature="glfw", feature="egli", feature="glutin")))] fn main() {} ``` Once we have a context we can start creating glin objects and issuing draw calls through it. # Creating glin Objects To create any glin object you need a context and the constructor calls are done through that context which generally returns a builder that can be customized with more parameters to finally create the desired object: ```no_run # use std::mem; use glin::gl; struct Vertex{ position: [f32;3], } fn main(){ # let gl: glin::Context = unsafe{ mem::MaybeUninit::uninit().assume_init() }; let buffer_object: glin::Buffer<Vertex> = gl.new_buffer().empty().unwrap(); let program = gl.new_program().from_src(&[ (gl::VERTEX_SHADER, "// vertex shader source"), (gl::FRAGMENT_SHADER, "// fragment shader source"), ]).unwrap(); let _texture = gl.new_texture().from_format(glin::texture::Format{ target: gl::TEXTURE_2D, internal_format: gl::RGBA, width: 640, height: 480, levels: 1, #[cfg(all(not(feature = "gles"), not(feature="webgl")))] samples: 0, }); } ``` # Drawing Drawing geometry in glin is done through vaos. A VAO is just an OpenGL vertex array object but also contains a memory reference to the buffers it uses internally. Apart from the geometry in order to draw something in glin you'll need a glsl program, it's uniforms and optionally some properties that customize the drawing. To use a set of properties, just call with on an exisiting context to create a new context with the original properties + the new properties passed as parameter: ```no_run #[macro_use] extern crate glin; use std::mem; use glin::gl; #[derive(VertexFormat)] struct Vertex{ position: [f32;3], } fn main(){ let gl: glin::Context = unsafe{ mem::uninitialized() }; let buffer_object: glin::Buffer<Vertex> = gl.new_buffer().empty().unwrap(); let program = gl.new_program().from_src(&[ (gl::VERTEX_SHADER, "// vertex shader source"), (gl::FRAGMENT_SHADER, "// fragment shader source"), ]).unwrap(); let vao: glin::SimpleVao<Vertex> = gl.new_simple_vao() .empty_from_bindings(&program, gl::TRIANGLES) .unwrap(); let gl = gl.with(&[glin::Property::DepthTest(true)]); gl.draw(&vao, &program, &[]).is_ok(); } ``` */ // #![warn(clippy::all)] #[macro_use] extern crate mopa; extern crate regex; #[macro_use] extern crate bitflags; #[cfg(feature = "webgl")] #[macro_use] extern crate stdweb; #[cfg(feature = "webgl")] #[macro_use] extern crate stdweb_derive; #[cfg(feature = "webgl")] extern crate serde; #[cfg(feature = "webgl")] #[macro_use] extern crate serde_derive; #[cfg(feature = "webgl")] extern crate densevec; #[cfg(feature = "webgl")] extern crate mem_cmp; #[macro_use] extern crate log; #[macro_use] extern crate lazy_static; extern crate indexmap; #[cfg(feature="glsl_optimizer")] extern crate glsl_optimizer_sys; #[doc(inline)] pub use program::Program; #[doc(inline)] pub use attributes::{VertexFormat, Bindings}; #[doc(inline)] pub use vao::{Vao, VaoRange, VaoDraw}; #[doc(inline)] pub use vao::simple_vao::{self, SimpleVao}; #[doc(inline)] pub use fbo::Fbo; #[doc(inline)] #[cfg(all(not(feature = "gles"), not(feature="webgl")))] pub use buffer::{Buffer, SharedBuffer, BufferStorage, SharedBufferStorage, MapReadFlags, MapWriteFlags, MapReadWriteFlags, BufferRange, BufferRangeMut}; #[doc(inline)] #[cfg(any(feature = "gles", feature="webgl"))] pub use buffer::{Buffer, SharedBuffer, BufferRange, BufferRangeMut}; #[doc(inline)] pub use texture::{Texture, TextureSampler}; #[doc(inline)] pub use cubemap::CubeMap; #[doc(inline)] pub use state::{Property, Vendor}; #[cfg(all(not(feature = "gles"), not(feature="webgl")))] #[doc(inline)] pub use state::{DebugInfo, DebugSeverity, DebugSource, DebugType}; #[doc(inline)] pub use context::{ Context, CreationContext, CreationContextMut, CreationProxy, SurfaceCreationContext, Screen, RenderSurface }; #[doc(inline)] pub use state::State; #[doc(inline)] pub use utils::Rect; #[doc(inline)] pub use features::traits::{Image, CubemapImage}; #[cfg(not(feature="webgl"))] #[doc(inline)] pub use features::traits::GlWindow; #[cfg(feature="webgl")] #[doc(inline)] pub use features::traits::WebGlWindow; #[doc(inline)] pub use error::{Error, ErrorKind}; #[doc(inline)] pub use offscreen_buffer::{OffscreenBuffer, UntypedOffscreenBuffer}; #[doc(inline)] pub use sampler::Sampler; #[doc(inline)] pub use utils::{gl_format_from_internal, gl_type_from_internal, Color}; #[doc(inline)] pub use state::{Capabilities, Viewport}; #[doc(inline)] #[cfg(all(not(feature = "gles"), not(feature="webgl")))] pub use sync::Fence; #[cfg(not(feature="webgl"))] pub use debug_group::DebugGroup; pub use indexmap::{IndexMap as HashMap, indexmap as hash_map}; #[cfg(feature = "gles")] pub use gles as gl; #[cfg(feature = "webgl")] pub use webgl2 as gl; use std::result; #[macro_use] pub mod macros; #[macro_use] mod utils; pub mod program; pub mod texture; pub mod cubemap; pub mod buffer; pub mod fbo; mod state; mod context; mod features; pub mod attributes; pub mod vao; #[cfg(all(not(feature = "gles"), not(feature="webgl")))] pub mod gl; #[cfg(feature = "gles")] pub mod gles; #[cfg(feature = "webgl")] pub mod webgl2; mod error; #[cfg(all(not(feature = "gles"), not(feature="webgl")))] pub mod query; mod offscreen_buffer; mod sampler; #[cfg(all(not(feature = "gles"), not(feature="webgl")))] mod sync; #[cfg(not(feature="webgl"))] mod debug_group; pub type IndexT = u32; pub type Result<T> = result::Result<T,Error>; #[cfg(feature = "derive")] #[allow(unused_imports)] #[macro_use] extern crate glin_derive; #[cfg(feature = "derive")] #[doc(hidden)] pub use glin_derive::*; use std::os::raw::c_uint; #[repr(C)] pub struct DrawElementsIndirectCommand{ pub count: c_uint, pub instance_count: c_uint, pub first_index: c_uint, pub base_vertex: c_uint, pub base_instance: c_uint, } #[repr(C)] pub struct DrawArraysIndirectCommand{ pub count: c_uint, pub instance_count: c_uint, pub first: c_uint, pub base_instance: c_uint, }