Skip to content

Commit cd37ebb

Browse files
Revamp core types, add several more functions
Revamped: - Types - Removed `From` impl - Converted wrapper structs to macro - Added macro for converting primitives with GL type aliases - Removed extraneous error types, added proper enum to `ObjectCreationError` Added: - functions and enum for enable/disable - functions and wrapper for uniforms
1 parent e94026f commit cd37ebb

File tree

10 files changed

+897
-220
lines changed

10 files changed

+897
-220
lines changed

crates/core/src/errors.rs

+26-49
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,36 @@
1-
use gl::types::*;
2-
use thiserror::Error;
3-
4-
5-
/// The error returned when attempting to convert a raw [`GLenum`] into an actual Rust enum fails. This can happen when
6-
/// the given `GLenum` value does not match any variants.
7-
#[derive(Error, Debug)]
8-
#[error("could not convert `GLenum` value '{original_value:#X}' into enum of type `{attempted_type}`")]
9-
pub struct EnumConversionError {
10-
original_value: GLenum,
11-
attempted_type: &'static str,
12-
}
13-
14-
impl EnumConversionError {
15-
pub(crate) const fn new(value: GLenum, name: &'static str) -> Self {
16-
Self {
17-
original_value: value,
18-
attempted_type: name,
19-
}
20-
}
21-
}
22-
23-
24-
/// The error returned when attempting to convert a raw [`GLbitfield`] into an actual Rust struct fails. This can happen
25-
/// when the given `GLbitfield` value does not
26-
#[derive(Error, Debug)]
27-
#[error("could not convert `GLbitfield` value '{original_value:#b}' into struct of type `{attempted_type}`")]
28-
pub struct BitfieldConversionError {
29-
original_value: GLbitfield,
30-
attempted_type: &'static str,
31-
}
32-
33-
impl BitfieldConversionError {
34-
pub(crate) const fn new(value: GLbitfield, name: &'static str) -> Self {
35-
Self {
36-
original_value: value,
37-
attempted_type: name,
38-
}
39-
}
40-
}
1+
use std::fmt;
412

3+
use thiserror::Error;
424

43-
/// An error returned when OpenGL itself fails to create an object.
5+
/// This error is returned when creating an OpenGL "_object_" fails.
446
///
45-
/// This error is returned by several functions, and contains no extra details. It corresponds to when an
46-
/// object-creation function (e.g., [`glCreateShader`] and [`glCreateProgram`]) returns zero.
7+
/// This error corresponds to when an object-creation function like [`glCreateShader`] or [`glCreateProgram`] returns a
8+
/// value of zero. There are no extra details associated with it.
479
///
4810
/// [`glCreateShader`]: https://registry.khronos.org/OpenGL-Refpages/gl4/html/glCreateShader.xhtml
4911
/// [`glCreateProgram`]: https://registry.khronos.org/OpenGL-Refpages/gl4/html/glCreateProgram.xhtml
50-
#[derive(Error, Debug)]
51-
#[error("OpenGL could not create {0} object")]
52-
// note: {0} should *include* article ("a shader" object) ("an ..." object)
53-
pub struct ObjectCreationError(&'static str);
12+
#[derive(Error, Debug, Clone, Copy)]
13+
#[error("OpenGL failed to create {0}.")] // note: {0} should *include* article ("an ..." object)
14+
pub struct ObjectCreationError(ObjectCreationErrorKind);
5415

5516
impl ObjectCreationError {
56-
pub(crate) const fn new(type_name: &'static str) -> Self {
57-
Self(type_name)
17+
pub(crate) const fn new(kind: ObjectCreationErrorKind) -> Self {
18+
Self(kind)
19+
}
20+
}
21+
22+
/// Which object [failed to be created][ObjectCreationError].
23+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24+
pub enum ObjectCreationErrorKind {
25+
Shader,
26+
Program,
27+
}
28+
29+
impl fmt::Display for ObjectCreationErrorKind {
30+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31+
f.write_str(match self {
32+
Self::Shader => "a shader object",
33+
Self::Program => "a program object",
34+
})
5835
}
5936
}

crates/core/src/funcs/buffers.rs

+26-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use gl::types::*;
22

3+
use crate::gl_convert;
34
use crate::types::*;
45

56

@@ -19,7 +20,7 @@ pub fn create_buffers(n: usize) -> Vec<BufferID> {
1920
}
2021

2122
let mut names = vec![0; n];
22-
let n: GLsizei = n.try_into().expect("buffer creation count should fit into `GLsizei`");
23+
let n = gl_convert!(n, GLsizei, "number of buffers");
2324

2425
unsafe {
2526
gl::CreateBuffers(n, names.as_mut_ptr());
@@ -29,26 +30,41 @@ pub fn create_buffers(n: usize) -> Vec<BufferID> {
2930
}
3031

3132

33+
pub fn delete_buffer(buffer: BufferID) {
34+
unsafe {
35+
// cast is safe because `BufferID` is `repr(transparent)`
36+
gl::DeleteBuffers(1, &buffer as *const BufferID as *const _)
37+
}
38+
}
39+
40+
41+
pub fn delete_buffers(buffers: &[BufferID]) {
42+
let n = gl_convert!(buffers.len(), GLsizei, "number of buffers");
43+
let p = buffers.as_ptr().cast(); // cast is safe because `BufferID` is `repr(transparent)`
44+
unsafe {
45+
gl::DeleteBuffers(n, p);
46+
}
47+
}
48+
49+
3250
pub fn bind_buffer(target: BufferTarget, buffer: BufferID) {
3351
unsafe {
34-
gl::BindBuffer(target.into(), buffer.name());
52+
gl::BindBuffer(target.raw(), buffer.raw());
3553
}
3654
}
3755

3856

39-
pub fn buffer_data(target: BufferTarget, data: impl AsRef<[u8]>, usage: BufferUsage) {
40-
let data = data.as_ref();
41-
let size: GLsizeiptr = data.len().try_into().expect("buffer data size should fit into `GLsizeiptr`");
57+
pub fn buffer_data(target: BufferTarget, data: &[u8], usage: BufferUsage) {
58+
let size = gl_convert!(data.len(), GLsizeiptr, "buffer data size");
4259
unsafe {
43-
gl::BufferData(target.into(), size, data.as_ptr().cast(), usage.into());
60+
gl::BufferData(target.raw(), size, data.as_ptr().cast(), usage.raw());
4461
}
4562
}
4663

4764

48-
pub fn named_buffer_data(buffer: BufferID, data: impl AsRef<[u8]>, usage: BufferUsage) {
49-
let data = data.as_ref();
50-
let size: GLsizeiptr = data.len().try_into().expect("buffer data size should fit into `GLsizeiptr`");
65+
pub fn named_buffer_data(buffer: BufferID, data: &[u8], usage: BufferUsage) {
66+
let size = gl_convert!(data.len(), GLsizeiptr, "buffer data size");
5167
unsafe {
52-
gl::NamedBufferData(buffer.name(), size, data.as_ptr().cast(), usage.into());
68+
gl::NamedBufferData(buffer.raw(), size, data.as_ptr().cast(), usage.raw());
5369
}
5470
}

crates/core/src/funcs/mod.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,32 @@
11
mod buffers;
22
mod shaders;
3+
mod uniforms;
34
mod vertex;
45

56
use gl::types::*;
67

78
pub use self::buffers::*;
89
pub use self::shaders::*;
10+
pub use self::uniforms::*;
911
pub use self::vertex::*;
12+
use crate::gl_convert;
1013
use crate::types::ClearMask;
14+
use crate::types::EnableCap;
1115

1216

1317
pub fn load_with<F>(load_fn: F)
1418
where
15-
F: FnMut(&'static str) -> *const core::ffi::c_void,
19+
F: FnMut(&'static str) -> *const std::ffi::c_void,
1620
{
1721
gl::load_with(load_fn)
1822
}
1923

2024

2125
pub fn viewport(x: i32, y: i32, width: i32, height: i32) {
22-
let x: GLint = x.try_into().expect("viewport x-position should fit into `GLint`");
23-
let y: GLint = y.try_into().expect("viewport y-position should fit into `GLint`");
24-
let width: GLsizei = width.try_into().expect("viewport width should fit into `GLsizei`");
25-
let height: GLsizei = height.try_into().expect("viewport height should fit into `GLsizei`");
26-
26+
let x = gl_convert!(x, GLint, "viewport x-position");
27+
let y = gl_convert!(y, GLint, "viewport y-position");
28+
let width = gl_convert!(width, GLsizei, "viewport width");
29+
let height = gl_convert!(height, GLsizei, "viewport height");
2730
unsafe {
2831
gl::Viewport(x, y, width, height);
2932
}
@@ -32,19 +35,31 @@ pub fn viewport(x: i32, y: i32, width: i32, height: i32) {
3235

3336
pub fn clear_color(red: f32, green: f32, blue: f32, alpha: f32) {
3437
let msg = "clear color should be made of valid `GLfloat`s";
35-
let r: GLfloat = red.try_into().expect(msg);
36-
let g: GLfloat = green.try_into().expect(msg);
37-
let b: GLfloat = blue.try_into().expect(msg);
38-
let a: GLfloat = alpha.try_into().expect(msg);
39-
38+
let r = gl_convert!(red, GLfloat, msg: msg);
39+
let g = gl_convert!(green, GLfloat, msg: msg);
40+
let b = gl_convert!(blue, GLfloat, msg: msg);
41+
let a = gl_convert!(alpha, GLfloat, msg: msg);
4042
unsafe {
4143
gl::ClearColor(r, g, b, a);
4244
}
4345
}
4446

4547

48+
pub fn enable(cap: EnableCap) {
49+
unsafe {
50+
gl::Enable(cap.raw());
51+
}
52+
}
53+
54+
pub fn disable(cap: EnableCap) {
55+
unsafe {
56+
gl::Disable(cap.raw());
57+
}
58+
}
59+
60+
4661
pub fn clear(mask: ClearMask) {
4762
unsafe {
48-
gl::Clear(mask.into());
63+
gl::Clear(mask.raw());
4964
}
5065
}

0 commit comments

Comments
 (0)