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::core::DataType;
9use crate::GfxContext;
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        let bytes =
37            std::slice::from_raw_parts(data.as_ptr() as *const u8, std::mem::size_of_val(data));
38        self.upload_bytes(ctx, bytes, dynamic);
39    }
40
41    /// Overwrite a sub-range of this buffer starting at `offset` bytes.
42    pub fn subdata_bytes(&self, ctx: &GfxContext, offset: u32, data: &[u8]) {
43        unsafe { (ctx.api().buf_subdata)(self.handle, offset, data.as_ptr(), data.len() as u32) }
44    }
45}
46
47// ── VertexArray ───────────────────────────────────────────────────────────────
48
49/// A vertex array object (VAO).
50///
51/// Created by [`GfxContext::create_vao`]. Must be deleted with
52/// [`GfxContext::delete_vao`].
53#[derive(Copy, Clone, Debug, PartialEq, Eq)]
54pub struct VertexArray {
55    pub handle: u32,
56}
57
58impl VertexArray {
59    /// Declare one vertex attribute in this VAO, sourced from `vbo`.
60    ///
61    /// - `index`: attribute location in the shader (`layout(location = N)`).
62    /// - `components`: number of components (1–4).
63    /// - `dtype`: component data type.
64    /// - `normalized`: if `true` and `dtype` is `U8`, values are mapped 0→1.
65    /// - `stride`: byte distance between consecutive vertices in `vbo`.
66    /// - `offset`: byte offset of this attribute within each vertex.
67    pub fn attrib(
68        &self,
69        ctx: &GfxContext,
70        vbo: &Buffer,
71        index: u32,
72        components: u8,
73        dtype: DataType,
74        normalized: bool,
75        stride: u32,
76        offset: u32,
77    ) {
78        unsafe {
79            (ctx.api().vao_attrib)(
80                self.handle,
81                vbo.handle,
82                index,
83                components,
84                dtype as u8,
85                normalized,
86                stride,
87                offset,
88            )
89        }
90    }
91
92    /// Bind an index buffer (EBO) to this VAO.
93    pub fn set_ebo(&self, ctx: &GfxContext, ebo: &Buffer) {
94        unsafe { (ctx.api().vao_set_ebo)(self.handle, ebo.handle) }
95    }
96}
97
98// ── ShaderProgram ─────────────────────────────────────────────────────────────
99
100/// A compiled and linked GLSL shader program.
101///
102/// Created by [`GfxContext::create_shader`]. Must be deleted with
103/// [`GfxContext::delete_shader`].
104#[derive(Copy, Clone, Debug, PartialEq, Eq)]
105pub struct ShaderProgram {
106    pub handle: u32,
107}
108
109impl ShaderProgram {
110    pub fn uniform_1i(&self, ctx: &GfxContext, name: &str, v: i32) {
111        unsafe { (ctx.api().prog_uniform_1i)(self.handle, YogStr::from_str(name), v) }
112    }
113    pub fn uniform_1f(&self, ctx: &GfxContext, name: &str, v: f32) {
114        unsafe { (ctx.api().prog_uniform_1f)(self.handle, YogStr::from_str(name), v) }
115    }
116    pub fn uniform_2f(&self, ctx: &GfxContext, name: &str, x: f32, y: f32) {
117        unsafe { (ctx.api().prog_uniform_2f)(self.handle, YogStr::from_str(name), x, y) }
118    }
119    pub fn uniform_3f(&self, ctx: &GfxContext, name: &str, x: f32, y: f32, z: f32) {
120        unsafe { (ctx.api().prog_uniform_3f)(self.handle, YogStr::from_str(name), x, y, z) }
121    }
122    pub fn uniform_4f(&self, ctx: &GfxContext, name: &str, x: f32, y: f32, z: f32, w: f32) {
123        unsafe { (ctx.api().prog_uniform_4f)(self.handle, YogStr::from_str(name), x, y, z, w) }
124    }
125    /// Upload a column-major 4×4 matrix (16 contiguous `f32` values).
126    pub fn uniform_mat4(&self, ctx: &GfxContext, name: &str, col_major: &[f32; 16]) {
127        unsafe {
128            (ctx.api().prog_uniform_mat4)(self.handle, YogStr::from_str(name), col_major.as_ptr())
129        }
130    }
131}
132
133// ── Texture ───────────────────────────────────────────────────────────────────
134
135/// A 2-D GPU texture.
136///
137/// Created by [`GfxContext::create_texture_rgba`] or [`GfxContext::texture_from_mc`].
138/// Must be deleted with [`GfxContext::delete_texture`] when you own it
139/// (do **not** delete handles from `texture_from_mc` — Minecraft owns those).
140#[derive(Copy, Clone, Debug, PartialEq, Eq)]
141pub struct Texture {
142    pub handle: u32,
143}