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<u32>
* 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
This commit is contained in:
iceiix 2020-12-25 10:00:22 -08:00 committed by GitHub
parent 9700ffe34d
commit 0aa062f4b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 178 additions and 290 deletions

28
Cargo.lock generated
View File

@ -827,6 +827,17 @@ dependencies = [
"xml-rs", "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]] [[package]]
name = "glutin" name = "glutin"
version = "0.26.0" version = "0.26.0"
@ -2270,6 +2281,12 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "slotmap"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c46a3482db8f247956e464d783693ece164ca056e6e67563ee5505bdb86452cd"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "0.6.13" version = "0.6.13"
@ -2389,15 +2406,6 @@ dependencies = [
"steven_shared", "steven_shared",
] ]
[[package]]
name = "steven_gl"
version = "0.0.1"
dependencies = [
"gl_generator",
"khronos_api",
"libc",
]
[[package]] [[package]]
name = "steven_protocol" name = "steven_protocol"
version = "0.0.1" version = "0.0.1"
@ -2436,6 +2444,7 @@ dependencies = [
"clipboard", "clipboard",
"collision", "collision",
"flate2", "flate2",
"glow",
"glutin", "glutin",
"image", "image",
"lazy_static", "lazy_static",
@ -2449,7 +2458,6 @@ dependencies = [
"std_or_web", "std_or_web",
"stdweb", "stdweb",
"steven_blocks", "steven_blocks",
"steven_gl",
"steven_protocol", "steven_protocol",
"steven_resources", "steven_resources",
"steven_shared", "steven_shared",

View File

@ -21,6 +21,7 @@ opt-level = 1
cfg-if = "1.0.0" cfg-if = "1.0.0"
wasm-bindgen = "0.2.69" wasm-bindgen = "0.2.69"
glutin = "0.26.0" glutin = "0.26.0"
glow = { git = "https://github.com/iceiix/glow", rev = "45c808678735e03737d5e1b9d6ed0e21070edcd9" }
byteorder = "1.3.4" byteorder = "1.3.4"
serde = "1.0.118" serde = "1.0.118"
serde_json = "1.0.60" serde_json = "1.0.60"
@ -46,10 +47,6 @@ reqwest = { version = "0.10.10", features = [ "blocking" ]}
stdweb = "0.4.20" stdweb = "0.4.20"
winit = { version = "0.24.0", features = [ "stdweb" ]} winit = { version = "0.24.0", features = [ "stdweb" ]}
[dependencies.steven_gl]
path = "./gl"
version = "0"
[dependencies.steven_resources] [dependencies.steven_resources]
path = "./resources" path = "./resources"
version = "0" version = "0"

56
gl/Cargo.lock generated
View File

@ -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"

View File

@ -1,13 +0,0 @@
[package]
name = "steven_gl"
version = "0.0.1"
authors = [ "Thinkofdeath <thinkofdeath@spigotmc.org>" ]
edition = "2018"
build = "build.rs"
[build-dependencies]
gl_generator = "0.14.0"
khronos_api = "3.1.0"
[dependencies]
libc = "0.2.71"

View File

@ -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();
}

View File

@ -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"));

View File

@ -12,18 +12,27 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
extern crate steven_gl as gl; use glow as gl;
use glow::{HasContext, PixelPackData, PixelUnpackData};
use log::{error, info}; use log::{error, info};
use std::ffi;
use std::mem; use std::mem;
use std::ops::BitOr; use std::ops::BitOr;
use std::ops::{Deref, DerefMut}; 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. /// Inits the gl library. This should be called once a context is ready.
pub fn init(vid: &glutin::WindowedContext<glutin::PossiblyCurrent>) { pub fn init(vid: &glutin::WindowedContext<glutin::PossiblyCurrent>) {
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 /// 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) { pub fn draw_arrays(ty: DrawType, offset: usize, count: usize) {
unsafe { 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) { pub fn draw_elements(ty: DrawType, count: i32, dty: Type, offset: usize) {
unsafe { 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]) { // Sets the size of the viewport of this context.
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.
pub fn viewport(x: i32, y: i32, w: i32, h: i32) { pub fn viewport(x: i32, y: i32, w: i32, h: i32) {
unsafe { 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. /// when Clear is called with the color flag.
pub fn clear_color(r: f32, g: f32, b: f32, a: f32) { pub fn clear_color(r: f32, g: f32, b: f32, a: f32) {
unsafe { 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. /// Clears the buffers specified by the passed flags.
pub fn clear(flags: ClearFlags) { pub fn clear(flags: ClearFlags) {
unsafe { gl::Clear(flags.internal()) } unsafe { glow_context().clear(flags.internal()) }
} }
pub fn depth_mask(f: bool) { pub fn depth_mask(f: bool) {
unsafe { 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) { pub fn depth_func(f: Func) {
unsafe { unsafe {
gl::DepthFunc(f); glow_context().depth_func(f);
} }
} }
@ -146,14 +143,14 @@ pub const MULTISAMPLE: Flag = gl::MULTISAMPLE;
/// Enables the passed flag. /// Enables the passed flag.
pub fn enable(f: Flag) { pub fn enable(f: Flag) {
unsafe { unsafe {
gl::Enable(f); glow_context().enable(f);
} }
} }
/// Disables the passed flag. /// Disables the passed flag.
pub fn disable(f: Flag) { pub fn disable(f: Flag) {
unsafe { unsafe {
gl::Disable(f); glow_context().disable(f);
} }
} }
@ -161,7 +158,7 @@ pub fn disable(f: Flag) {
/// currently active one. /// currently active one.
pub fn active_texture(id: u32) { pub fn active_texture(id: u32) {
unsafe { 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. /// Sets the factors to be used when blending.
pub fn blend_func(s_factor: Factor, d_factor: Factor) { pub fn blend_func(s_factor: Factor, d_factor: Factor) {
unsafe { 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, d_factor_a: Factor,
) { ) {
unsafe { 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. /// Sets the face to be culled by the gpu.
pub fn cull_face(face: Face) { pub fn cull_face(face: Face) {
unsafe { 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 /// Sets the direction of vertices used to specify the
/// front face (e.g. for culling). /// front face (e.g. for culling).
pub fn front_face(dir: FaceDirection) { 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. /// `Type` is a type of data used by various operations.
@ -270,17 +267,17 @@ pub struct Texture(u32);
impl Texture { impl Texture {
// Allocates a new texture. // Allocates a new texture.
pub fn new() -> Texture { pub fn new() -> Texture {
let mut t = Texture(0); Texture(unsafe {
unsafe { glow_context()
gl::GenTextures(1, &mut t.0); .create_texture()
} .expect("create texture failed")
t })
} }
/// Binds the texture to the passed target. /// Binds the texture to the passed target.
pub fn bind(&self, target: TextureTarget) { pub fn bind(&self, target: TextureTarget) {
unsafe { unsafe {
gl::BindTexture(target, self.0); glow_context().bind_texture(target, Some(self.0));
} }
} }
@ -293,13 +290,7 @@ impl Texture {
pixels: &mut [u8], pixels: &mut [u8],
) { ) {
unsafe { unsafe {
gl::GetTexImage( glow_context().get_tex_image(target, level, format, ty, PixelPackData::Slice(pixels));
target,
level,
format,
ty,
pixels.as_mut_ptr() as *mut gl::types::GLvoid,
);
} }
} }
@ -314,11 +305,7 @@ impl Texture {
pix: Option<&[u8]>, pix: Option<&[u8]>,
) { ) {
unsafe { unsafe {
let ptr = match pix { glow_context().tex_image_2d(
Some(val) => val.as_ptr() as *const gl::types::GLvoid,
None => ptr::null(),
};
gl::TexImage2D(
target, target,
level, level,
format as i32, format as i32,
@ -327,7 +314,7 @@ impl Texture {
0, 0,
format, format,
ty, ty,
ptr, pix,
); );
} }
} }
@ -345,7 +332,7 @@ impl Texture {
pix: &[u8], pix: &[u8],
) { ) {
unsafe { unsafe {
gl::TexSubImage2D( glow_context().tex_sub_image_2d(
target, target,
level, level,
x as i32, x as i32,
@ -354,7 +341,7 @@ impl Texture {
height as i32, height as i32,
format, format,
ty, ty,
pix.as_ptr() as *const _, PixelUnpackData::Slice(pix),
); );
} }
} }
@ -371,11 +358,7 @@ impl Texture {
pix: Option<&[u8]>, pix: Option<&[u8]>,
) { ) {
unsafe { unsafe {
let ptr = match pix { glow_context().tex_image_2d(
Some(val) => val.as_ptr() as *const gl::types::GLvoid,
None => ptr::null(),
};
gl::TexImage2D(
target, target,
level, level,
internal_format as i32, internal_format as i32,
@ -384,7 +367,7 @@ impl Texture {
0, 0,
format, format,
ty, ty,
ptr, pix,
); );
} }
} }
@ -399,25 +382,24 @@ impl Texture {
fixed: bool, fixed: bool,
) { ) {
unsafe { unsafe {
let result: &mut [i32] = &mut [0; 1]; let result: i32 = glow_context().get_parameter_i32(gl::MAX_SAMPLES);
gl::GetIntegerv(gl::MAX_SAMPLES, &mut result[0]); let use_samples = if samples > result {
let use_samples = if samples > result[0] {
info!( info!(
"glTexImage2DMultisample: requested {} samples but GL_MAX_SAMPLES is {}", "glTexImage2DMultisample: requested {} samples but GL_MAX_SAMPLES is {}",
samples, result[0] samples, result
); );
result[0] result
} else { } else {
samples samples
}; };
// TODO: switch to glRenderbufferStorageMultisample https://github.com/iceiix/stevenarella/pull/442
gl::TexImage2DMultisample( glow_context().tex_image_2d_multisample(
target, target,
use_samples, use_samples,
format, format,
width as i32, width as i32,
height as i32, height as i32,
fixed as u8, fixed,
); );
} }
} }
@ -434,7 +416,7 @@ impl Texture {
pix: &[u8], pix: &[u8],
) { ) {
unsafe { unsafe {
gl::TexImage3D( glow_context().tex_image_3d(
target, target,
level, level,
format as i32, format as i32,
@ -444,7 +426,7 @@ impl Texture {
0, 0,
format, format,
ty, ty,
pix.as_ptr() as *const gl::types::GLvoid, Some(pix),
); );
} }
} }
@ -464,7 +446,7 @@ impl Texture {
pix: &[u8], pix: &[u8],
) { ) {
unsafe { unsafe {
gl::TexSubImage3D( glow_context().tex_sub_image_3d(
target, target,
level, level,
x as i32, x as i32,
@ -475,7 +457,7 @@ impl Texture {
depth as i32, depth as i32,
format, format,
ty, ty,
pix.as_ptr() as *const gl::types::GLvoid, PixelUnpackData::Slice(pix),
); );
} }
} }
@ -487,7 +469,7 @@ impl Texture {
value: TextureValue, value: TextureValue,
) { ) {
unsafe { unsafe {
gl::TexParameteri(target, param, value); glow_context().tex_parameter_i32(target, param, value);
} }
} }
} }
@ -495,7 +477,7 @@ impl Texture {
impl Drop for Texture { impl Drop for Texture {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gl::DeleteTextures(1, &self.0); glow_context().delete_texture(self.0);
} }
} }
} }
@ -516,31 +498,34 @@ pub struct Program(u32);
impl Program { impl Program {
pub fn new() -> 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) { pub fn attach_shader(&self, shader: Shader) {
unsafe { unsafe {
gl::AttachShader(self.0, shader.0); glow_context().attach_shader(self.0, shader.0);
} }
} }
pub fn link(&self) { pub fn link(&self) {
unsafe { unsafe {
gl::LinkProgram(self.0); glow_context().link_program(self.0);
} }
} }
pub fn use_program(&self) { pub fn use_program(&self) {
unsafe { unsafe {
gl::UseProgram(self.0); glow_context().use_program(Some(self.0));
} }
} }
pub fn uniform_location(&self, name: &str) -> Option<Uniform> { pub fn uniform_location(&self, name: &str) -> Option<Uniform> {
let c_name = ffi::CString::new(name).unwrap(); let u = unsafe { glow_context().get_uniform_location(self.0, name) };
let u = unsafe { gl::GetUniformLocation(self.0, c_name.as_ptr()) }; if let Some(u) = u {
if u != -1 {
Some(Uniform(u)) Some(Uniform(u))
} else { } else {
None None
@ -548,12 +533,9 @@ impl Program {
} }
pub fn attribute_location(&self, name: &str) -> Option<Attribute> { pub fn attribute_location(&self, name: &str) -> Option<Attribute> {
let a = unsafe { let a = unsafe { glow_context().get_attrib_location(self.0, name) };
let name_c = ffi::CString::new(name).unwrap(); if let Some(a) = a {
gl::GetAttribLocation(self.0, name_c.as_ptr()) Some(Attribute(a as i32))
};
if a != -1 {
Some(Attribute(a))
} else { } else {
None None
} }
@ -563,7 +545,7 @@ impl Program {
impl Drop for Program { impl Drop for Program {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gl::DeleteProgram(self.0); glow_context().delete_program(self.0);
} }
} }
} }
@ -572,98 +554,96 @@ pub struct Shader(u32);
impl Shader { impl Shader {
pub fn new(ty: ShaderType) -> 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) { pub fn set_source(&self, src: &str) {
unsafe { unsafe {
let src_c = ffi::CString::new(src).unwrap(); glow_context().shader_source(self.0, src);
gl::ShaderSource(self.0, 1, &src_c.as_ptr(), ptr::null());
} }
} }
pub fn compile(&self) { pub fn compile(&self) {
unsafe { unsafe {
gl::CompileShader(self.0); glow_context().compile_shader(self.0);
} }
} }
pub fn get_parameter(&self, param: ShaderParameter) -> i32 { pub fn get_shader_compile_status(&self) -> bool {
let mut ret: i32 = 0; unsafe { glow_context().get_shader_compile_status(self.0) }
unsafe {
gl::GetShaderiv(self.0, param, &mut ret);
}
ret
} }
pub fn get_info_log(&self) -> String { pub fn get_info_log(&self) -> String {
let len = self.get_parameter(INFO_LOG_LENGTH); unsafe { glow_context().get_shader_info_log(self.0) }
let mut data = Vec::<u8>::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()
} }
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Uniform(i32); pub struct Uniform(u32);
impl Uniform { impl Uniform {
pub fn set_int(&self, val: i32) { pub fn set_int(&self, val: i32) {
unsafe { 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) { pub fn set_int3(&self, x: i32, y: i32, z: i32) {
unsafe { 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) { pub fn set_float(&self, val: f32) {
unsafe { unsafe {
gl::Uniform1f(self.0, val); glow_context().uniform_1_f32(Some(&self.0), val);
} }
} }
pub fn set_float2(&self, x: f32, y: f32) { pub fn set_float2(&self, x: f32, y: f32) {
unsafe { 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) { pub fn set_float3(&self, x: f32, y: f32, z: f32) {
unsafe { 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) { pub fn set_float4(&self, x: f32, y: f32, z: f32, w: f32) {
unsafe { 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)] #[allow(clippy::missing_safety_doc)]
pub unsafe fn set_float_multi_raw(&self, data: *const f32, len: usize) { 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<f32>) { pub fn set_matrix4(&self, m: &::cgmath::Matrix4<f32>) {
use cgmath::Matrix;
unsafe { 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<f32> as *const [f32; 4 * 4]),
);
} }
} }
pub fn set_matrix4_multi(&self, m: &[::cgmath::Matrix4<f32>]) { pub fn set_matrix4_multi(&self, m: &[::cgmath::Matrix4<f32>]) {
unsafe { unsafe {
gl::UniformMatrix4fv(self.0, m.len() as i32, false as u8, m.as_ptr() as *const _); glow_context().uniform_matrix_4_f32_slice(
// TODO: Most likely isn't safe 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 { impl Attribute {
pub fn enable(&self) { pub fn enable(&self) {
unsafe { unsafe {
gl::EnableVertexAttribArray(self.0 as u32); glow_context().enable_vertex_attrib_array(self.0 as u32);
} }
} }
pub fn disable(&self) { pub fn disable(&self) {
unsafe { 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) { pub fn vertex_pointer(&self, size: i32, ty: Type, normalized: bool, stride: i32, offset: i32) {
unsafe { unsafe {
gl::VertexAttribPointer( glow_context().vertex_attrib_pointer_f32(
self.0 as u32, self.0 as u32,
size, size,
ty, ty,
normalized as u8, normalized,
stride, stride,
offset as *const gl::types::GLvoid, offset,
); );
} }
} }
pub fn vertex_pointer_int(&self, size: i32, ty: Type, stride: i32, offset: i32) { pub fn vertex_pointer_int(&self, size: i32, ty: Type, stride: i32, offset: i32) {
unsafe { unsafe {
gl::VertexAttribIPointer( glow_context().vertex_attrib_pointer_i32(self.0 as u32, size, ty, stride, offset);
self.0 as u32,
size,
ty,
stride,
offset as *const gl::types::GLvoid,
);
} }
} }
} }
@ -719,11 +693,11 @@ pub struct VertexArray(u32);
impl VertexArray { impl VertexArray {
/// Allocates a new `VertexArray`. /// Allocates a new `VertexArray`.
pub fn new() -> VertexArray { pub fn new() -> VertexArray {
let mut va = VertexArray(0); VertexArray(unsafe {
unsafe { glow_context()
gl::GenVertexArrays(1, &mut va.0); .create_vertex_array()
} .expect("create vertex array failed")
va })
} }
/// Marks the `VertexArray` as the currently active one, this /// Marks the `VertexArray` as the currently active one, this
@ -731,7 +705,7 @@ impl VertexArray {
/// this `VertexArray`. /// this `VertexArray`.
pub fn bind(&self) { pub fn bind(&self) {
unsafe { unsafe {
gl::BindVertexArray(self.0); glow_context().bind_vertex_array(Some(self.0));
} }
} }
} }
@ -739,7 +713,7 @@ impl VertexArray {
impl Drop for VertexArray { impl Drop for VertexArray {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gl::DeleteVertexArrays(1, &self.0); glow_context().delete_vertex_array(self.0);
} }
self.0 = 0; self.0 = 0;
} }
@ -780,11 +754,11 @@ pub struct Buffer(u32);
impl Buffer { impl Buffer {
/// Allocates a new Buffer. /// Allocates a new Buffer.
pub fn new() -> Buffer { pub fn new() -> Buffer {
let mut b = Buffer(0); Buffer(unsafe {
unsafe { glow_context()
gl::GenBuffers(1, &mut b.0); .create_buffer()
} .expect("create buffer failed")
b })
} }
/// Makes the buffer the currently active one for the given target. /// Makes the buffer the currently active one for the given target.
@ -792,24 +766,19 @@ impl Buffer {
/// (Data, Map etc). /// (Data, Map etc).
pub fn bind(&self, target: BufferTarget) { pub fn bind(&self, target: BufferTarget) {
unsafe { 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) { pub fn set_data(&self, target: BufferTarget, data: &[u8], usage: BufferUsage) {
unsafe { unsafe {
gl::BufferData( glow_context().buffer_data_u8_slice(target, data, usage);
target,
data.len() as isize,
data.as_ptr() as *const gl::types::GLvoid,
usage,
);
} }
} }
pub fn re_set_data(&self, target: BufferTarget, data: &[u8]) { pub fn re_set_data(&self, target: BufferTarget, data: &[u8]) {
unsafe { 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 { pub fn map(&self, target: BufferTarget, access: Access, length: usize) -> MappedBuffer {
unsafe { unsafe {
MappedBuffer { 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, target,
} }
} }
@ -833,7 +806,7 @@ impl Buffer {
impl Drop for Buffer { impl Drop for Buffer {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gl::DeleteBuffers(1, &self.0); glow_context().delete_buffer(self.0);
} }
} }
} }
@ -860,7 +833,7 @@ impl DerefMut for MappedBuffer {
impl Drop for MappedBuffer { impl Drop for MappedBuffer {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gl::UnmapBuffer(self.target); glow_context().unmap_buffer(self.target);
} }
mem::forget(mem::replace(&mut self.inner, Vec::new())); mem::forget(mem::replace(&mut self.inner, Vec::new()));
} }
@ -879,7 +852,7 @@ pub struct Framebuffer(u32);
pub fn check_framebuffer_status() { pub fn check_framebuffer_status() {
unsafe { unsafe {
let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER); let status = glow_context().check_framebuffer_status(gl::FRAMEBUFFER);
let s = match status { let s = match status {
gl::FRAMEBUFFER_UNDEFINED => "GL_FRAMEBUFFER_UNDEFINED", gl::FRAMEBUFFER_UNDEFINED => "GL_FRAMEBUFFER_UNDEFINED",
gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT => "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT => "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
@ -909,7 +882,7 @@ pub fn check_framebuffer_status() {
pub fn check_gl_error() { pub fn check_gl_error() {
unsafe { unsafe {
loop { loop {
let err = gl::GetError(); let err = glow_context().get_error();
if err == gl::NO_ERROR { if err == gl::NO_ERROR {
break; break;
} }
@ -921,28 +894,28 @@ pub fn check_gl_error() {
impl Framebuffer { impl Framebuffer {
pub fn new() -> Framebuffer { pub fn new() -> Framebuffer {
let mut fb = Framebuffer(0); Framebuffer(unsafe {
unsafe { glow_context()
gl::GenFramebuffers(1, &mut fb.0); .create_framebuffer()
} .expect("create framebuffer failed")
fb })
} }
pub fn bind(&self) { pub fn bind(&self) {
unsafe { unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, self.0); glow_context().bind_framebuffer(gl::FRAMEBUFFER, Some(self.0));
} }
} }
pub fn bind_read(&self) { pub fn bind_read(&self) {
unsafe { unsafe {
gl::BindFramebuffer(gl::READ_FRAMEBUFFER, self.0); glow_context().bind_framebuffer(gl::READ_FRAMEBUFFER, Some(self.0));
} }
} }
pub fn bind_draw(&self) { pub fn bind_draw(&self) {
unsafe { 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, level: i32,
) { ) {
unsafe { 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 { impl Drop for Framebuffer {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gl::DeleteFramebuffers(1, &self.0); glow_context().delete_framebuffer(self.0);
} }
} }
} }
pub fn unbind_framebuffer() { pub fn unbind_framebuffer() {
unsafe { unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, 0); glow_context().bind_framebuffer(gl::FRAMEBUFFER, None);
} }
} }
pub fn unbind_framebuffer_read() { pub fn unbind_framebuffer_read() {
unsafe { unsafe {
gl::BindFramebuffer(gl::READ_FRAMEBUFFER, 0); glow_context().bind_framebuffer(gl::READ_FRAMEBUFFER, None);
} }
} }
pub fn unbind_framebuffer_draw() { pub fn unbind_framebuffer_draw() {
unsafe { unsafe {
gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, 0); glow_context().bind_framebuffer(gl::DRAW_FRAMEBUFFER, None);
} }
} }
pub fn draw_buffers(bufs: &[Attachment]) { pub fn draw_buffers(bufs: &[Attachment]) {
unsafe { 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) { pub fn bind_frag_data_location(p: &Program, cn: u32, name: &str) {
unsafe { unsafe { glow_context().bind_frag_data_location(p.0, cn, name) }
let name_c = ffi::CString::new(name).unwrap();
gl::BindFragDataLocation(p.0, cn, name_c.as_ptr());
}
} }
pub fn blit_framebuffer( pub fn blit_framebuffer(
@ -1011,7 +987,7 @@ pub fn blit_framebuffer(
filter: TextureValue, filter: TextureValue,
) { ) {
unsafe { unsafe {
gl::BlitFramebuffer( glow_context().blit_framebuffer(
sx0, sx0,
sy0, sy0,
sx1, sx1,
@ -1026,17 +1002,12 @@ pub fn blit_framebuffer(
} }
} }
pub fn read_buffer(a: Attachment) {
unsafe {
gl::ReadBuffer(a);
}
}
pub type TargetBuffer = u32; pub type TargetBuffer = u32;
pub const COLOR: TargetBuffer = gl::COLOR; 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 { 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);
} }
} }

View File

@ -46,7 +46,7 @@ impl Clouds {
v.set_source(&vertex); v.set_source(&vertex);
v.compile(); v.compile();
if v.get_parameter(gl::COMPILE_STATUS) == 0 { if !v.get_shader_compile_status() {
error!("Src: {}", vertex); error!("Src: {}", vertex);
panic!("Shader error: {}", v.get_info_log()); panic!("Shader error: {}", v.get_info_log());
} else { } else {
@ -61,7 +61,7 @@ impl Clouds {
g.set_source(&geo); g.set_source(&geo);
g.compile(); g.compile();
if g.get_parameter(gl::COMPILE_STATUS) == 0 { if !g.get_shader_compile_status() {
error!("Src: {}", geo); error!("Src: {}", geo);
panic!("Shader error: {}", g.get_info_log()); panic!("Shader error: {}", g.get_info_log());
} else { } else {
@ -76,7 +76,7 @@ impl Clouds {
f.set_source(&fragment); f.set_source(&fragment);
f.compile(); f.compile();
if f.get_parameter(gl::COMPILE_STATUS) == 0 { if !f.get_shader_compile_status() {
error!("Src: {}", fragment); error!("Src: {}", fragment);
panic!("Shader error: {}", f.get_info_log()); panic!("Shader error: {}", f.get_info_log());
} else { } else {

View File

@ -412,8 +412,8 @@ impl Renderer {
trans.trans.bind(); trans.trans.bind();
gl::clear_color(0.0, 0.0, 0.0, 1.0); gl::clear_color(0.0, 0.0, 0.0, 1.0);
gl::clear(gl::ClearFlags::Color); gl::clear(gl::ClearFlags::Color);
gl::clear_buffer(gl::COLOR, 0, &[0.0, 0.0, 0.0, 1.0]); gl::clear_buffer(gl::COLOR, 0, &mut [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, 1, &mut [0.0, 0.0, 0.0, 0.0]);
gl::blend_func_separate( gl::blend_func_separate(
gl::ONE_FACTOR, gl::ONE_FACTOR,
gl::ONE_FACTOR, gl::ONE_FACTOR,

View File

@ -131,7 +131,7 @@ pub fn create_program(vertex: &str, fragment: &str) -> gl::Program {
v.set_source(vertex); v.set_source(vertex);
v.compile(); v.compile();
if v.get_parameter(gl::COMPILE_STATUS) == 0 { if !v.get_shader_compile_status() {
error!("Src: {}", vertex); error!("Src: {}", vertex);
panic!("Shader error: {}", v.get_info_log()); panic!("Shader error: {}", v.get_info_log());
} else { } else {
@ -146,7 +146,7 @@ pub fn create_program(vertex: &str, fragment: &str) -> gl::Program {
f.set_source(fragment); f.set_source(fragment);
f.compile(); f.compile();
if f.get_parameter(gl::COMPILE_STATUS) == 0 { if !f.get_shader_compile_status() {
error!("Src: {}", fragment); error!("Src: {}", fragment);
panic!("Shader error: {}", f.get_info_log()); panic!("Shader error: {}", f.get_info_log());
} else { } else {