wxbox/crates/client/src/map/render.rs

156 lines
5.3 KiB
Rust
Raw Normal View History

2025-03-07 23:34:29 -05:00
use tracing::{debug, warn};
use crate::map::Tileset;
pub struct MapRender {
program: glow::Program,
vertex_buffer: glow::Buffer,
}
#[allow(unsafe_code)]
impl MapRender {
pub fn new(gl: &glow::Context) -> Option<Self> {
use glow::HasContext as _;
let shader_version = egui_glow::ShaderVersion::get(gl);
unsafe {
let program = gl.create_program().expect("Cannot create program");
if !shader_version.is_new_shader_interface() {
warn!(
"Custom 3D painting hasn't been ported to {:?}",
shader_version
);
return None;
}
let (vertex_shader_source, fragment_shader_source) = (
r#"
layout(location = 0) in vec2 pos;
const vec4 colors[6] = vec4[6](
vec4(1.0, 0.0, 0.0, 1.0),
vec4(0.0, 1.0, 0.0, 1.0),
vec4(0.0, 0.0, 1.0, 1.0),
vec4(1.0, 0.0, 0.0, 1.0),
vec4(0.0, 1.0, 0.0, 1.0),
vec4(0.0, 0.0, 1.0, 1.0)
);
out vec4 v_color;
void main() {
v_color = colors[gl_VertexID];
gl_Position = vec4(pos, 0.0, 1.0);
}
"#,
r#"
precision mediump float;
in vec4 v_color;
out vec4 out_color;
void main() {
out_color = v_color;
}
"#,
);
let shader_sources = [
(glow::VERTEX_SHADER, vertex_shader_source),
(glow::FRAGMENT_SHADER, fragment_shader_source),
];
let shaders: Vec<_> = shader_sources
.iter()
.map(|(shader_type, shader_source)| {
let shader = gl
.create_shader(*shader_type)
.expect("Cannot create shader");
gl.shader_source(
shader,
&format!(
"{}\n{}",
shader_version.version_declaration(),
shader_source
),
);
gl.compile_shader(shader);
assert!(
gl.get_shader_compile_status(shader),
"Failed to compile custom_3d_glow {shader_type} ({} {}): {}",
glow::VERTEX_SHADER,
glow::FRAGMENT_SHADER,
gl.get_shader_info_log(shader)
);
gl.attach_shader(program, shader);
shader
})
.collect();
gl.link_program(program);
assert!(
gl.get_program_link_status(program),
"{}",
gl.get_program_info_log(program)
);
for shader in shaders {
gl.detach_shader(program, shader);
gl.delete_shader(shader);
}
let vertex_buffer = gl.create_buffer().expect("Cannot create vertex buffer");
2025-03-07 23:49:27 -05:00
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer));
2025-03-07 23:34:29 -05:00
gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, (2 * size_of::<f32>()) as i32, 0);
gl.enable_vertex_attrib_array(0);
Some(Self {
program,
vertex_buffer
})
}
}
pub fn destroy(&self, gl: &glow::Context) {
use glow::HasContext as _;
unsafe {
gl.delete_program(self.program);
}
}
pub fn paint(&self, gl: &glow::Context, tileset: Tileset) {
use glow::HasContext as _;
unsafe {
gl.use_program(Some(self.program));
2025-03-07 23:49:27 -05:00
2025-03-07 23:34:29 -05:00
let tiles = tileset.tiles.lock().unwrap();
for tile in tiles.iter() {
let mut data = vec![];
// A-B
// | |
// C-D
// ABC
// BDC
// a: (sp_xclip, sp_yclip)
// b: (ep_xclip, sp_yclip)
// c: (sp_xclip, ep_yclip)
// d: (ep_xclip, ep_yclip)
// sp_xclip sp_yclip ep_xclip sp_yclip sp_xclip ep_yclip // ABC
// ep_xclip sp_yclip ep_xclip ep_yclip sp_xclip ep_yclip // BDC
debug!("A {:?} - B {:?}", (tile.sp_xclip, tile.sp_yclip), (tile.ep_xclip, tile.sp_yclip));
debug!("C {:?} - D {:?}", (tile.sp_xclip, tile.ep_yclip), (tile.ep_xclip, tile.ep_yclip));
2025-03-07 23:49:27 -05:00
//let raw_data = [tile.sp_xclip, tile.sp_yclip, tile.ep_xclip, tile.sp_yclip, tile.sp_xclip, tile.ep_yclip, tile.ep_xclip, tile.sp_yclip, tile.ep_xclip, tile.ep_yclip, tile.sp_xclip, tile.ep_yclip];
let raw_data = [1.0f32, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0];
for v in &raw_data {
2025-03-07 23:34:29 -05:00
data.extend(v.to_be_bytes());
}
2025-03-07 23:49:27 -05:00
2025-03-07 23:34:29 -05:00
gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, &data, glow::DYNAMIC_DRAW);
2025-03-07 23:49:27 -05:00
gl.draw_arrays(glow::TRIANGLES, 0, 3);
2025-03-07 23:34:29 -05:00
}
}
}
}