mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2026-01-07 02:24:59 -08:00
use of instancing and impl inside the line rasterizer. Lyon is not needed anymore for plotting lines, but still used for plotting filled paths
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {showReticle: true, showSurveyStackControl: true, showOverlayStackControl: false, projection: "TAN", target: '15 16 57.636 -60 55 7.49', showProjectionControl: true, realFullscreen: true, showZoomControl: true, showSimbadPointerControl: true, showShareControl: true, showContextMenu: true, showCooGridControl: true, fullScreen: true, showCooGrid: true, fov: 90});
|
||||
|
||||
var moc_0_99 = A.MOCFromURL("./data//gw/gw_0.9.fits",{ name: "GW 90%", color: "#ff0000", opacity: 0.0, lineWidth: 3, fill: false, perimeter: true});
|
||||
var moc_0_99 = A.MOCFromURL("./data//gw/gw_0.9.fits",{ name: "GW 90%", color: "#ff0000", opacity: 0.0, lineWidth: 10, fill: false, perimeter: true});
|
||||
var moc_0_95 = A.MOCFromURL("./data/gw/gw_0.6.fits",{ name: "GW 60%", color: "#00ff00", opacity: 0.5, lineWidth: 3, fill: true, perimeter: true});
|
||||
var moc_0_5 = A.MOCFromURL("./data/gw/gw_0.3.fits",{ name: "GW 30%", color: "#00ffff", opacity: 0.5, lineWidth: 3, fill: true, perimeter: true});
|
||||
var moc_0_2 = A.MOCFromURL("./data/gw/gw_0.1.fits",{ name: "GW 10%", color: "#ff00ff", opacity: 0.5, lineWidth: 3, fill: true, perimeter: true});
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
reticleColor: '#ff89ff', // change reticle color
|
||||
reticleSize: 64, // change reticle size
|
||||
showContextMenu: true,
|
||||
showCooGrid: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::webgl_ctx::WebGlContext;
|
||||
pub struct ArrayBufferInstanced {
|
||||
buffer: WebGlBuffer,
|
||||
|
||||
len: usize,
|
||||
num_packed_data: usize,
|
||||
offset_idx: u32,
|
||||
|
||||
@@ -39,7 +40,7 @@ impl ArrayBufferInstanced {
|
||||
offset_idx: u32,
|
||||
stride: usize,
|
||||
sizes: &[usize],
|
||||
_offsets: &[usize],
|
||||
offsets: &[usize],
|
||||
usage: u32,
|
||||
data: B,
|
||||
) -> ArrayBufferInstanced {
|
||||
@@ -49,29 +50,43 @@ impl ArrayBufferInstanced {
|
||||
let num_f32_in_buf = data.len() as i32;
|
||||
|
||||
let num_instances = num_f32_in_buf / (num_f32_per_instance as i32);
|
||||
let len = data.len();
|
||||
|
||||
let buffer = gl.create_buffer().ok_or("failed to create buffer").unwrap_abort();
|
||||
let buffer = gl
|
||||
.create_buffer()
|
||||
.ok_or("failed to create buffer")
|
||||
.unwrap_abort();
|
||||
|
||||
// Bind the buffer
|
||||
gl.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, Some(buffer.as_ref()));
|
||||
// Pass the vertices data to the buffer
|
||||
f32::buffer_data_with_array_buffer_view(gl, data, WebGlRenderingCtx::ARRAY_BUFFER, usage);
|
||||
// Link to the shader
|
||||
let idx = offset_idx;
|
||||
for (idx, (size, offset)) in sizes.iter().zip(offsets.iter()).enumerate() {
|
||||
let idx = (idx as u32) + offset_idx;
|
||||
|
||||
f32::vertex_attrib_pointer_with_i32(gl, idx, *sizes.first().unwrap_abort() as i32, 0, 0);
|
||||
gl.enable_vertex_attrib_array(idx);
|
||||
f32::vertex_attrib_pointer_with_i32(
|
||||
gl,
|
||||
idx,
|
||||
*size as i32,
|
||||
stride as i32,
|
||||
*offset as i32,
|
||||
);
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
gl.vertex_attrib_divisor(idx, 1);
|
||||
#[cfg(feature = "webgl1")]
|
||||
gl.ext.angles.vertex_attrib_divisor_angle(idx, 1);
|
||||
gl.enable_vertex_attrib_array(idx);
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
gl.vertex_attrib_divisor(idx, 1);
|
||||
#[cfg(feature = "webgl1")]
|
||||
gl.ext.angles.vertex_attrib_divisor_angle(idx, 1);
|
||||
}
|
||||
|
||||
let num_packed_data = sizes.len();
|
||||
let gl = gl.clone();
|
||||
// Returns an instance that keeps only the buffer
|
||||
ArrayBufferInstanced {
|
||||
buffer,
|
||||
len,
|
||||
num_packed_data,
|
||||
offset_idx,
|
||||
|
||||
@@ -119,13 +134,30 @@ impl ArrayBufferInstanced {
|
||||
self.gl.disable_vertex_attrib_array(loc as u32);
|
||||
}
|
||||
|
||||
pub fn update<'a, B: BufferDataStorage<'a, f32>>(&self, buffer: B) {
|
||||
pub fn update<'a, B: BufferDataStorage<'a, f32>>(&mut self, usage: u32, data: B) {
|
||||
self.bind();
|
||||
f32::buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
if self.len >= data.len() {
|
||||
f32::buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
&self.gl,
|
||||
data,
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
);
|
||||
} else {
|
||||
self.len = data.len();
|
||||
|
||||
f32::buffer_data_with_array_buffer_view(
|
||||
&self.gl,
|
||||
data,
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
usage,
|
||||
);
|
||||
}
|
||||
|
||||
/*f32::buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
&self.gl,
|
||||
buffer,
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
);
|
||||
);*/
|
||||
/*self.gl.buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
0,
|
||||
|
||||
@@ -9,8 +9,8 @@ pub mod vao {
|
||||
use crate::object::element_array_buffer::ElementArrayBuffer;
|
||||
|
||||
use crate::webgl_ctx::WebGlContext;
|
||||
use std::collections::HashMap;
|
||||
use crate::Abort;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct VertexArrayObject {
|
||||
array_buffer: HashMap<&'static str, ArrayBuffer>,
|
||||
@@ -88,7 +88,10 @@ pub mod vao {
|
||||
}*/
|
||||
|
||||
pub fn num_elements(&self) -> usize {
|
||||
self.element_array_buffer.as_ref().unwrap_abort().num_elements()
|
||||
self.element_array_buffer
|
||||
.as_ref()
|
||||
.unwrap_abort()
|
||||
.num_elements()
|
||||
}
|
||||
|
||||
pub fn num_instances(&self) -> i32 {
|
||||
@@ -143,13 +146,14 @@ pub mod vao {
|
||||
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
|
||||
&mut self,
|
||||
attr: &'static str,
|
||||
usage: u32,
|
||||
array_data: B,
|
||||
) -> &mut Self {
|
||||
self.vao
|
||||
.array_buffer_instanced
|
||||
.get_mut(attr)
|
||||
.unwrap_abort()
|
||||
.update(array_data);
|
||||
.update(usage, array_data);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -333,13 +337,14 @@ pub mod vao {
|
||||
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
|
||||
&mut self,
|
||||
attr: &'static str,
|
||||
usage: u32,
|
||||
array_data: B,
|
||||
) -> &mut Self {
|
||||
self.vao
|
||||
.array_buffer_instanced
|
||||
.get_mut(attr)
|
||||
.unwrap_abort()
|
||||
.update(array_data);
|
||||
.update(usage, array_data);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -444,7 +449,10 @@ pub mod vao {
|
||||
}*/
|
||||
|
||||
pub fn num_elements(&self) -> usize {
|
||||
self.element_array_buffer.as_ref().unwrap_abort().num_elements()
|
||||
self.element_array_buffer
|
||||
.as_ref()
|
||||
.unwrap_abort()
|
||||
.num_elements()
|
||||
}
|
||||
|
||||
pub fn num_instances(&self) -> i32 {
|
||||
@@ -694,13 +702,14 @@ pub mod vao {
|
||||
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
|
||||
&mut self,
|
||||
attr: &'static str,
|
||||
usage: u32,
|
||||
array_data: B,
|
||||
) -> &mut Self {
|
||||
self.vao
|
||||
.array_buffer_instanced
|
||||
.get_mut(attr)
|
||||
.expect("cannot get attribute from the array buffer")
|
||||
.update(array_data);
|
||||
.update(usage, array_data);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ impl From<Error> for JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
// Num of shapes
|
||||
const _NUM_SHAPES: usize = 5;
|
||||
pub struct Manager {
|
||||
gl: WebGlContext,
|
||||
@@ -457,7 +458,11 @@ impl Catalog {
|
||||
#[cfg(feature = "webgl2")]
|
||||
self.vertex_array_object_catalog
|
||||
.bind_for_update()
|
||||
.update_instanced_array("center", VecData(&sources));
|
||||
.update_instanced_array(
|
||||
"center",
|
||||
WebGl2RenderingContext::DYNAMIC_DRAW,
|
||||
VecData(&sources),
|
||||
);
|
||||
}
|
||||
|
||||
fn draw(
|
||||
|
||||
@@ -11,14 +11,11 @@ use super::Renderer;
|
||||
use al_api::color::ColorRGBA;
|
||||
use al_core::SliceData;
|
||||
|
||||
use lyon::algorithms::{
|
||||
math::point,
|
||||
measure::{PathMeasurements, SampleType},
|
||||
path::Path,
|
||||
};
|
||||
use lyon::algorithms::{math::point, path::Path};
|
||||
|
||||
struct Meta {
|
||||
color: ColorRGBA,
|
||||
thickness: f32,
|
||||
off_indices: usize,
|
||||
num_indices: usize,
|
||||
}
|
||||
@@ -35,9 +32,16 @@ pub struct RasterizedLineRenderer {
|
||||
shader: Shader,
|
||||
vao: VertexArrayObject,
|
||||
|
||||
shader_line_instanced: Shader,
|
||||
|
||||
vao_idx: usize,
|
||||
|
||||
vertices: Vec<f32>,
|
||||
indices: Vec<u32>,
|
||||
meta: Vec<Meta>,
|
||||
|
||||
instanced_line_vaos: Vec<VertexArrayObject>,
|
||||
meta_instanced: Vec<Meta>,
|
||||
}
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
@@ -68,6 +72,38 @@ impl RasterizedLineRenderer {
|
||||
include_str!("../../../../glsl/webgl2/line/line_vertex.glsl"),
|
||||
include_str!("../../../../glsl/webgl2/line/line_frag.glsl"),
|
||||
)?;
|
||||
let shader_line_instanced = Shader::new(
|
||||
&gl,
|
||||
r#"#version 300 es
|
||||
precision lowp float;
|
||||
layout (location = 0) in vec2 p_a;
|
||||
layout (location = 1) in vec2 p_b;
|
||||
layout (location = 2) in vec2 vertex;
|
||||
|
||||
out vec2 out_uv;
|
||||
out vec3 out_p;
|
||||
|
||||
uniform float u_width;
|
||||
|
||||
void main() {
|
||||
vec2 x_b = p_b - p_a;
|
||||
vec2 y_b = normalize(vec2(-x_b.y, x_b.x));
|
||||
|
||||
vec2 p = p_a + x_b * vertex.x + y_b * u_width * 0.001 * vertex.y;
|
||||
gl_Position = vec4(p, 0.f, 1.f);
|
||||
}"#,
|
||||
r#"#version 300 es
|
||||
precision lowp float;
|
||||
out vec4 color;
|
||||
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main() {
|
||||
// Multiply vertex color with texture color (in linear space).
|
||||
// Linear color is written and blended in Framebuffer and converted to sRGB later
|
||||
color = u_color;
|
||||
}"#,
|
||||
)?;
|
||||
let mut vao = VertexArrayObject::new(&gl);
|
||||
|
||||
vao.bind_for_update()
|
||||
@@ -87,10 +123,17 @@ impl RasterizedLineRenderer {
|
||||
.unbind();
|
||||
|
||||
let meta = vec![];
|
||||
let meta_instanced = vec![];
|
||||
let gl = gl.clone();
|
||||
|
||||
let instanced_line_vaos = vec![];
|
||||
Ok(Self {
|
||||
gl,
|
||||
shader,
|
||||
shader_line_instanced,
|
||||
vao_idx: 0,
|
||||
instanced_line_vaos,
|
||||
meta_instanced,
|
||||
vao,
|
||||
meta,
|
||||
vertices,
|
||||
@@ -167,22 +210,57 @@ impl RasterizedLineRenderer {
|
||||
self.meta.push(Meta {
|
||||
off_indices,
|
||||
num_indices,
|
||||
thickness: 1.0,
|
||||
color: color.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
fn create_instanced_vao(&mut self) {
|
||||
let mut vao = VertexArrayObject::new(&self.gl);
|
||||
|
||||
vao.bind_for_update()
|
||||
// Store the cartesian position of the center of the source in the a instanced VBO
|
||||
.add_instanced_array_buffer(
|
||||
"ndc_pos",
|
||||
4 * std::mem::size_of::<f32>(),
|
||||
&[2, 2],
|
||||
&[0, 2 * std::mem::size_of::<f32>()],
|
||||
WebGl2RenderingContext::DYNAMIC_DRAW,
|
||||
SliceData(&[]),
|
||||
)
|
||||
.add_array_buffer(
|
||||
"vertices",
|
||||
2 * std::mem::size_of::<f32>(),
|
||||
&[2],
|
||||
&[0],
|
||||
WebGl2RenderingContext::STATIC_DRAW,
|
||||
SliceData(&[
|
||||
0_f32, -0.5_f32, 1_f32, -0.5_f32, 1_f32, 0.5_f32, 0_f32, 0.5_f32,
|
||||
]),
|
||||
)
|
||||
// Set the element buffer
|
||||
.add_element_buffer(
|
||||
WebGl2RenderingContext::STATIC_DRAW,
|
||||
SliceData(&[0_u16, 1_u16, 2_u16, 0_u16, 2_u16, 3_u16]),
|
||||
)
|
||||
// Unbind the buffer
|
||||
.unbind();
|
||||
|
||||
self.instanced_line_vaos.push(vao);
|
||||
}
|
||||
|
||||
pub fn add_stroke_paths<T>(
|
||||
&mut self,
|
||||
paths: impl Iterator<Item = PathVertices<T>>,
|
||||
thickness: f32,
|
||||
color: &ColorRGBA,
|
||||
style: &Style,
|
||||
_style: &Style,
|
||||
) where
|
||||
T: AsRef<[[f32; 2]]>,
|
||||
{
|
||||
let num_vertices = (self.vertices.len() / 2) as u32;
|
||||
//let num_vertices = (self.vertices.len() / 2) as u32;
|
||||
|
||||
let mut path_builder = Path::builder();
|
||||
/*let mut path_builder = Path::builder();
|
||||
|
||||
match &style {
|
||||
Style::None => {
|
||||
@@ -268,17 +346,40 @@ impl RasterizedLineRenderer {
|
||||
.unwrap_abort();
|
||||
}
|
||||
|
||||
let VertexBuffers { vertices, indices } = geometry;
|
||||
let VertexBuffers { vertices, indices } = geometry;*/
|
||||
if self.vao_idx == self.instanced_line_vaos.len() {
|
||||
// create a vao
|
||||
self.create_instanced_vao();
|
||||
}
|
||||
|
||||
let num_indices = indices.len();
|
||||
let off_indices = self.indices.len();
|
||||
let vao = &mut self.instanced_line_vaos[self.vao_idx];
|
||||
self.vao_idx += 1;
|
||||
|
||||
self.vertices.extend(vertices.iter().flatten());
|
||||
self.indices.extend(indices.iter());
|
||||
let mut buf: Vec<f32> = vec![];
|
||||
|
||||
self.meta.push(Meta {
|
||||
off_indices,
|
||||
num_indices,
|
||||
for PathVertices { vertices } in paths {
|
||||
let vertices = vertices.as_ref();
|
||||
let path_vertices_buf_iter = vertices
|
||||
.iter()
|
||||
.zip(vertices.iter().skip(1))
|
||||
.map(|(a, b)| [a[0], a[1], b[0], b[1]])
|
||||
.flatten();
|
||||
|
||||
buf.extend(path_vertices_buf_iter);
|
||||
}
|
||||
|
||||
vao.bind_for_update().update_instanced_array(
|
||||
"ndc_pos",
|
||||
WebGl2RenderingContext::DYNAMIC_DRAW,
|
||||
VecData(&buf),
|
||||
);
|
||||
|
||||
let num_instances = buf.len() / 4;
|
||||
|
||||
self.meta_instanced.push(Meta {
|
||||
off_indices: 0,
|
||||
thickness,
|
||||
num_indices: num_instances,
|
||||
color: color.clone(),
|
||||
});
|
||||
}
|
||||
@@ -308,6 +409,21 @@ impl RasterizedLineRenderer {
|
||||
}
|
||||
|
||||
//self.gl.enable(WebGl2RenderingContext::CULL_FACE);
|
||||
|
||||
// draw the lines
|
||||
let shader_bound = self.shader_line_instanced.bind(&self.gl);
|
||||
for (idx, meta) in self.meta_instanced.iter().enumerate() {
|
||||
let vao_bound = shader_bound
|
||||
.attach_uniform("u_color", &meta.color)
|
||||
.attach_uniform("u_width", &meta.thickness)
|
||||
.bind_vertex_array_object_ref(&self.instanced_line_vaos[idx]);
|
||||
|
||||
vao_bound.draw_elements_instanced_with_i32(
|
||||
WebGl2RenderingContext::TRIANGLES,
|
||||
0,
|
||||
meta.num_indices as i32,
|
||||
);
|
||||
}
|
||||
self.gl.disable(WebGl2RenderingContext::BLEND);
|
||||
|
||||
Ok(())
|
||||
@@ -318,8 +434,10 @@ impl Renderer for RasterizedLineRenderer {
|
||||
fn begin(&mut self) {
|
||||
self.vertices.clear();
|
||||
self.indices.clear();
|
||||
|
||||
self.meta.clear();
|
||||
|
||||
self.meta_instanced.clear();
|
||||
self.vao_idx = 0;
|
||||
}
|
||||
|
||||
fn end(&mut self) {
|
||||
|
||||
@@ -164,7 +164,7 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
|
||||
files.forEach(file => {
|
||||
const url = URL.createObjectURL(file);
|
||||
let moc = A.MOCFromURL(url, { name: file.name, fill: true, opacity: 0.4 });
|
||||
let moc = A.MOCFromURL(url, { name: file.name, edge: true });
|
||||
a.addMOC(moc);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ export let MOC = (function() {
|
||||
*
|
||||
* @class
|
||||
* @constructs MOC
|
||||
* @param {MOCOptions} options - Configuration options for the MOC.
|
||||
* @param {MOCOptions} options - Configuration options for the MOC
|
||||
*/
|
||||
let MOC = function(options) {
|
||||
//this.order = undefined;
|
||||
|
||||
Reference in New Issue
Block a user