summaryrefslogtreecommitdiff
path: root/src/shader.rs
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2025-04-09 03:13:42 -0400
committerLLLL Colonq <llll@colonq>2025-04-09 03:13:42 -0400
commit32ff6ce2d75e898cd350172916751ec13226d5f8 (patch)
treeb0bb588e91b7f9fb0092642ae4c01588eeaefa0e /src/shader.rs
parent7b3157308a0359320f5d098acfa80c6f3bff5a54 (diff)
Reorganize into workspace
Diffstat (limited to 'src/shader.rs')
-rw-r--r--src/shader.rs253
1 files changed, 0 insertions, 253 deletions
diff --git a/src/shader.rs b/src/shader.rs
deleted file mode 100644
index 178833a..0000000
--- a/src/shader.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-use std::collections::HashMap;
-
-use glow::HasContext;
-
-use crate::{context, mesh};
-
-const COMMON_VERT: &'static str = include_str!("assets/shaders/common/vert.glsl");
-const COMMON_FRAG: &'static str = include_str!("assets/shaders/common/frag.glsl");
-
-#[derive(Clone)]
-pub struct Shader {
- pub program: glow::Program,
- pub uniforms: std::rc::Rc<HashMap<String, glow::UniformLocation>>
-}
-
-impl Shader {
- pub fn new_helper(ctx: &context::Context, vsrc: &str, fsrc: &str) -> Result<Self, String> {
- unsafe {
- let program = ctx.gl.create_program()?;
-
- let vert = ctx.gl.create_shader(glow::VERTEX_SHADER)?;
- ctx.gl.shader_source(vert, &vsrc);
- ctx.gl.compile_shader(vert);
- if !ctx.gl.get_shader_compile_status(vert) {
- return Err(format!(
- "failed to compile vertex shader:\n{}",
- ctx.gl.get_shader_info_log(vert)
- ));
- }
- ctx.gl.attach_shader(program, vert);
-
- let frag = ctx.gl.create_shader(glow::FRAGMENT_SHADER)?;
- ctx.gl.shader_source(frag, &fsrc);
- ctx.gl.compile_shader(frag);
- if !ctx.gl.get_shader_compile_status(frag) {
- return Err(format!(
- "failed to compile fragment shader:\n{}",
- ctx.gl.get_shader_info_log(frag)
- ));
- }
- ctx.gl.attach_shader(program, frag);
-
- ctx.gl.bind_attrib_location(program, mesh::ATTRIB_VERTEX, "vertex");
- ctx.gl.bind_attrib_location(program, mesh::ATTRIB_NORMAL, "normal");
- ctx.gl.bind_attrib_location(program, mesh::ATTRIB_TEXCOORD, "texcoord");
- ctx.gl.bind_attrib_location(program, mesh::ATTRIB_JOINT, "joint");
- ctx.gl.bind_attrib_location(program, mesh::ATTRIB_WEIGHT, "weight");
- ctx.gl.bind_attrib_location(program, mesh::ATTRIB_COLOR, "color");
-
- ctx.gl.link_program(program);
- if !ctx.gl.get_program_link_status(program) {
- return Err(format!(
- "failed to link shader program:\n{}",
- ctx.gl.get_program_info_log(program),
- ));
- }
-
- ctx.gl.detach_shader(program, vert);
- ctx.gl.delete_shader(vert);
- ctx.gl.detach_shader(program, frag);
- ctx.gl.delete_shader(frag);
-
- ctx.gl.use_program(Some(program));
-
- let mut uniforms = HashMap::new();
- for index in 0..ctx.gl.get_active_uniforms(program) {
- if let Some(active) = ctx.gl.get_active_uniform(program, index) {
- if let Some(loc) = ctx.gl.get_uniform_location(program, &active.name) {
- uniforms.insert(active.name, loc);
- } else {
- log::warn!("failed to get location for uniform: {}", active.name);
- }
- } else {
- log::warn!("failed to get active uniform for index: {}", index);
- }
- }
-
- Ok(Self {
- program,
- uniforms: std::rc::Rc::new(uniforms),
- })
- }
- }
-
- pub fn new_nolib(ctx: &context::Context, vsrc: &str, fsrc: &str) -> Self {
- Self::new_helper(ctx, vsrc, fsrc).expect("failed to load shader")
- }
-
- pub fn new(ctx: &context::Context, vsrcstr: &str, fsrcstr: &str) -> Self {
- let vsrc = format!("{}\n{}\n", COMMON_VERT, vsrcstr);
- let fsrc = format!("{}\n{}\n", COMMON_FRAG, fsrcstr);
- Self::new_nolib(ctx, &vsrc, &fsrc)
- }
-
- pub fn delete(&mut self, ctx: &context::Context) {
- unsafe { ctx.gl.delete_program(self.program); }
- }
-
- pub fn replace(&mut self, ctx: &context::Context, vsrc: &str, fsrc: &str) -> Result<(), String> {
- self.delete(ctx);
- *self = Self::new_helper(ctx, vsrc, fsrc)?;
- Ok(())
- }
-
- pub fn set_i32(&self, ctx: &context::Context, name: &str, val: i32) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe { ctx.gl.uniform_1_i32(Some(loc), val) }
- }
- }
-
- pub fn set_i32_array(&self, ctx: &context::Context, name: &str, val: &[i32]) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe {
- ctx.gl.uniform_1_i32_slice(Some(loc), val)
- }
- }
- }
-
- pub fn set_f32(&self, ctx: &context::Context, name: &str, val: f32) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe { ctx.gl.uniform_1_f32(Some(loc), val) }
- }
- }
-
- pub fn set_vec2(&self, ctx: &context::Context, name: &str, val: &glam::Vec2) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe {
- ctx.gl.uniform_2_f32(
- Some(loc),
- val.x,
- val.y,
- );
- }
- }
- }
-
- pub fn set_vec2_array(&self, ctx: &context::Context, name: &str, val: &[glam::Vec2]) {
- if let Some(loc) = self.uniforms.get(name) {
- let vs: Vec<f32> = val.iter().flat_map(|v| [v.x, v.y]).collect();
- unsafe {
- ctx.gl.uniform_2_f32_slice(
- Some(loc),
- &vs,
- );
- }
- }
- }
-
- pub fn set_vec3(&self, ctx: &context::Context, name: &str, val: &glam::Vec3) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe {
- ctx.gl.uniform_3_f32(
- Some(loc),
- val.x,
- val.y,
- val.z,
- );
- }
- }
- }
-
- pub fn set_vec3_array(&self, ctx: &context::Context, name: &str, val: &[glam::Vec3]) {
- if let Some(loc) = self.uniforms.get(name) {
- let vs: Vec<f32> = val.iter().flat_map(|v| [v.x, v.y, v.z]).collect();
- unsafe {
- ctx.gl.uniform_3_f32_slice(
- Some(loc),
- &vs,
- );
- }
- }
- }
-
- pub fn set_vec4(&self, ctx: &context::Context, name: &str, val: &glam::Vec4) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe {
- ctx.gl.uniform_4_f32(
- Some(loc),
- val.x,
- val.y,
- val.z,
- val.w,
- );
- }
- }
- }
-
- pub fn set_mat4(&self, ctx: &context::Context, name: &str, val: &glam::Mat4) {
- if let Some(loc) = self.uniforms.get(name) {
- unsafe {
- ctx.gl.uniform_matrix_4_f32_slice(
- Some(loc),
- false,
- &val.to_cols_array(),
- );
- }
- }
- }
-
- pub fn set_mat4_array(&self, ctx: &context::Context, name: &str, val: &[glam::Mat4]) {
- if let Some(loc) = self.uniforms.get(name) {
- let vs: Vec<f32> = val.iter().flat_map(|m| m.to_cols_array()).collect();
- unsafe {
- ctx.gl.uniform_matrix_4_f32_slice(
- Some(loc),
- false,
- &vs,
- );
- }
- }
- }
-
- pub fn set_position_3d(&self, ctx: &context::Context, position: &glam::Mat4) {
- self.set_mat4(&ctx, "position", &position);
- self.set_mat4(&ctx, "normal_matrix", &position.inverse().transpose());
- }
-
- pub fn set_position_2d_helper(&self, ctx: &context::Context, pos: &glam::Vec2, dims: &glam::Vec2, rot: &glam::Quat) {
- let halfwidth = dims.x / 2.0;
- let halfheight = dims.y / 2.0;
- self.set_mat4(
- &ctx, "position",
- &glam::Mat4::from_scale_rotation_translation(
- glam::Vec3::new(halfwidth, halfheight, 1.0),
- rot.clone(),
- glam::Vec3::new(
- -ctx.render_width / 2.0 + pos.x + halfwidth,
- ctx.render_height / 2.0 - pos.y - halfheight,
- 0.0,
- ),
- )
- );
- }
-
- pub fn set_position_2d(&self, ctx: &context::Context, pos: &glam::Vec2, dims: &glam::Vec2) {
- self.set_position_2d_helper(ctx, pos, dims, &glam::Quat::IDENTITY)
- }
-
- pub fn set_texture_offset(&self, ctx: &context::Context, inc: i32, x: i32, y: i32) {
- let count = inc as f32;
- let ratio = 1.0 / count;
- self.set_vec3(
- ctx, "texture_offset",
- &glam::Vec3::new((x % inc) as f32 * ratio, (y % inc) as f32 * ratio, count)
- );
- }
-
- pub fn bind(&self, ctx: &context::Context) {
- unsafe {
- ctx.gl.use_program(Some(self.program));
- }
- }
-}