render work
Some checks failed
build and test / wxbox - latest (push) Failing after 38m15s
Verify Latest Dependencies / Verify Latest Dependencies (push) Successful in 38m29s

This commit is contained in:
core 2025-03-08 13:29:30 -05:00
parent cb0b3f5993
commit 13aa62ecbc
11 changed files with 183 additions and 146 deletions

5
.idea/wxbox.iml generated
View file

@ -12,6 +12,11 @@
<sourceFolder url="file://$MODULE_DIR$/wxbox_client_wasm/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/wxbox_client_wasm/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_common/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/wxbox_common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_web/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/wxbox_web/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/grib2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/pal/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/tiler/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" /> <excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" /> <excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" /> <excludeFolder url="file://$MODULE_DIR$/tmp" />

5
Cargo.lock generated
View file

@ -828,9 +828,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.21.0" version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
dependencies = [ dependencies = [
"bytemuck_derive", "bytemuck_derive",
] ]
@ -5106,6 +5106,7 @@ dependencies = [
name = "wxbox-client" name = "wxbox-client"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytemuck",
"console_error_panic_hook", "console_error_panic_hook",
"eframe", "eframe",
"egui", "egui",

View file

@ -13,6 +13,7 @@ egui = "0.31"
poll-promise = "0.3" poll-promise = "0.3"
ehttp = "0.5" ehttp = "0.5"
image = "0.25" image = "0.25"
bytemuck = "1.22"
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
tracing-web = "0.1" tracing-web = "0.1"

View file

@ -94,7 +94,7 @@
} }
} }
</style> </style>
<link rel="modulepreload" href="/wxbox-client-5fe4727443779190.js" crossorigin="anonymous" integrity="sha384-A3JOZ15bmE6xydSHdMZU5eIbrIJ8XY/DNJ5CtuoUisRN+ij0kXCl7eikCAcPsitl"><link rel="preload" href="/wxbox-client-5fe4727443779190_bg.wasm" crossorigin="anonymous" integrity="sha384-9sLtaYmgcP7scAP05eP73dWDxb1P/1C+pS93pBTkZLNTsrnwri+zXI/1NrlJBm9z" as="fetch" type="application/wasm"></head> <link rel="modulepreload" href="/wxbox-client-b2e1a3e7de3c6850.js" crossorigin="anonymous" integrity="sha384-nDqexAJ4zOC1UgJKvlu7tZO/Xu13qGp8nhmNPBCjCZhoWJ2FIphBbxmj+dwXs9Uw"><link rel="preload" href="/wxbox-client-b2e1a3e7de3c6850_bg.wasm" crossorigin="anonymous" integrity="sha384-Qv6lJAdZwj0oPiGat7p3dWQwZr1TtBEsq1J/pIPFPRI4IcAQ2r5ulP2rCVt+eFeN" as="fetch" type="application/wasm"></head>
<body> <body>
<!-- The WASM code will resize the canvas dynamically --> <!-- The WASM code will resize the canvas dynamically -->
@ -111,8 +111,8 @@
<script type="module"> <script type="module">
import init, * as bindings from '/wxbox-client-5fe4727443779190.js'; import init, * as bindings from '/wxbox-client-b2e1a3e7de3c6850.js';
const wasm = await init({ module_or_path: '/wxbox-client-5fe4727443779190_bg.wasm' }); const wasm = await init({ module_or_path: '/wxbox-client-b2e1a3e7de3c6850_bg.wasm' });
window.wasmBindings = bindings; window.wasmBindings = bindings;

View file

@ -197,25 +197,24 @@ function debugString(val) {
// TODO we could test for more things here, like `Set`s and `Map`s. // TODO we could test for more things here, like `Set`s and `Map`s.
return className; return className;
} }
function __wbg_adapter_32(arg0, arg1, arg2) {
wasm.closure1003_externref_shim(arg0, arg1, arg2);
}
function takeFromExternrefTable0(idx) { function takeFromExternrefTable0(idx) {
const value = wasm.__wbindgen_export_1.get(idx); const value = wasm.__wbindgen_export_1.get(idx);
wasm.__externref_table_dealloc(idx); wasm.__externref_table_dealloc(idx);
return value; return value;
} }
function __wbg_adapter_32(arg0, arg1) { function __wbg_adapter_35(arg0, arg1) {
const ret = wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3a79313ab83803af_multivalue_shim(arg0, arg1); const ret = wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h099b1487e92de126_multivalue_shim(arg0, arg1);
if (ret[1]) { if (ret[1]) {
throw takeFromExternrefTable0(ret[0]); throw takeFromExternrefTable0(ret[0]);
} }
} }
function __wbg_adapter_35(arg0, arg1, arg2) {
wasm.closure786_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_40(arg0, arg1, arg2) { function __wbg_adapter_40(arg0, arg1, arg2) {
wasm.closure1466_externref_shim(arg0, arg1, arg2); wasm.closure1689_externref_shim(arg0, arg1, arg2);
} }
/** /**
@ -551,6 +550,12 @@ function __wbg_get_imports() {
imports.wbg.__wbg_deleteTexture_eaf729f97b59aaf4 = function(arg0, arg1) { imports.wbg.__wbg_deleteTexture_eaf729f97b59aaf4 = function(arg0, arg1) {
arg0.deleteTexture(arg1); arg0.deleteTexture(arg1);
}; };
imports.wbg.__wbg_deleteVertexArrayOES_0de32bd8adddeecb = function(arg0, arg1) {
arg0.deleteVertexArrayOES(arg1);
};
imports.wbg.__wbg_deleteVertexArray_cff2c6ab55f2c8b6 = function(arg0, arg1) {
arg0.deleteVertexArray(arg1);
};
imports.wbg.__wbg_deltaMode_b2e9bb0dca5cf196 = function(arg0) { imports.wbg.__wbg_deltaMode_b2e9bb0dca5cf196 = function(arg0) {
const ret = arg0.deltaMode; const ret = arg0.deltaMode;
return ret; return ret;
@ -600,12 +605,6 @@ function __wbg_get_imports() {
const ret = arg0.done; const ret = arg0.done;
return ret; return ret;
}; };
imports.wbg.__wbg_drawArrays_01e26acf05821932 = function(arg0, arg1, arg2, arg3) {
arg0.drawArrays(arg1 >>> 0, arg2, arg3);
};
imports.wbg.__wbg_drawArrays_32d97bfaf282c738 = function(arg0, arg1, arg2, arg3) {
arg0.drawArrays(arg1 >>> 0, arg2, arg3);
};
imports.wbg.__wbg_drawElements_28e4f5037fe8c665 = function(arg0, arg1, arg2, arg3, arg4) { imports.wbg.__wbg_drawElements_28e4f5037fe8c665 = function(arg0, arg1, arg2, arg3, arg4) {
arg0.drawElements(arg1 >>> 0, arg2, arg3 >>> 0, arg4); arg0.drawElements(arg1 >>> 0, arg2, arg3 >>> 0, arg4);
}; };
@ -1614,20 +1613,20 @@ function __wbg_get_imports() {
const ret = false; const ret = false;
return ret; return ret;
}; };
imports.wbg.__wbindgen_closure_wrapper3076 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper3632 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 783, __wbg_adapter_32); const ret = makeMutClosure(arg0, arg1, 1004, __wbg_adapter_32);
return ret; return ret;
}; };
imports.wbg.__wbindgen_closure_wrapper3078 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper3634 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 783, __wbg_adapter_35); const ret = makeMutClosure(arg0, arg1, 1004, __wbg_adapter_35);
return ret; return ret;
}; };
imports.wbg.__wbindgen_closure_wrapper3080 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper3636 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 783, __wbg_adapter_35); const ret = makeMutClosure(arg0, arg1, 1004, __wbg_adapter_32);
return ret; return ret;
}; };
imports.wbg.__wbindgen_closure_wrapper5619 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper6213 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1467, __wbg_adapter_40); const ret = makeMutClosure(arg0, arg1, 1690, __wbg_adapter_40);
return ret; return ret;
}; };
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {

View file

@ -7,7 +7,7 @@ use crate::map::osm::OSMBaselayer;
use crate::map::tiles::{LayerManager, LayerSource}; use crate::map::tiles::{LayerManager, LayerSource};
pub struct App { pub struct App {
map: Arc<Mutex<Map>> map: Map
} }
impl App { impl App {
@ -16,7 +16,7 @@ impl App {
layer_manager.layers.insert(0, OSMBaselayer::SOURCE_ID); layer_manager.layers.insert(0, OSMBaselayer::SOURCE_ID);
Self { Self {
map: Arc::new(Mutex::new(Map::new(layer_manager, cc).unwrap())), map: Map::new(layer_manager, cc).unwrap(),
} }
} }
} }
@ -31,16 +31,13 @@ impl eframe::App for App {
egui::CentralPanel::default() egui::CentralPanel::default()
.show(ctx, |ui| { .show(ctx, |ui| {
{ self.map.custom_painting(&ctx, ui);
let map = self.map.clone();
map.lock().unwrap().custom_painting(&ctx, ui);
}
}); });
} }
fn on_exit(&mut self, gl: Option<&glow::Context>) { fn on_exit(&mut self, gl: Option<&glow::Context>) {
if let Some(gl) = gl { if let Some(gl) = gl {
self.map.lock().unwrap().render.lock().unwrap().destroy(gl); self.map.render.lock().unwrap().destroy(gl);
} }
} }
} }

View file

@ -10,7 +10,7 @@ use image::{DynamicImage, ImageReader};
use poll_promise::Promise; use poll_promise::Promise;
use tracing::{debug, warn}; use tracing::{debug, warn};
use crate::map::osm::OSMBaselayer; use crate::map::osm::OSMBaselayer;
use crate::map::render::MapRender; use crate::map::render::{ExtraRenderOptions, MapRender};
use crate::map::tiles::{LayerManager, LayerSource, Tile}; use crate::map::tiles::{LayerManager, LayerSource, Tile};
pub struct Map { pub struct Map {
@ -18,7 +18,8 @@ pub struct Map {
pub lat: f64, pub lat: f64,
pub long: f64, pub long: f64,
pub zoom: f64, pub zoom: f64,
pub render: Arc<Mutex<MapRender>> pub render: Arc<Mutex<MapRender>>,
pub options: ExtraRenderOptions
} }
impl Map { impl Map {
@ -29,7 +30,9 @@ impl Map {
lat: 35.227085, lat: 35.227085,
long: -80.843124, long: -80.843124,
zoom: 12.0, zoom: 12.0,
render: Arc::new(Mutex::new(MapRender::new(gl)?)) render: Arc::new(Mutex::new(MapRender::new(gl)?)),
options: ExtraRenderOptions {
}
}) })
} }
pub fn process_input(&mut self, ctx: &egui::Context, ui: &mut Ui, rect: Rect, response: egui::Response) { pub fn process_input(&mut self, ctx: &egui::Context, ui: &mut Ui, rect: Rect, response: egui::Response) {
@ -180,9 +183,10 @@ impl Map {
self.process_input(ctx, ui, rect, response); self.process_input(ctx, ui, rect, response);
let tileset = self.load_tiles(ctx, rect.width() as usize, rect.height() as usize); let tileset = self.load_tiles(ctx, rect.width() as usize, rect.height() as usize);
let render = self.render.clone(); let render = self.render.clone();
let options = self.options;
let cb = egui_glow::CallbackFn::new(move |_info, painter| { let cb = egui_glow::CallbackFn::new(move |_info, painter| {
let tileset = tileset.clone(); let tileset = tileset.clone();
render.lock().unwrap().paint(painter.gl(), tileset); render.lock().unwrap().paint(painter.gl(), tileset, options);
}); });
ui.painter().add(egui::PaintCallback { ui.painter().add(egui::PaintCallback {
rect, rect,

View file

@ -0,0 +1,10 @@
#version 300 es
precision mediump float; // floats: medium precision
out vec4 FragColor;
in vec2 texCoord;
uniform sampler2D tex;
void main() {
FragColor = texture(tex, texCoord);
}

View file

@ -1,9 +1,16 @@
use tracing::{debug, warn}; use std::io::Cursor;
use std::mem;
use glow::{Buffer, HasContext, PixelUnpackData, Program, Texture, VertexArray};
use image::{DynamicImage, EncodableLayout, ImageReader};
use tracing::{debug, error, warn};
use crate::map::Tileset; use crate::map::Tileset;
pub struct MapRender { pub struct MapRender {
program: glow::Program, vbo: Buffer,
vertex_buffer: glow::Buffer, vao: VertexArray,
ebo: Buffer,
shader_program: Program,
test_texture: Texture,
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -14,8 +21,6 @@ impl MapRender {
let shader_version = egui_glow::ShaderVersion::get(gl); let shader_version = egui_glow::ShaderVersion::get(gl);
unsafe { unsafe {
let program = gl.create_program().expect("Cannot create program");
if !shader_version.is_new_shader_interface() { if !shader_version.is_new_shader_interface() {
warn!( warn!(
"Custom 3D painting hasn't been ported to {:?}", "Custom 3D painting hasn't been ported to {:?}",
@ -24,86 +29,75 @@ impl MapRender {
return None; return None;
} }
let (vertex_shader_source, fragment_shader_source) = ( let vbo = gl.create_buffer().unwrap();
r#" let ebo = gl.create_buffer().unwrap();
layout(location = 0) in vec2 pos; let vao = gl.create_vertex_array().unwrap();
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 = [ let vertex_shader = gl.create_shader(glow::VERTEX_SHADER).unwrap();
(glow::VERTEX_SHADER, vertex_shader_source), gl.shader_source(vertex_shader, include_str!("vertex.glsl"));
(glow::FRAGMENT_SHADER, fragment_shader_source), gl.compile_shader(vertex_shader);
]; if !gl.get_shader_compile_status(vertex_shader) {
// shader compilation failed
let shaders: Vec<_> = shader_sources error!("vertex shader compilation failed: {}", gl.get_shader_info_log(vertex_shader));
.iter() return None;
.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"); let fragment_shader = gl.create_shader(glow::FRAGMENT_SHADER).unwrap();
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer)); gl.shader_source(fragment_shader, include_str!("frag.glsl"));
gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, (2 * size_of::<f32>()) as i32, 0); gl.compile_shader(fragment_shader);
gl.enable_vertex_attrib_array(0); if !gl.get_shader_compile_status(fragment_shader) {
// shader compilation failed
error!("fragment shader compilation failed: {}", gl.get_shader_info_log(fragment_shader));
return None;
}
let shader_program = gl.create_program().unwrap();
gl.attach_shader(shader_program, vertex_shader);
gl.attach_shader(shader_program, fragment_shader);
gl.link_program(shader_program);
if !gl.get_program_link_status(shader_program) {
error!("linking shader failed: {}", gl.get_program_info_log(shader_program));
}
gl.use_program(Some(shader_program));
gl.delete_shader(vertex_shader);
gl.delete_shader(fragment_shader);
let test_img = ImageReader::new(Cursor::new(include_bytes!("../../0.png"))).with_guessed_format().unwrap().decode().unwrap();
let test_img_rgb8 = test_img.flipv().into_rgb8();
let w = test_img_rgb8.width();
let h = test_img_rgb8.height();
let raw = test_img_rgb8.into_raw();
let test_texture = gl.create_texture().unwrap();
gl.bind_texture(glow::TEXTURE_2D, Some(test_texture));
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32);
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32);
gl.tex_image_2d(
glow::TEXTURE_2D,
0,
glow::RGB as i32,
w as i32,
h as i32,
0,
glow::RGB,
glow::UNSIGNED_BYTE,
PixelUnpackData::Slice(Some(&raw)),
);
gl.generate_mipmap(glow::TEXTURE_2D);
gl.uniform_1_i32(
gl.get_uniform_location(shader_program, "tex").as_ref(),
0
);
Some(Self { Some(Self {
program, vbo,
vertex_buffer shader_program,
vao,
ebo,
test_texture,
}) })
} }
} }
@ -111,46 +105,62 @@ impl MapRender {
pub fn destroy(&self, gl: &glow::Context) { pub fn destroy(&self, gl: &glow::Context) {
use glow::HasContext as _; use glow::HasContext as _;
unsafe { unsafe {
gl.delete_program(self.program); gl.delete_program(self.shader_program);
gl.delete_buffer(self.vbo);
gl.delete_vertex_array(self.vao);
} }
} }
pub fn paint(&self, gl: &glow::Context, tileset: Tileset) { pub fn paint(&self, gl: &glow::Context, tileset: Tileset, options: ExtraRenderOptions) {
use glow::HasContext as _; use glow::HasContext as _;
let verticies: &[f32] = &[
// X Y Z S T
0.5, 0.5, 0.0, 1.0, 1.0, // top right
0.5, -0.5, 0.0, 1.0, 0.0, // bottom right
-0.5, -0.5, 0.0, 0.0, 0.0, // bottom left
-0.5, 0.5, 0.0, 0.0, 1.0, // top left
];
let indicies: &[u32] = &[
0, 1, 3,
1, 2, 3
];
unsafe { unsafe {
gl.use_program(Some(self.program)); gl.clear_color(0.5, 0.1, 0.1, 1.0);
gl.clear(glow::COLOR_BUFFER_BIT);
gl.bind_vertex_array(Some(self.vao));
gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vbo));
gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, bytemuck::cast_slice(verticies), glow::DYNAMIC_DRAW);
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.ebo));
gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, bytemuck::cast_slice(indicies), glow::DYNAMIC_DRAW);
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, (5 * mem::size_of::<f32>()) as i32, 0);
gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, (5 * mem::size_of::<f32>()) as i32, 3 * mem::size_of::<f32>() as i32);
gl.enable_vertex_attrib_array(0);
gl.enable_vertex_attrib_array(1);
gl.use_program(Some(self.shader_program));
gl.active_texture(glow::TEXTURE0);
gl.bind_texture(glow::TEXTURE_2D, Some(self.test_texture));
let tiles = tileset.tiles.lock().unwrap(); gl.bind_vertex_array(Some(self.vao));
for tile in tiles.iter() { gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.ebo));
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));
//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 {
data.extend(v.to_be_bytes());
}
gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, &data, glow::DYNAMIC_DRAW);
gl.draw_arrays(glow::TRIANGLES, 0, 3);
}
gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT, 0);
} }
} }
} }
#[derive(Copy, Clone)]
pub struct ExtraRenderOptions {
}

View file

@ -0,0 +1,10 @@
#version 300 es
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 texCoord;
void main() {
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
texCoord = aTexCoord;
}