Skip to content

Commit 82f901d

Browse files
Port teapots example from WebGL
Trying to test `glDrawArrays` on some bigger sets of data. Hoped it would help me narrow down the issue with the loaded OBJ file, but it sadly worked totally fine.
1 parent 9ff4dce commit 82f901d

11 files changed

+1096
-0
lines changed

Cargo.lock

+73
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ gloog-math = { version = "0.1.0", path = "./gloog-math" }
1414
bytemuck = "1.13.1"
1515
glfw = "0.52.0"
1616
log = "0.4.20"
17+
rand = "0.8.5"
18+
rand_distr = "0.4.3"
1719
simple_logger = { version = "4.3.3", features = ["timestamps", "colors", "stderr"] }
1820

1921

Binary file not shown.
Binary file not shown.
Binary file not shown.

src/bin/teapot-test/light.rs

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
use std::sync::{Mutex, OnceLock};
2+
3+
use gloog_core::types::{
4+
BufferTarget,
5+
BufferUsage,
6+
DrawMode,
7+
ProgramID,
8+
UniformLocation,
9+
VertexArrayID,
10+
VertexAttribType,
11+
};
12+
use gloog_core::GLContext;
13+
use gloog_math::{Mat4, Vec3, Vec4};
14+
15+
use crate::{scale_matrix, trans_matrix};
16+
17+
#[allow(unused)]
18+
const MAX_LIGHTS: u32 = 16;
19+
20+
21+
pub struct Light<'gl> {
22+
gl: &'gl GLContext,
23+
id: usize,
24+
pub ambient: Vec4,
25+
pub diffuse: Vec4,
26+
pub specular: Vec4,
27+
pub position: Vec3,
28+
pub draw_color: Vec4,
29+
info: &'static StaticLightInfo,
30+
uniforms: LightUniforms,
31+
}
32+
33+
struct StaticLightInfo {
34+
vao: VertexArrayID,
35+
vertex_count: usize,
36+
program: ProgramID,
37+
u_color: UniformLocation,
38+
u_model_view_matrix: UniformLocation,
39+
u_projection_matrix: UniformLocation,
40+
}
41+
42+
struct LightUniforms {
43+
diffuse: UniformLocation,
44+
ambient: UniformLocation,
45+
specular: UniformLocation,
46+
position: UniformLocation,
47+
}
48+
49+
50+
static LIGHT_INFO: OnceLock<StaticLightInfo> = OnceLock::new();
51+
static NEXT_LIGHT_ID: OnceLock<Mutex<usize>> = OnceLock::new();
52+
53+
54+
impl<'gl> Light<'gl> {
55+
#[allow(unused)]
56+
pub fn id(&self) -> usize {
57+
self.id
58+
}
59+
60+
pub fn new(
61+
gl: &'gl GLContext,
62+
program: ProgramID,
63+
position: Vec3,
64+
diffuse: Vec4,
65+
ambient: Vec4,
66+
specular: Vec4,
67+
draw_color_override: Option<Vec4>,
68+
) -> Self {
69+
let info = LIGHT_INFO.get_or_init(|| Self::init(gl));
70+
let id = Self::next_id();
71+
let uniforms = Self::get_uniforms(gl, id, program);
72+
73+
Self {
74+
gl,
75+
id,
76+
ambient,
77+
diffuse,
78+
specular,
79+
position,
80+
uniforms,
81+
draw_color: draw_color_override.unwrap_or(diffuse),
82+
info,
83+
}
84+
}
85+
86+
87+
fn get_uniforms(gl: &GLContext, id: usize, program: ProgramID) -> LightUniforms {
88+
let diffuse = gl.get_uniform_location(program, &format!("lights[{id}].diffuse")).unwrap();
89+
let ambient = gl.get_uniform_location(program, &format!("lights[{id}].ambient")).unwrap();
90+
let specular = gl.get_uniform_location(program, &format!("lights[{id}].specular")).unwrap();
91+
let position = gl.get_uniform_location(program, &format!("lights[{id}].position")).unwrap();
92+
93+
LightUniforms {
94+
diffuse,
95+
ambient,
96+
specular,
97+
position,
98+
}
99+
}
100+
101+
102+
fn next_id() -> usize {
103+
let id = NEXT_LIGHT_ID.get_or_init(|| Mutex::new(0));
104+
let mut id = id.lock().expect("mutex poisoned");
105+
let out = *id;
106+
*id += 1;
107+
out
108+
}
109+
110+
111+
fn init(gl: &GLContext) -> StaticLightInfo {
112+
let vertex_data = {
113+
let verts = [
114+
Vec3::new(-0.5, -0.5, 0.5),
115+
Vec3::new(-0.5, 0.5, 0.5),
116+
Vec3::new(0.5, 0.5, 0.5),
117+
Vec3::new(0.5, -0.5, 0.5),
118+
Vec3::new(-0.5, -0.5, -0.5),
119+
Vec3::new(-0.5, 0.5, -0.5),
120+
Vec3::new(0.5, 0.5, -0.5),
121+
Vec3::new(0.5, -0.5, -0.5),
122+
];
123+
124+
let mut idx = 0;
125+
let mut buf = [Vec3::default(); 36];
126+
127+
let mut inc = || {
128+
let i = idx;
129+
idx += 1;
130+
i
131+
};
132+
133+
let mut push_quad = |a: usize, b: usize, c: usize, d: usize| {
134+
let tl = verts[a];
135+
let bl = verts[b];
136+
let br = verts[c];
137+
let tr = verts[d];
138+
139+
buf[inc()] = tl;
140+
buf[inc()] = bl;
141+
buf[inc()] = br;
142+
143+
buf[inc()] = tl;
144+
buf[inc()] = br;
145+
buf[inc()] = tr;
146+
};
147+
148+
push_quad(1, 0, 3, 2);
149+
push_quad(5, 4, 0, 1);
150+
push_quad(2, 3, 7, 6);
151+
push_quad(6, 7, 4, 5);
152+
push_quad(5, 1, 2, 6);
153+
push_quad(7, 3, 0, 4);
154+
155+
buf
156+
};
157+
158+
const VERT_SRC: &str = include_str!("./shaders/vert.glsl");
159+
const FRAG_SRC: &str = include_str!("./shaders/frag-light.glsl");
160+
let program = super::setup_program(gl, VERT_SRC, FRAG_SRC);
161+
162+
let u_color = gl.get_uniform_location(program, "uColor").unwrap();
163+
let u_model_view_matrix = gl.get_uniform_location(program, "uModelViewMatrix").unwrap();
164+
let u_projection_matrix = gl.get_uniform_location(program, "uProjectionMatrix").unwrap();
165+
166+
let vao = gl.create_vertex_array();
167+
gl.bind_vertex_array(vao);
168+
169+
let vbo = gl.create_buffer();
170+
gl.bind_buffer(BufferTarget::ArrayBuffer, vbo);
171+
gl.buffer_data(BufferTarget::ArrayBuffer, bytemuck::cast_slice(&vertex_data[..]), BufferUsage::StaticDraw);
172+
gl.vertex_attrib_pointer(0, 3, VertexAttribType::Float, false, 0, 0);
173+
gl.enable_vertex_attrib_array(0);
174+
175+
gl.unbind_vertex_array();
176+
177+
StaticLightInfo {
178+
vao,
179+
vertex_count: vertex_data.len(),
180+
program,
181+
u_color,
182+
u_model_view_matrix,
183+
u_projection_matrix,
184+
}
185+
}
186+
187+
pub fn set_uniforms(&self, view_matrix: &Mat4) {
188+
let &Self { gl, ref uniforms, .. } = self;
189+
190+
gl.uniform_4fv(uniforms.diffuse, &[self.diffuse.into()]);
191+
gl.uniform_4fv(uniforms.ambient, &[self.ambient.into()]);
192+
gl.uniform_4fv(uniforms.specular, &[self.specular.into()]);
193+
194+
let position4 = Vec4::from3(self.position, 1.0);
195+
let vs_position = view_matrix * position4;
196+
let vs_position = Vec3::new(vs_position.x, vs_position.y, vs_position.z);
197+
gl.uniform_3fv(uniforms.position, &[vs_position.into()]);
198+
}
199+
200+
pub fn draw(&self, view_matrix: &Mat4, proj_matrix: &Mat4) {
201+
let &Self { gl, info, .. } = self;
202+
203+
gl.use_program(info.program);
204+
gl.bind_vertex_array(info.vao);
205+
206+
let model_view = view_matrix * trans_matrix(self.position) * scale_matrix(Vec3::new(0.2, 0.2, 0.2));
207+
208+
gl.uniform_4fv(info.u_color, &[self.draw_color.into()]);
209+
gl.uniform_matrix_4fv(info.u_model_view_matrix, false, &[model_view.into()]);
210+
gl.uniform_matrix_4fv(info.u_projection_matrix, false, &[(*proj_matrix).into()]);
211+
212+
gl.draw_arrays(DrawMode::Triangles, 0, info.vertex_count);
213+
}
214+
}

0 commit comments

Comments
 (0)