diff --git a/examples/al-gw.html b/examples/al-gw.html
index c09ab433..3b209720 100644
--- a/examples/al-gw.html
+++ b/examples/al-gw.html
@@ -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});
diff --git a/examples/al-init-custom-options.html b/examples/al-init-custom-options.html
index 1b02b5d9..1dc96761 100644
--- a/examples/al-init-custom-options.html
+++ b/examples/al-init-custom-options.html
@@ -23,6 +23,7 @@
reticleColor: '#ff89ff', // change reticle color
reticleSize: 64, // change reticle size
showContextMenu: true,
+ showCooGrid: true,
}
);
});
diff --git a/src/core/al-core/src/object/array_buffer_instanced.rs b/src/core/al-core/src/object/array_buffer_instanced.rs
index a6e5a0f0..f4f0d218 100644
--- a/src/core/al-core/src/object/array_buffer_instanced.rs
+++ b/src/core/al-core/src/object/array_buffer_instanced.rs
@@ -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,
diff --git a/src/core/al-core/src/object/vertex_array_object.rs b/src/core/al-core/src/object/vertex_array_object.rs
index e34f8595..87b91ba2 100644
--- a/src/core/al-core/src/object/vertex_array_object.rs
+++ b/src/core/al-core/src/object/vertex_array_object.rs
@@ -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>(
&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>(
&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>(
&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
}
diff --git a/src/core/src/renderable/catalog/manager.rs b/src/core/src/renderable/catalog/manager.rs
index 409f2cc2..e21b54e3 100644
--- a/src/core/src/renderable/catalog/manager.rs
+++ b/src/core/src/renderable/catalog/manager.rs
@@ -26,6 +26,7 @@ impl From 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(
diff --git a/src/core/src/renderable/line/mod.rs b/src/core/src/renderable/line/mod.rs
index 751366b6..53fc8d7d 100644
--- a/src/core/src/renderable/line/mod.rs
+++ b/src/core/src/renderable/line/mod.rs
@@ -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,
indices: Vec,
meta: Vec,
+
+ instanced_line_vaos: Vec,
+ meta_instanced: Vec,
}
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::(),
+ &[2, 2],
+ &[0, 2 * std::mem::size_of::()],
+ WebGl2RenderingContext::DYNAMIC_DRAW,
+ SliceData(&[]),
+ )
+ .add_array_buffer(
+ "vertices",
+ 2 * std::mem::size_of::(),
+ &[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(
&mut self,
paths: impl Iterator- >,
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 = 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) {
diff --git a/src/js/DefaultActionsForContextMenu.js b/src/js/DefaultActionsForContextMenu.js
index 9915725a..3151d21b 100644
--- a/src/js/DefaultActionsForContextMenu.js
+++ b/src/js/DefaultActionsForContextMenu.js
@@ -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);
});
};
diff --git a/src/js/MOC.js b/src/js/MOC.js
index 4b04829d..46f9e8ae 100644
--- a/src/js/MOC.js
+++ b/src/js/MOC.js
@@ -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;