From 0aa062f4b89ae1c572c0a9a9530cec718e63a2ca Mon Sep 17 00:00:00 2001 From: iceiix <43691553+iceiix@users.noreply.github.com> Date: Fri, 25 Dec 2020 10:00:22 -0800 Subject: [PATCH] Use glow, GL on Whatever (#262) Replaces the use of gl_generator with the glow wrapper: * Add glow dependency, based on glow 0.6.1 * Pin version of glow fork for https://github.com/iceiix/glow/pull/1 until #442 renderbuffer * Remove gl module, steven_gl Porting details: * Initialize glow in src/gl/mod.rs * Call gl methods on glow context * glow uses camelcase * Import glow::HasContext trait, finds draw_elements etc. * Fix mismatched types, glow uses Option and &str instead of raw pointers * Fix uniform_location, glow already returns Some(u32) * uniform_location: convert i32 to u32 for Uniform * Fix attribute_location * Fix shader creation Result u32 type * Fix passing GLvoid and 2d/3d * Fix missing Options type mismatches * Offsets are i32 in glow, not GLvoid * Fix clear_buffer using _f32_slice * Delete methods are singular not plural * glBufferData -> buffer_data_u8_slice * buffer_sub_data_u8_slice * Update more glow method wrapper names found by reviewing glow native platform * Remove unused multi_draw_elements, can be replaced by draw_elements in a loop and it has no WebGL equivalent * glow implements glMapBufferRange * Remove unused read_buffer * glow's deletes automatically pass 1 and take no reference * shader_source() accepts &str directly; removes last of std::ptr * Pass uniform Option * Fix bool passing normalized parameter * Fix draw_buffers parameter * Stop unnecessarily returning context from gl::init * Getting shader info is unsafe * Unwrapping static mut is unsafe * Use unsafe raw pointers for global mutable context * Fix initializing GL objects wrappers from glow wrappers * Unbinding framebuffers uses None * Uppercase global to fix warning * Shaders return Some instead of None * Unbox the context to a raw pointer * Use tex_image_2d_multisample added in glow fork * Implement uniform_location, fixing unwrap None failed * Add tex_sub_image_3d, using PixelUnpackData::Slice * set_matrix4: transmute the Matrix4 since it is repr(C) * get_pixels -> get_tex_image -> glGetTexImage, with PixelPackData::Slice * Wrap sub_image_2d (glTexSubImage2D) and fix warnings * Implement set_float_multi_raw and set_matrix4_multi, using from_raw_parts --- Cargo.lock | 28 ++-- Cargo.toml | 5 +- gl/Cargo.lock | 56 ------- gl/Cargo.toml | 13 -- gl/build.rs | 15 -- gl/src/lib.rs | 4 - src/gl/mod.rs | 333 +++++++++++++++++++----------------------- src/render/clouds.rs | 6 +- src/render/mod.rs | 4 +- src/render/shaders.rs | 4 +- 10 files changed, 178 insertions(+), 290 deletions(-) delete mode 100644 gl/Cargo.lock delete mode 100644 gl/Cargo.toml delete mode 100644 gl/build.rs delete mode 100644 gl/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d7e56d2..f802624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,6 +827,17 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glow" +version = "0.6.1" +source = "git+https://github.com/iceiix/glow?rev=45c808678735e03737d5e1b9d6ed0e21070edcd9#45c808678735e03737d5e1b9d6ed0e21070edcd9" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "glutin" version = "0.26.0" @@ -2270,6 +2281,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "slotmap" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c46a3482db8f247956e464d783693ece164ca056e6e67563ee5505bdb86452cd" + [[package]] name = "smallvec" version = "0.6.13" @@ -2389,15 +2406,6 @@ dependencies = [ "steven_shared", ] -[[package]] -name = "steven_gl" -version = "0.0.1" -dependencies = [ - "gl_generator", - "khronos_api", - "libc", -] - [[package]] name = "steven_protocol" version = "0.0.1" @@ -2436,6 +2444,7 @@ dependencies = [ "clipboard", "collision", "flate2", + "glow", "glutin", "image", "lazy_static", @@ -2449,7 +2458,6 @@ dependencies = [ "std_or_web", "stdweb", "steven_blocks", - "steven_gl", "steven_protocol", "steven_resources", "steven_shared", diff --git a/Cargo.toml b/Cargo.toml index d760514..7ef5c52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ opt-level = 1 cfg-if = "1.0.0" wasm-bindgen = "0.2.69" glutin = "0.26.0" +glow = { git = "https://github.com/iceiix/glow", rev = "45c808678735e03737d5e1b9d6ed0e21070edcd9" } byteorder = "1.3.4" serde = "1.0.118" serde_json = "1.0.60" @@ -46,10 +47,6 @@ reqwest = { version = "0.10.10", features = [ "blocking" ]} stdweb = "0.4.20" winit = { version = "0.24.0", features = [ "stdweb" ]} -[dependencies.steven_gl] -path = "./gl" -version = "0" - [dependencies.steven_resources] path = "./resources" version = "0" diff --git a/gl/Cargo.lock b/gl/Cargo.lock deleted file mode 100644 index a04e258..0000000 --- a/gl/Cargo.lock +++ /dev/null @@ -1,56 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "khronos_api 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.66" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "steven_gl" -version = "0.0.1" -dependencies = [ - "gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "khronos_api 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "xml-rs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -"checksum khronos_api 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" diff --git a/gl/Cargo.toml b/gl/Cargo.toml deleted file mode 100644 index 1e3401e..0000000 --- a/gl/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "steven_gl" -version = "0.0.1" -authors = [ "Thinkofdeath " ] -edition = "2018" -build = "build.rs" - -[build-dependencies] -gl_generator = "0.14.0" -khronos_api = "3.1.0" - -[dependencies] -libc = "0.2.71" diff --git a/gl/build.rs b/gl/build.rs deleted file mode 100644 index 2ede032..0000000 --- a/gl/build.rs +++ /dev/null @@ -1,15 +0,0 @@ -use gl_generator::{Api, Fallbacks, GlobalGenerator, Profile, Registry}; -use std::env; -use std::fs::File; -use std::io::BufWriter; -use std::path::Path; - -fn main() { - let out_dir = env::var("OUT_DIR").unwrap(); - let dest = Path::new(&out_dir); - - let mut file = BufWriter::new(File::create(&dest.join("bindings.rs")).unwrap()); - Registry::new(Api::Gl, (3, 2), Profile::Core, Fallbacks::All, []) - .write_bindings(GlobalGenerator, &mut file) - .unwrap(); -} diff --git a/gl/src/lib.rs b/gl/src/lib.rs deleted file mode 100644 index 0d44ad1..0000000 --- a/gl/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![allow(clippy::unused_unit)] -#![allow(clippy::missing_safety_doc)] -#![allow(clippy::too_many_arguments)] -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/src/gl/mod.rs b/src/gl/mod.rs index 646a322..05bac14 100644 --- a/src/gl/mod.rs +++ b/src/gl/mod.rs @@ -12,18 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate steven_gl as gl; - +use glow as gl; +use glow::{HasContext, PixelPackData, PixelUnpackData}; use log::{error, info}; -use std::ffi; use std::mem; use std::ops::BitOr; use std::ops::{Deref, DerefMut}; -use std::ptr; + +static mut CONTEXT: *mut glow::Context = 0 as *mut glow::Context; /// Inits the gl library. This should be called once a context is ready. pub fn init(vid: &glutin::WindowedContext) { - gl::load_with(|s| vid.get_proc_address(s) as *const _); + unsafe { + let context = Box::new(gl::Context::from_loader_function(|s| { + vid.get_proc_address(s) as *const _ + })); + CONTEXT = Box::into_raw(context); + } +} + +fn glow_context() -> &'static glow::Context { + unsafe { CONTEXT.as_ref().unwrap() } } /// Dsed to specify how the vertices will be handled @@ -42,32 +51,20 @@ pub const POINTS: DrawType = gl::POINTS; pub fn draw_arrays(ty: DrawType, offset: usize, count: usize) { unsafe { - gl::DrawArrays(ty, offset as i32, count as i32); + glow_context().draw_arrays(ty, offset as i32, count as i32); } } pub fn draw_elements(ty: DrawType, count: i32, dty: Type, offset: usize) { unsafe { - gl::DrawElements(ty, count, dty, offset as *const gl::types::GLvoid); + glow_context().draw_elements(ty, count, dty, offset as i32); } } -pub fn multi_draw_elements(ty: DrawType, count: &[i32], dty: Type, offsets: &[usize]) { - unsafe { - gl::MultiDrawElements( - ty, - count.as_ptr(), - dty, - offsets.as_ptr() as *const _, - count.len() as i32, - ); - } -} - -/// Sets the size of the viewport of this context. +// Sets the size of the viewport of this context. pub fn viewport(x: i32, y: i32, w: i32, h: i32) { unsafe { - gl::Viewport(x, y, w, h); + glow_context().viewport(x, y, w, h); } } @@ -75,7 +72,7 @@ pub fn viewport(x: i32, y: i32, w: i32, h: i32) { /// when Clear is called with the color flag. pub fn clear_color(r: f32, g: f32, b: f32, a: f32) { unsafe { - gl::ClearColor(r, g, b, a); + glow_context().clear_color(r, g, b, a); } } @@ -109,12 +106,12 @@ impl BitOr for ClearFlags { /// Clears the buffers specified by the passed flags. pub fn clear(flags: ClearFlags) { - unsafe { gl::Clear(flags.internal()) } + unsafe { glow_context().clear(flags.internal()) } } pub fn depth_mask(f: bool) { unsafe { - gl::DepthMask(f as u8); + glow_context().depth_mask(f); } } @@ -130,7 +127,7 @@ pub const EQUAL: Func = gl::EQUAL; pub fn depth_func(f: Func) { unsafe { - gl::DepthFunc(f); + glow_context().depth_func(f); } } @@ -146,14 +143,14 @@ pub const MULTISAMPLE: Flag = gl::MULTISAMPLE; /// Enables the passed flag. pub fn enable(f: Flag) { unsafe { - gl::Enable(f); + glow_context().enable(f); } } /// Disables the passed flag. pub fn disable(f: Flag) { unsafe { - gl::Disable(f); + glow_context().disable(f); } } @@ -161,7 +158,7 @@ pub fn disable(f: Flag) { /// currently active one. pub fn active_texture(id: u32) { unsafe { - gl::ActiveTexture(gl::TEXTURE0 + id); + glow_context().active_texture(gl::TEXTURE0 + id); } } @@ -175,7 +172,7 @@ pub const ZERO_FACTOR: Factor = gl::ZERO; /// Sets the factors to be used when blending. pub fn blend_func(s_factor: Factor, d_factor: Factor) { unsafe { - gl::BlendFunc(s_factor, d_factor); + glow_context().blend_func(s_factor, d_factor); } } @@ -186,7 +183,7 @@ pub fn blend_func_separate( d_factor_a: Factor, ) { unsafe { - gl::BlendFuncSeparate(s_factor_rgb, d_factor_rgb, s_factor_a, d_factor_a); + glow_context().blend_func_separate(s_factor_rgb, d_factor_rgb, s_factor_a, d_factor_a); } } @@ -198,7 +195,7 @@ pub const FRONT: Face = gl::FRONT; /// Sets the face to be culled by the gpu. pub fn cull_face(face: Face) { unsafe { - gl::CullFace(face); + glow_context().cull_face(face); } } @@ -211,7 +208,7 @@ pub const COUNTER_CLOCK_WISE: FaceDirection = gl::CCW; /// Sets the direction of vertices used to specify the /// front face (e.g. for culling). pub fn front_face(dir: FaceDirection) { - unsafe { gl::FrontFace(dir) } + unsafe { glow_context().front_face(dir) } } /// `Type` is a type of data used by various operations. @@ -270,17 +267,17 @@ pub struct Texture(u32); impl Texture { // Allocates a new texture. pub fn new() -> Texture { - let mut t = Texture(0); - unsafe { - gl::GenTextures(1, &mut t.0); - } - t + Texture(unsafe { + glow_context() + .create_texture() + .expect("create texture failed") + }) } /// Binds the texture to the passed target. pub fn bind(&self, target: TextureTarget) { unsafe { - gl::BindTexture(target, self.0); + glow_context().bind_texture(target, Some(self.0)); } } @@ -293,13 +290,7 @@ impl Texture { pixels: &mut [u8], ) { unsafe { - gl::GetTexImage( - target, - level, - format, - ty, - pixels.as_mut_ptr() as *mut gl::types::GLvoid, - ); + glow_context().get_tex_image(target, level, format, ty, PixelPackData::Slice(pixels)); } } @@ -314,11 +305,7 @@ impl Texture { pix: Option<&[u8]>, ) { unsafe { - let ptr = match pix { - Some(val) => val.as_ptr() as *const gl::types::GLvoid, - None => ptr::null(), - }; - gl::TexImage2D( + glow_context().tex_image_2d( target, level, format as i32, @@ -327,7 +314,7 @@ impl Texture { 0, format, ty, - ptr, + pix, ); } } @@ -345,7 +332,7 @@ impl Texture { pix: &[u8], ) { unsafe { - gl::TexSubImage2D( + glow_context().tex_sub_image_2d( target, level, x as i32, @@ -354,7 +341,7 @@ impl Texture { height as i32, format, ty, - pix.as_ptr() as *const _, + PixelUnpackData::Slice(pix), ); } } @@ -371,11 +358,7 @@ impl Texture { pix: Option<&[u8]>, ) { unsafe { - let ptr = match pix { - Some(val) => val.as_ptr() as *const gl::types::GLvoid, - None => ptr::null(), - }; - gl::TexImage2D( + glow_context().tex_image_2d( target, level, internal_format as i32, @@ -384,7 +367,7 @@ impl Texture { 0, format, ty, - ptr, + pix, ); } } @@ -399,25 +382,24 @@ impl Texture { fixed: bool, ) { unsafe { - let result: &mut [i32] = &mut [0; 1]; - gl::GetIntegerv(gl::MAX_SAMPLES, &mut result[0]); - let use_samples = if samples > result[0] { + let result: i32 = glow_context().get_parameter_i32(gl::MAX_SAMPLES); + let use_samples = if samples > result { info!( "glTexImage2DMultisample: requested {} samples but GL_MAX_SAMPLES is {}", - samples, result[0] + samples, result ); - result[0] + result } else { samples }; - - gl::TexImage2DMultisample( + // TODO: switch to glRenderbufferStorageMultisample https://github.com/iceiix/stevenarella/pull/442 + glow_context().tex_image_2d_multisample( target, use_samples, format, width as i32, height as i32, - fixed as u8, + fixed, ); } } @@ -434,7 +416,7 @@ impl Texture { pix: &[u8], ) { unsafe { - gl::TexImage3D( + glow_context().tex_image_3d( target, level, format as i32, @@ -444,7 +426,7 @@ impl Texture { 0, format, ty, - pix.as_ptr() as *const gl::types::GLvoid, + Some(pix), ); } } @@ -464,7 +446,7 @@ impl Texture { pix: &[u8], ) { unsafe { - gl::TexSubImage3D( + glow_context().tex_sub_image_3d( target, level, x as i32, @@ -475,7 +457,7 @@ impl Texture { depth as i32, format, ty, - pix.as_ptr() as *const gl::types::GLvoid, + PixelUnpackData::Slice(pix), ); } } @@ -487,7 +469,7 @@ impl Texture { value: TextureValue, ) { unsafe { - gl::TexParameteri(target, param, value); + glow_context().tex_parameter_i32(target, param, value); } } } @@ -495,7 +477,7 @@ impl Texture { impl Drop for Texture { fn drop(&mut self) { unsafe { - gl::DeleteTextures(1, &self.0); + glow_context().delete_texture(self.0); } } } @@ -516,31 +498,34 @@ pub struct Program(u32); impl Program { pub fn new() -> Program { - Program(unsafe { gl::CreateProgram() }) + Program(unsafe { + glow_context() + .create_program() + .expect("program creation failed") + }) } pub fn attach_shader(&self, shader: Shader) { unsafe { - gl::AttachShader(self.0, shader.0); + glow_context().attach_shader(self.0, shader.0); } } pub fn link(&self) { unsafe { - gl::LinkProgram(self.0); + glow_context().link_program(self.0); } } pub fn use_program(&self) { unsafe { - gl::UseProgram(self.0); + glow_context().use_program(Some(self.0)); } } pub fn uniform_location(&self, name: &str) -> Option { - let c_name = ffi::CString::new(name).unwrap(); - let u = unsafe { gl::GetUniformLocation(self.0, c_name.as_ptr()) }; - if u != -1 { + let u = unsafe { glow_context().get_uniform_location(self.0, name) }; + if let Some(u) = u { Some(Uniform(u)) } else { None @@ -548,12 +533,9 @@ impl Program { } pub fn attribute_location(&self, name: &str) -> Option { - let a = unsafe { - let name_c = ffi::CString::new(name).unwrap(); - gl::GetAttribLocation(self.0, name_c.as_ptr()) - }; - if a != -1 { - Some(Attribute(a)) + let a = unsafe { glow_context().get_attrib_location(self.0, name) }; + if let Some(a) = a { + Some(Attribute(a as i32)) } else { None } @@ -563,7 +545,7 @@ impl Program { impl Drop for Program { fn drop(&mut self) { unsafe { - gl::DeleteProgram(self.0); + glow_context().delete_program(self.0); } } } @@ -572,98 +554,96 @@ pub struct Shader(u32); impl Shader { pub fn new(ty: ShaderType) -> Shader { - Shader(unsafe { gl::CreateShader(ty) }) + Shader(unsafe { + glow_context() + .create_shader(ty) + .expect("failed to create shader") + }) } pub fn set_source(&self, src: &str) { unsafe { - let src_c = ffi::CString::new(src).unwrap(); - gl::ShaderSource(self.0, 1, &src_c.as_ptr(), ptr::null()); + glow_context().shader_source(self.0, src); } } pub fn compile(&self) { unsafe { - gl::CompileShader(self.0); + glow_context().compile_shader(self.0); } } - pub fn get_parameter(&self, param: ShaderParameter) -> i32 { - let mut ret: i32 = 0; - unsafe { - gl::GetShaderiv(self.0, param, &mut ret); - } - ret + pub fn get_shader_compile_status(&self) -> bool { + unsafe { glow_context().get_shader_compile_status(self.0) } } pub fn get_info_log(&self) -> String { - let len = self.get_parameter(INFO_LOG_LENGTH); - - let mut data = Vec::::with_capacity(len as usize); - unsafe { - data.set_len(len as usize); - gl::GetShaderInfoLog(self.0, len, ptr::null_mut(), data.as_mut_ptr() as *mut i8); - } - String::from_utf8(data).unwrap() + unsafe { glow_context().get_shader_info_log(self.0) } } } #[derive(Clone, Copy)] -pub struct Uniform(i32); +pub struct Uniform(u32); impl Uniform { pub fn set_int(&self, val: i32) { unsafe { - gl::Uniform1i(self.0, val); + glow_context().uniform_1_i32(Some(&self.0), val); } } pub fn set_int3(&self, x: i32, y: i32, z: i32) { unsafe { - gl::Uniform3i(self.0, x, y, z); + glow_context().uniform_3_i32(Some(&self.0), x, y, z); } } pub fn set_float(&self, val: f32) { unsafe { - gl::Uniform1f(self.0, val); + glow_context().uniform_1_f32(Some(&self.0), val); } } pub fn set_float2(&self, x: f32, y: f32) { unsafe { - gl::Uniform2f(self.0, x, y); + glow_context().uniform_2_f32(Some(&self.0), x, y); } } pub fn set_float3(&self, x: f32, y: f32, z: f32) { unsafe { - gl::Uniform3f(self.0, x, y, z); + glow_context().uniform_3_f32(Some(&self.0), x, y, z); } } pub fn set_float4(&self, x: f32, y: f32, z: f32, w: f32) { unsafe { - gl::Uniform4f(self.0, x, y, z, w); + glow_context().uniform_4_f32(Some(&self.0), x, y, z, w); } } #[allow(clippy::missing_safety_doc)] pub unsafe fn set_float_multi_raw(&self, data: *const f32, len: usize) { - gl::Uniform4fv(self.0, len as i32, data); + glow_context().uniform_4_f32_slice(Some(&self.0), std::slice::from_raw_parts(data, len)); } pub fn set_matrix4(&self, m: &::cgmath::Matrix4) { - use cgmath::Matrix; unsafe { - gl::UniformMatrix4fv(self.0, 1, false as u8, m.as_ptr()); + glow_context().uniform_matrix_4_f32_slice( + Some(&self.0), + false, + &*(m as *const cgmath::Matrix4 as *const [f32; 4 * 4]), + ); } } pub fn set_matrix4_multi(&self, m: &[::cgmath::Matrix4]) { unsafe { - gl::UniformMatrix4fv(self.0, m.len() as i32, false as u8, m.as_ptr() as *const _); - // TODO: Most likely isn't safe + glow_context().uniform_matrix_4_f32_slice( + Some(&self.0), + false, + std::slice::from_raw_parts(m.as_ptr() as *const _, m.len() * 4 * 4), + ); // TODO: Most likely isn't safe } } } @@ -674,38 +654,32 @@ pub struct Attribute(i32); impl Attribute { pub fn enable(&self) { unsafe { - gl::EnableVertexAttribArray(self.0 as u32); + glow_context().enable_vertex_attrib_array(self.0 as u32); } } pub fn disable(&self) { unsafe { - gl::DisableVertexAttribArray(self.0 as u32); + glow_context().disable_vertex_attrib_array(self.0 as u32); } } pub fn vertex_pointer(&self, size: i32, ty: Type, normalized: bool, stride: i32, offset: i32) { unsafe { - gl::VertexAttribPointer( + glow_context().vertex_attrib_pointer_f32( self.0 as u32, size, ty, - normalized as u8, + normalized, stride, - offset as *const gl::types::GLvoid, + offset, ); } } pub fn vertex_pointer_int(&self, size: i32, ty: Type, stride: i32, offset: i32) { unsafe { - gl::VertexAttribIPointer( - self.0 as u32, - size, - ty, - stride, - offset as *const gl::types::GLvoid, - ); + glow_context().vertex_attrib_pointer_i32(self.0 as u32, size, ty, stride, offset); } } } @@ -719,11 +693,11 @@ pub struct VertexArray(u32); impl VertexArray { /// Allocates a new `VertexArray`. pub fn new() -> VertexArray { - let mut va = VertexArray(0); - unsafe { - gl::GenVertexArrays(1, &mut va.0); - } - va + VertexArray(unsafe { + glow_context() + .create_vertex_array() + .expect("create vertex array failed") + }) } /// Marks the `VertexArray` as the currently active one, this @@ -731,7 +705,7 @@ impl VertexArray { /// this `VertexArray`. pub fn bind(&self) { unsafe { - gl::BindVertexArray(self.0); + glow_context().bind_vertex_array(Some(self.0)); } } } @@ -739,7 +713,7 @@ impl VertexArray { impl Drop for VertexArray { fn drop(&mut self) { unsafe { - gl::DeleteVertexArrays(1, &self.0); + glow_context().delete_vertex_array(self.0); } self.0 = 0; } @@ -780,11 +754,11 @@ pub struct Buffer(u32); impl Buffer { /// Allocates a new Buffer. pub fn new() -> Buffer { - let mut b = Buffer(0); - unsafe { - gl::GenBuffers(1, &mut b.0); - } - b + Buffer(unsafe { + glow_context() + .create_buffer() + .expect("create buffer failed") + }) } /// Makes the buffer the currently active one for the given target. @@ -792,24 +766,19 @@ impl Buffer { /// (Data, Map etc). pub fn bind(&self, target: BufferTarget) { unsafe { - gl::BindBuffer(target, self.0); + glow_context().bind_buffer(target, Some(self.0)); } } pub fn set_data(&self, target: BufferTarget, data: &[u8], usage: BufferUsage) { unsafe { - gl::BufferData( - target, - data.len() as isize, - data.as_ptr() as *const gl::types::GLvoid, - usage, - ); + glow_context().buffer_data_u8_slice(target, data, usage); } } pub fn re_set_data(&self, target: BufferTarget, data: &[u8]) { unsafe { - gl::BufferSubData(target, 0, data.len() as isize, data.as_ptr() as *const _); + glow_context().buffer_sub_data_u8_slice(target, 0, data); } } @@ -823,7 +792,11 @@ impl Buffer { pub fn map(&self, target: BufferTarget, access: Access, length: usize) -> MappedBuffer { unsafe { MappedBuffer { - inner: Vec::from_raw_parts(gl::MapBuffer(target, access) as *mut u8, 0, length), + inner: Vec::from_raw_parts( + glow_context().map_buffer_range(target, 0, length as i32, access) as *mut u8, + 0, + length, + ), target, } } @@ -833,7 +806,7 @@ impl Buffer { impl Drop for Buffer { fn drop(&mut self) { unsafe { - gl::DeleteBuffers(1, &self.0); + glow_context().delete_buffer(self.0); } } } @@ -860,7 +833,7 @@ impl DerefMut for MappedBuffer { impl Drop for MappedBuffer { fn drop(&mut self) { unsafe { - gl::UnmapBuffer(self.target); + glow_context().unmap_buffer(self.target); } mem::forget(mem::replace(&mut self.inner, Vec::new())); } @@ -879,7 +852,7 @@ pub struct Framebuffer(u32); pub fn check_framebuffer_status() { unsafe { - let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER); + let status = glow_context().check_framebuffer_status(gl::FRAMEBUFFER); let s = match status { gl::FRAMEBUFFER_UNDEFINED => "GL_FRAMEBUFFER_UNDEFINED", gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT => "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", @@ -909,7 +882,7 @@ pub fn check_framebuffer_status() { pub fn check_gl_error() { unsafe { loop { - let err = gl::GetError(); + let err = glow_context().get_error(); if err == gl::NO_ERROR { break; } @@ -921,28 +894,28 @@ pub fn check_gl_error() { impl Framebuffer { pub fn new() -> Framebuffer { - let mut fb = Framebuffer(0); - unsafe { - gl::GenFramebuffers(1, &mut fb.0); - } - fb + Framebuffer(unsafe { + glow_context() + .create_framebuffer() + .expect("create framebuffer failed") + }) } pub fn bind(&self) { unsafe { - gl::BindFramebuffer(gl::FRAMEBUFFER, self.0); + glow_context().bind_framebuffer(gl::FRAMEBUFFER, Some(self.0)); } } pub fn bind_read(&self) { unsafe { - gl::BindFramebuffer(gl::READ_FRAMEBUFFER, self.0); + glow_context().bind_framebuffer(gl::READ_FRAMEBUFFER, Some(self.0)); } } pub fn bind_draw(&self) { unsafe { - gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, self.0); + glow_context().bind_framebuffer(gl::DRAW_FRAMEBUFFER, Some(self.0)); } } @@ -954,7 +927,13 @@ impl Framebuffer { level: i32, ) { unsafe { - gl::FramebufferTexture2D(gl::FRAMEBUFFER, attachment, target, tex.0, level); + glow_context().framebuffer_texture_2d( + gl::FRAMEBUFFER, + attachment, + target, + Some(tex.0), + level, + ); } } } @@ -962,40 +941,37 @@ impl Framebuffer { impl Drop for Framebuffer { fn drop(&mut self) { unsafe { - gl::DeleteFramebuffers(1, &self.0); + glow_context().delete_framebuffer(self.0); } } } pub fn unbind_framebuffer() { unsafe { - gl::BindFramebuffer(gl::FRAMEBUFFER, 0); + glow_context().bind_framebuffer(gl::FRAMEBUFFER, None); } } pub fn unbind_framebuffer_read() { unsafe { - gl::BindFramebuffer(gl::READ_FRAMEBUFFER, 0); + glow_context().bind_framebuffer(gl::READ_FRAMEBUFFER, None); } } pub fn unbind_framebuffer_draw() { unsafe { - gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, 0); + glow_context().bind_framebuffer(gl::DRAW_FRAMEBUFFER, None); } } pub fn draw_buffers(bufs: &[Attachment]) { unsafe { - gl::DrawBuffers(bufs.len() as i32, bufs.as_ptr()); + glow_context().draw_buffers(bufs); } } pub fn bind_frag_data_location(p: &Program, cn: u32, name: &str) { - unsafe { - let name_c = ffi::CString::new(name).unwrap(); - gl::BindFragDataLocation(p.0, cn, name_c.as_ptr()); - } + unsafe { glow_context().bind_frag_data_location(p.0, cn, name) } } pub fn blit_framebuffer( @@ -1011,7 +987,7 @@ pub fn blit_framebuffer( filter: TextureValue, ) { unsafe { - gl::BlitFramebuffer( + glow_context().blit_framebuffer( sx0, sy0, sx1, @@ -1026,17 +1002,12 @@ pub fn blit_framebuffer( } } -pub fn read_buffer(a: Attachment) { - unsafe { - gl::ReadBuffer(a); - } -} - pub type TargetBuffer = u32; pub const COLOR: TargetBuffer = gl::COLOR; -pub fn clear_buffer(buffer: TargetBuffer, draw_buffer: i32, values: &[f32]) { +pub fn clear_buffer(buffer: TargetBuffer, draw_buffer: u32, values: &mut [f32]) { unsafe { - gl::ClearBufferfv(buffer, draw_buffer, values.as_ptr()); + // TODO: why does glow have &mut on clear buffer values, why would it change the color? + glow_context().clear_buffer_f32_slice(buffer, draw_buffer, values); } } diff --git a/src/render/clouds.rs b/src/render/clouds.rs index c3d102f..a2fd829 100644 --- a/src/render/clouds.rs +++ b/src/render/clouds.rs @@ -46,7 +46,7 @@ impl Clouds { v.set_source(&vertex); v.compile(); - if v.get_parameter(gl::COMPILE_STATUS) == 0 { + if !v.get_shader_compile_status() { error!("Src: {}", vertex); panic!("Shader error: {}", v.get_info_log()); } else { @@ -61,7 +61,7 @@ impl Clouds { g.set_source(&geo); g.compile(); - if g.get_parameter(gl::COMPILE_STATUS) == 0 { + if !g.get_shader_compile_status() { error!("Src: {}", geo); panic!("Shader error: {}", g.get_info_log()); } else { @@ -76,7 +76,7 @@ impl Clouds { f.set_source(&fragment); f.compile(); - if f.get_parameter(gl::COMPILE_STATUS) == 0 { + if !f.get_shader_compile_status() { error!("Src: {}", fragment); panic!("Shader error: {}", f.get_info_log()); } else { diff --git a/src/render/mod.rs b/src/render/mod.rs index 0374090..163e33e 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -412,8 +412,8 @@ impl Renderer { trans.trans.bind(); gl::clear_color(0.0, 0.0, 0.0, 1.0); gl::clear(gl::ClearFlags::Color); - gl::clear_buffer(gl::COLOR, 0, &[0.0, 0.0, 0.0, 1.0]); - gl::clear_buffer(gl::COLOR, 1, &[0.0, 0.0, 0.0, 0.0]); + gl::clear_buffer(gl::COLOR, 0, &mut [0.0, 0.0, 0.0, 1.0]); + gl::clear_buffer(gl::COLOR, 1, &mut [0.0, 0.0, 0.0, 0.0]); gl::blend_func_separate( gl::ONE_FACTOR, gl::ONE_FACTOR, diff --git a/src/render/shaders.rs b/src/render/shaders.rs index bdd2f7c..050ac95 100644 --- a/src/render/shaders.rs +++ b/src/render/shaders.rs @@ -131,7 +131,7 @@ pub fn create_program(vertex: &str, fragment: &str) -> gl::Program { v.set_source(vertex); v.compile(); - if v.get_parameter(gl::COMPILE_STATUS) == 0 { + if !v.get_shader_compile_status() { error!("Src: {}", vertex); panic!("Shader error: {}", v.get_info_log()); } else { @@ -146,7 +146,7 @@ pub fn create_program(vertex: &str, fragment: &str) -> gl::Program { f.set_source(fragment); f.compile(); - if f.get_parameter(gl::COMPILE_STATUS) == 0 { + if !f.get_shader_compile_status() { error!("Src: {}", fragment); panic!("Shader error: {}", f.get_info_log()); } else {