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:
parent
9700ffe34d
commit
0aa062f4b8
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
|
@ -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"
|
15
gl/build.rs
15
gl/build.rs
|
@ -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();
|
||||
}
|
|
@ -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"));
|
333
src/gl/mod.rs
333
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<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
|
||||
|
@ -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<Uniform> {
|
||||
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<Attribute> {
|
||||
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::<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()
|
||||
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<f32>) {
|
||||
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<f32> as *const [f32; 4 * 4]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_matrix4_multi(&self, m: &[::cgmath::Matrix4<f32>]) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue