yog_gfx/gl/mod.rs
1//! Low-level GPU resource wrappers: [`Buffer`], [`VertexArray`], [`ShaderProgram`], [`Texture`].
2//!
3//! All types are plain handles (`u32`). Create them via [`GfxContext`] methods;
4//! delete them explicitly with `ctx.delete_*` when no longer needed.
5
6use yog_abi::YogStr;
7
8use crate::GfxContext;
9use crate::core::DataType;
10
11// ── Buffer ────────────────────────────────────────────────────────────────────
12
13/// A GPU buffer (VBO or EBO).
14///
15/// Created by [`GfxContext::create_buffer`]. Must be deleted with
16/// [`GfxContext::delete_buffer`] when done.
17#[derive(Copy, Clone, Debug, PartialEq, Eq)]
18pub struct Buffer {
19 pub handle: u32,
20}
21
22impl Buffer {
23 /// Upload bytes to this buffer.
24 /// `dynamic`: hint that the buffer will be updated frequently.
25 pub fn upload_bytes(&self, ctx: &GfxContext, data: &[u8], dynamic: bool) {
26 unsafe { (ctx.api().buf_data)(self.handle, data.as_ptr(), data.len() as u32, dynamic) }
27 }
28
29 /// Upload typed data to this buffer. `T` must be a plain-old-data type
30 /// (the bytes are used as-is, in the layout `T` has in memory).
31 ///
32 /// # Safety
33 /// The byte representation of `T` must be well-defined (no padding traps,
34 /// no floats encoding NaN, etc.). Use `#[repr(C)]` structs or primitive types.
35 pub unsafe fn upload<T: Sized>(&self, ctx: &GfxContext, data: &[T], dynamic: bool) {
36 unsafe {
37 let bytes =
38 std::slice::from_raw_parts(data.as_ptr() as *const u8, std::mem::size_of_val(data));
39 self.upload_bytes(ctx, bytes, dynamic);
40 }
41 }
42
43 /// Overwrite a sub-range of this buffer starting at `offset` bytes.
44 pub fn subdata_bytes(&self, ctx: &GfxContext, offset: u32, data: &[u8]) {
45 unsafe { (ctx.api().buf_subdata)(self.handle, offset, data.as_ptr(), data.len() as u32) }
46 }
47}
48
49// ── VertexArray ───────────────────────────────────────────────────────────────
50
51/// A vertex array object (VAO).
52///
53/// Created by [`GfxContext::create_vao`]. Must be deleted with
54/// [`GfxContext::delete_vao`].
55#[derive(Copy, Clone, Debug, PartialEq, Eq)]
56pub struct VertexArray {
57 pub handle: u32,
58}
59
60impl VertexArray {
61 /// Declare one vertex attribute in this VAO, sourced from `vbo`.
62 ///
63 /// - `index`: attribute location in the shader (`layout(location = N)`).
64 /// - `components`: number of components (1–4).
65 /// - `dtype`: component data type.
66 /// - `normalized`: if `true` and `dtype` is `U8`, values are mapped 0→1.
67 /// - `stride`: byte distance between consecutive vertices in `vbo`.
68 /// - `offset`: byte offset of this attribute within each vertex.
69 pub fn attrib(
70 &self,
71 ctx: &GfxContext,
72 vbo: &Buffer,
73 index: u32,
74 components: u8,
75 dtype: DataType,
76 normalized: bool,
77 stride: u32,
78 offset: u32,
79 ) {
80 unsafe {
81 (ctx.api().vao_attrib)(
82 self.handle,
83 vbo.handle,
84 index,
85 components,
86 dtype as u8,
87 normalized,
88 stride,
89 offset,
90 )
91 }
92 }
93
94 /// Bind an index buffer (EBO) to this VAO.
95 pub fn set_ebo(&self, ctx: &GfxContext, ebo: &Buffer) {
96 unsafe { (ctx.api().vao_set_ebo)(self.handle, ebo.handle) }
97 }
98}
99
100// ── ShaderProgram ─────────────────────────────────────────────────────────────
101
102/// A compiled and linked GLSL shader program.
103///
104/// Created by [`GfxContext::create_shader`]. Must be deleted with
105/// [`GfxContext::delete_shader`].
106#[derive(Copy, Clone, Debug, PartialEq, Eq)]
107pub struct ShaderProgram {
108 pub handle: u32,
109}
110
111impl ShaderProgram {
112 pub fn uniform_1i(&self, ctx: &GfxContext, name: &str, v: i32) {
113 unsafe { (ctx.api().prog_uniform_1i)(self.handle, YogStr::from_str(name), v) }
114 }
115 pub fn uniform_1f(&self, ctx: &GfxContext, name: &str, v: f32) {
116 unsafe { (ctx.api().prog_uniform_1f)(self.handle, YogStr::from_str(name), v) }
117 }
118 pub fn uniform_2f(&self, ctx: &GfxContext, name: &str, x: f32, y: f32) {
119 unsafe { (ctx.api().prog_uniform_2f)(self.handle, YogStr::from_str(name), x, y) }
120 }
121 pub fn uniform_3f(&self, ctx: &GfxContext, name: &str, x: f32, y: f32, z: f32) {
122 unsafe { (ctx.api().prog_uniform_3f)(self.handle, YogStr::from_str(name), x, y, z) }
123 }
124 pub fn uniform_4f(&self, ctx: &GfxContext, name: &str, x: f32, y: f32, z: f32, w: f32) {
125 unsafe { (ctx.api().prog_uniform_4f)(self.handle, YogStr::from_str(name), x, y, z, w) }
126 }
127 /// Upload a column-major 4×4 matrix (16 contiguous `f32` values).
128 pub fn uniform_mat4(&self, ctx: &GfxContext, name: &str, col_major: &[f32; 16]) {
129 unsafe {
130 (ctx.api().prog_uniform_mat4)(self.handle, YogStr::from_str(name), col_major.as_ptr())
131 }
132 }
133}
134
135// ── Texture ───────────────────────────────────────────────────────────────────
136
137/// A 2-D GPU texture.
138///
139/// Created by [`GfxContext::create_texture_rgba`] or [`GfxContext::texture_from_mc`].
140/// Must be deleted with [`GfxContext::delete_texture`] when you own it
141/// (do **not** delete handles from `texture_from_mc` — Minecraft owns those).
142#[derive(Copy, Clone, Debug, PartialEq, Eq)]
143pub struct Texture {
144 pub handle: u32,
145}