Skip to main content

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
60/// One vertex attribute: where the shader reads it and how it lies in the buffer.
61#[derive(Copy, Clone, Debug, PartialEq, Eq)]
62pub struct Attrib {
63    /// The attribute's location in the shader (`layout(location = N)`).
64    pub index: u32,
65    /// How many components (1–4).
66    pub components: u8,
67    pub dtype: DataType,
68    /// A `U8` component mapped to 0–1.
69    pub normalized: bool,
70    /// Bytes from one vertex to the next.
71    pub stride: u32,
72    /// Bytes from a vertex's start to this attribute.
73    pub offset: u32,
74}
75
76impl VertexArray {
77    /// Declares vertex attribute `a` of this VAO, sourced from `vbo`.
78    pub fn attrib(&self, ctx: &GfxContext, vbo: &Buffer, a: Attrib) {
79        unsafe {
80            (ctx.api().vao_attrib)(
81                self.handle,
82                vbo.handle,
83                a.index,
84                a.components,
85                a.dtype as u8,
86                a.normalized,
87                a.stride,
88                a.offset,
89            )
90        }
91    }
92
93    /// Bind an index buffer (EBO) to this VAO.
94    pub fn set_ebo(&self, ctx: &GfxContext, ebo: &Buffer) {
95        unsafe { (ctx.api().vao_set_ebo)(self.handle, ebo.handle) }
96    }
97}
98
99// ── ShaderProgram ─────────────────────────────────────────────────────────────
100
101/// A compiled and linked GLSL shader program.
102///
103/// Created by [`GfxContext::create_shader`]. Must be deleted with
104/// [`GfxContext::delete_shader`].
105#[derive(Copy, Clone, Debug, PartialEq, Eq)]
106pub struct ShaderProgram {
107    pub handle: u32,
108}
109
110impl ShaderProgram {
111    pub fn uniform_1i(&self, ctx: &GfxContext, name: &str, v: i32) {
112        unsafe { (ctx.api().prog_uniform_1i)(self.handle, YogStr::from_str(name), v) }
113    }
114    pub fn uniform_1f(&self, ctx: &GfxContext, name: &str, v: f32) {
115        unsafe { (ctx.api().prog_uniform_1f)(self.handle, YogStr::from_str(name), v) }
116    }
117    pub fn uniform_2f(&self, ctx: &GfxContext, name: &str, [x, y]: [f32; 2]) {
118        unsafe { (ctx.api().prog_uniform_2f)(self.handle, YogStr::from_str(name), x, y) }
119    }
120    pub fn uniform_3f(&self, ctx: &GfxContext, name: &str, [x, y, z]: [f32; 3]) {
121        unsafe { (ctx.api().prog_uniform_3f)(self.handle, YogStr::from_str(name), x, y, z) }
122    }
123    pub fn uniform_4f(&self, ctx: &GfxContext, name: &str, [x, y, z, w]: [f32; 4]) {
124        unsafe { (ctx.api().prog_uniform_4f)(self.handle, YogStr::from_str(name), x, y, z, w) }
125    }
126    /// Upload a column-major 4×4 matrix (16 contiguous `f32` values).
127    pub fn uniform_mat4(&self, ctx: &GfxContext, name: &str, col_major: &[f32; 16]) {
128        unsafe {
129            (ctx.api().prog_uniform_mat4)(self.handle, YogStr::from_str(name), col_major.as_ptr())
130        }
131    }
132}
133
134// ── Texture ───────────────────────────────────────────────────────────────────
135
136/// A 2-D GPU texture.
137///
138/// Created by [`GfxContext::create_texture_rgba`] or [`GfxContext::texture_from_mc`].
139/// Must be deleted with [`GfxContext::delete_texture`] when you own it
140/// (do **not** delete handles from `texture_from_mc` — Minecraft owns those).
141#[derive(Copy, Clone, Debug, PartialEq, Eq)]
142pub struct Texture {
143    pub handle: u32,
144}