This commit is contained in:
Tsuki 2024-08-21 22:00:45 +08:00
parent 480888e8fc
commit f25ed801f5
16 changed files with 235 additions and 54 deletions

View File

@ -51,6 +51,7 @@ femtovg = "0.9.2"
[features]
default = ["sdf_font"]
sdfer_use_f64_instead_of_f32 = []
normal_font = []
sdf_font = []
inparser = []

View File

@ -33,14 +33,26 @@ impl Camera {
self.upward
}
pub fn get_center(&self) -> Vec3 {
self.center
}
pub fn set_upward(&mut self, upward: Vec3) {
self.upward = upward;
}
pub fn set_center(&mut self, center: Vec3) {
self.center = center;
}
pub fn get_view_matrix(&self) -> Mat4x4 {
let l = self.center;
look_at(&self.pos, &l, &self.upward)
}
pub fn front(&self) -> Vec3 {
self.center - self.pos
}
}
impl Default for Camera {

View File

@ -137,6 +137,15 @@ impl AttaWithBuffer for AggFastPath {
config: &<Self as Graphics>::Config,
) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
let points = data.iter().map(|v| &v.points).flatten().collect::<Vec<_>>();
let mut lens = Vec::with_capacity(data.len());
let mut sum = 0;
for num in data.iter().map(|v| v.len()) {
lens.push(sum);
sum += num;
}
let point_lens = data.iter().map(|d| d.len()).collect::<Vec<_>>();
let mut vbo = Vec::with_capacity(points.len() * 10);
for p in points {
vbo.extend_from_slice(&[
@ -145,8 +154,17 @@ impl AttaWithBuffer for AggFastPath {
]);
}
let mut ebo = vec![];
for e in data.iter().map(|v| &v.ebo).flatten() {
ebo.extend_from_slice(e);
for (idx, e) in data.iter().map(|v| &v.ebo).enumerate() {
if idx > 0 {
let len = lens[idx - 1] as u32;
for e in e.iter() {
ebo.extend_from_slice(&[e[0] + len, e[1] + len, e[2] + len]);
}
} else {
for e in e.iter() {
ebo.extend_from_slice(e);
}
}
}
let len = ebo.len() as i32;

View File

@ -147,6 +147,24 @@ impl<'a> Cache<'a> {
self.cache.get(&c).unwrap()
}
fn test(&self) {
let mut data = vec![0; 1024 * 1024];
unsafe {
self.gl
.bind_texture(glow::TEXTURE_2D, Some(self.tex.native()));
self.gl.get_tex_image(
glow::TEXTURE_2D,
0,
glow::RED,
glow::UNSIGNED_BYTE,
glow::PixelPackData::Slice(&mut data),
);
self.gl.bind_texture(glow::TEXTURE_2D, None);
}
let img = image::GrayImage::from_raw(1024, 1024, data).unwrap();
img.save("test.png").unwrap();
}
}
#[derive(Clone)]
@ -220,7 +238,7 @@ impl<'a> Text<'a> {
let u_fill = self.program.get_uniform_location(&self.gl, "uFill");
unsafe {
self.gl.uniform_4_f32(conf.as_ref(), 5.0, 0.0, 0.0, 0.0);
self.gl.uniform_4_f32(conf.as_ref(), 5.0, 3.0, 0.0, 0.0);
self.gl.uniform_1_i32(u_mode.as_ref(), -1);
self.gl.uniform_4_f32(u_border.as_ref(), 0.0, 0.0, 0.0, 0.0);
self.gl.uniform_4_f32(u_stroke.as_ref(), 1.0, 1.0, 1.0, 1.0);
@ -319,10 +337,10 @@ impl<'a> AttaWithBuffer for Text<'a> {
let vbo = gl.create_buffer().unwrap();
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
gl.enable_vertex_attrib_array(0);
gl.vertex_attrib_pointer_f32(0, 4, glow::FLOAT, false, 32, 0);
gl.vertex_attrib_pointer_f32(0, 4, glow::FLOAT, false, 48, 0);
gl.enable_vertex_attrib_array(1);
gl.vertex_attrib_pointer_f32(1, 4, glow::FLOAT, false, 32, 16);
gl.vertex_attrib_pointer_f32(1, 4, glow::FLOAT, false, 48, 16);
gl.bind_vertex_array(None);
gl.bind_buffer(glow::ARRAY_BUFFER, None);

View File

@ -3,6 +3,7 @@ pub mod colormap;
mod colormesh;
pub mod font;
pub mod hello;
pub mod plane;
pub mod ppi;
pub mod threed;
pub mod tools;
@ -14,6 +15,7 @@ use crate::{
components::Program,
errors::*,
graphics::font::FontConfig,
pg::layout_type::ViewPort,
ui::{operation::Projection, typ::CameraOP},
};
@ -125,6 +127,7 @@ pub trait AttachWithMouse {
state: &Self::State,
camera: &mut Camera,
projection: &mut Projection,
viewport: &ViewPort,
) -> bool;
fn reset(&mut self);

7
src/graphics/plane.rs Normal file
View File

@ -0,0 +1,7 @@
pub struct Plane {}
impl Plane {
pub fn new() -> Self {
Self {}
}
}

View File

@ -5,6 +5,7 @@ use super::transforms::{position::Position, trackball::TrackballModel};
use super::{AttaWithProgram, AttachWithMouse};
use crate::camera::{self, Camera};
use crate::errors::*;
use crate::pg::layout_type::ViewPort;
use crate::ui::operation::Projection;
use glow::HasContext;
use nalgebra_glm::{Mat4, Vec3};
@ -46,6 +47,7 @@ impl AttachWithMouse for Trackball {
state: &Self::State,
camera: &mut Camera,
projection: &mut Projection,
viewport: &ViewPort,
) -> bool {
match state {
&super::MouseState::Wheel(delta) => {

View File

@ -1,3 +1,4 @@
pub mod plane;
pub mod polar;
pub mod position;
pub mod trackball;

View File

@ -0,0 +1,88 @@
use crate::components::{CodeType, Program, Snippet};
use crate::errors::Result;
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
use crate::pg::layout_type::ViewPort;
use glow::HasContext;
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
use nalgebra_glm::vec3;
#[derive(Debug, Clone)]
pub struct PlaneTrans {}
impl AttachWithMouse for PlaneTrans {
type State = MouseState;
fn attach_with_mouse(
&mut self,
state: &Self::State,
camera: &mut crate::camera::Camera,
projection: &mut crate::ui::operation::Projection,
viewport: &ViewPort,
) -> bool {
let watch_vec = camera.front();
let viewport_size = viewport.size();
let if_vertical = true;
match state {
MouseState::Drag { from, delta } => {
if if_vertical {
// Radian
let fov = projection.fov().to_radians();
let aspect = projection.aspect();
// Z_near
let z_near = projection.z_near();
let h = 2.0 * z_near * (fov / 2.0).tan();
let w = h * aspect;
let move_width = (delta[0] * w) / viewport_size[0];
let move_height = (delta[1] * h) / viewport_size[1];
let up = camera.get_upward();
let right = watch_vec.cross(&up).normalize();
let _move = move_width * right + move_height * up;
camera.set_position(camera.get_position() + _move);
camera.set_center(camera.get_center() + _move);
} else {
}
}
MouseState::Wheel(delta) => {
projection.set_fov((projection.fov() - delta).clamp(15.0, 120.0));
}
_ => {}
}
true
}
fn init_camera(&self) -> crate::camera::Camera {
crate::camera::Camera::new(
vec3(0.0, 20.0, 0.0),
vec3(0.0, 0.0, 1.0),
vec3(0.0, 0.0, 0.0),
)
}
fn reset(&mut self) {}
}
impl AttaWithProgram for PlaneTrans {
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
unsafe {
let loc = program.get_uniform_location(gl, "trackball_model");
let trackball = nalgebra_glm::rotate_x(&nalgebra_glm::identity(), 90.0f32.to_radians());
gl.uniform_matrix_4_f32_slice(loc.as_ref(), false, trackball.as_slice());
}
Ok(())
}
}
impl Default for PlaneTrans {
fn default() -> Self {
Self {}
}
}

View File

@ -25,7 +25,7 @@ impl TrackballModel {
count: 0,
model: Matrix4::identity(),
renorm_count: 97,
trackball_size: 100.0,
trackball_size: 20.0,
x: 0.0,
y: 0.0,
theta,

View File

@ -11,6 +11,7 @@ use crate::graphics::collections::agg_fast_path::AggFastPath;
use crate::graphics::font::Text;
use crate::graphics::ppi::PPI;
use crate::graphics::threed::Trackball;
use crate::graphics::transforms::plane::PlaneTrans;
use crate::graphics::transforms::viewport;
use crate::graphics::{AttaWithProgram, AttachWithMouse};
use crate::ui::operation::Operation;
@ -85,7 +86,7 @@ impl<'gl> Programs<'gl> {
pub fn draw_modules(
&mut self,
modules: &mut ModulePackage<'gl>,
operation: &Operation<Trackball>,
operation: &Operation<PlaneTrans>,
viewport: &ViewPort,
) -> Result<()> {
match &mut modules.modules {

View File

@ -4,6 +4,7 @@ use font::{FontConfig, LineStyle, PositionText, TextLine};
use glow::HasContext;
use std::rc::Rc;
use tracker::track;
use transforms::plane::PlaneTrans;
use transforms::viewport;
use crate::font_manager::{FontSize, FontStyle};
@ -65,21 +66,39 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
config: &PPIModuleConfig,
) -> Result<()> {
let config = config.to_line_config();
// Create the path
let mut path = Path::new(true);
// Will be changed in the future
let outskirt = 10.0;
for seg in 0..500 {
let angle = 2f32 * f32::consts::PI / 500.0 * seg as f32;
let x = (angle.cos() * outskirt) as f32;
let y = (angle.sin() * outskirt) as f32;
path.push([x, y, 0.0]);
}
path.finish();
let mut paths = vec![];
let (vbo, ebo, len) = self.line_program.bake(&vec![path], &config)?;
for range in 1..=6 {
let r = outskirt / 5.0 * range as f32;
// Create the path
let mut path = Path::new(true);
// Draw the circle
for seg in 0..200 {
let angle = 2f32 * f32::consts::PI / 200.0 * seg as f32;
let x = (angle.cos() * r) as f32;
let y = (angle.sin() * r) as f32;
path.push([x, y, 0.01]);
}
path.finish();
paths.push(path);
}
let a = 2.0 * f32::consts::PI / 6.0;
for _a in 0..7 {
let mut path = Path::new(false);
let x = (a * _a as f32).cos() * outskirt;
let y = (a * _a as f32).sin() * outskirt;
path.push([0.0, 0.0, 0.01]);
path.push([x, y, 0.01]);
path.finish();
paths.push(path);
}
let (vbo, ebo, len) = self.line_program.bake(&paths, &config)?;
attach.bind_data(&vbo, ebo.as_ref(), len);
Ok(())
}
@ -89,12 +108,10 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
match font_style {
FontConfig::Textline(line_style, font_style) => {
let new_text = TextLine::new("ABC", Some(font_style), None);
let new_text = TextLine::new("Hello,World", Some(font_style), None);
let position_text =
PositionText::new(new_text, [0.0, 0.0, 0.0], font::Anchor::BottomCenter);
let text_pg_config = config.to_font_config();
let (vbo, ebo, len) = self.text_program.bake(&position_text, &text_pg_config)?;
attach.bind_data(&vbo, ebo.as_ref(), len);
}
@ -107,7 +124,8 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
type Cursor = PPIPackage<'a>;
type Data = Data;
type Operation = Trackball;
// type Operation = Trackball;
type Operation = PlaneTrans;
fn render<'dt>(
&mut self,
@ -223,7 +241,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
// Bind the data
self.bind_ppi_pg(&mut ppi_attach, &data.borrow(), &config);
self.bind_line_pg(&mut line_attach, &data.borrow(), &config);
self.bind_tick(&mut tick_attach, &data.borrow(), &config);
// self.bind_tick(&mut tick_attach, &data.borrow(), &config);
Ok(PPIPackage::new(
config,
@ -333,8 +351,8 @@ impl Default for PPIModuleConfig {
Self {
ticks: true,
line_color: [1.0, 1.0, 1.0, 1.0],
line_width: 2.0,
line_antialias: 2.0,
line_width: 1.5,
line_antialias: 0.5,
layer: 0,
colors: vec![],
color_range: [0.0, 0.0],

View File

@ -18,7 +18,6 @@ impl FontVertex {
// texcoord (left top, right bottom)
layout(location = 0) in vec4 texcoord;
// Relative position (x, y, width, height)
layout(location = 1) in vec4 relative_position;
@ -29,7 +28,6 @@ impl FontVertex {
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
vs_out.texcoord = texcoord;
vs_out.pos = relative_position;
}
@ -43,6 +41,7 @@ impl FontGeometry {
pub fn new() -> Self {
let mut transform = Trackball::new().0;
let raw = glsl! {
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
@ -55,6 +54,7 @@ impl FontGeometry {
uniform vec2 atlas_shape;
out vec2 v_texCoord;
out vec2 UV_coord;
in VS_OUT {
vec4 texcoord;
@ -76,6 +76,10 @@ impl FontGeometry {
vec2 tex_coord_lt = gs_in[0].texcoord.xy / atlas_shape;
vec2 tex_coord_rb = gs_in[0].texcoord.zw / atlas_shape;
// uv_coord
vec2 uv_coord_lt = gs_in[0].texcoord.xy;
vec2 uv_coord_rb = gs_in[0].texcoord.zw;
// Char Size
vec2 size = vec2(width, hgt);
@ -97,19 +101,23 @@ impl FontGeometry {
// Emit vertices
gl_Position = vec4(ndc_left_top.x, ndc_right_bottom.y, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = vec2(tex_coord_lt.x, tex_coord_lt.y);
v_texCoord = vec2(tex_coord_lt.x, tex_coord_rb.y);
UV_coord = vec2(uv_coord_lt.x, uv_coord_rb.y);
EmitVertex();
gl_Position = vec4(ndc_right_bottom.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = tex_coord_rb;
UV_coord = uv_coord_rb;
EmitVertex();
gl_Position = vec4(ndc_left_top.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = tex_coord_lt;
UV_coord = uv_coord_lt;
EmitVertex();
gl_Position = vec4(ndc_right_bottom.x, ndc_left_top.y, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = vec2(tex_coord_rb.x, tex_coord_lt.y);
UV_coord = vec2(uv_coord_rb.x, uv_coord_lt.y);
EmitVertex();
EndPrimitive();
@ -128,6 +136,7 @@ impl FontFragment {
let raw = glsl! {
uniform sampler2D atlas_data;
in vec2 v_texCoord;
in vec2 UV_coord;
uniform vec4 uClipUV;
uniform vec4 uSdfConfig;
@ -161,20 +170,14 @@ impl FontFragment {
vec4 fillColor = uFill;
vec4 strokeColor = uStroke;
float scale = getUVScale(v_texCoord);
float scale = getUVScale(UV_coord);
vec4 texture = getTexture(v_texCoord);
float dis = texture.r;
if (dis<0.5) {
discard;
}else {
fragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
// float sdfRaw = 0.0;
// float mark = 0.0;
// float sdf;
// float sdfRadius = uSdfConfig.x;
@ -189,21 +192,15 @@ impl FontFragment {
// fillColor = vec4(texture.rgb, fillColor.a);
// }
// // if (gl_FragCoord.x < uClipUV.x || gl_FragCoord.y < uClipUV.y || gl_FragCoord.x > uClipUV.z || gl_FragCoord.y > uClipUV.w) {
// // discard;
// // }
// // Compute mask based on SDF
// float mask = clamp(sdf, 0.0, 1.0);
// // Final color blending logic here
// Final color blending logic here
// fragColor = vec4(fillColor.rgb + mark, mask + mark);
fragColor = vec4(dis,dis,dis,dis);
// if(mask < 0.5) {
// fragColor = vec4(0.0, 0.0, 0.0, 0.0);
// } else {
// fragColor = vec4(fillColor.rgb, 1.0);
// }
// fragColor = vec4(fillColor.rgb + mark, fillColor.a * mask + mark);
// fragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
};

View File

@ -3,6 +3,7 @@ use crate::{
camera::Camera,
components::Program,
graphics::{AttaWithProgram, AttachWithMouse},
pg::layout_type::ViewPort,
};
pub struct Operation<T: AttachWithMouse> {
@ -23,11 +24,12 @@ impl<T: AttachWithMouse + AttaWithProgram> Operation<T> {
}
}
pub fn deal_io(&mut self, io: &super::io::IO) {
pub fn deal_io(&mut self, viewport: &ViewPort, io: &super::io::IO) {
self.need_update = self.operation.attach_with_mouse(
&T::State::from_context(io),
&mut self.camera,
&mut self.projection,
viewport,
);
}
@ -56,10 +58,10 @@ impl<T: AttachWithMouse + AttaWithProgram> Operation<T> {
self.operation.attach_with_program(gl, program);
}
pub fn attach_with_mouse(&mut self, camera_op: &T::State) -> bool {
self.operation
.attach_with_mouse(camera_op, &mut self.camera, &mut self.projection)
}
// pub fn attach_with_mouse(&mut self, camera_op: &T::State) -> bool {
// self.operation
// .attach_with_mouse(camera_op, &mut self.camera, &mut self.projection)
// }
pub fn is_need_update(&self) -> bool {
self.need_update
@ -118,6 +120,18 @@ impl Projection {
self.fov
}
pub fn z_far(&self) -> f32 {
self.z_far
}
pub fn z_near(&self) -> f32 {
self.z_near
}
pub fn aspect(&self) -> f32 {
self.aspect
}
fn as_slice(&self) -> &[f32] {
self.projection.as_slice()
}

View File

@ -3,6 +3,7 @@ use std::thread::panicking;
use super::{CameraOP, Layout, LayoutAttach, LayoutMod, Size};
use crate::camera::Camera;
use crate::graphics::threed::Trackball;
use crate::graphics::transforms::plane::PlaneTrans;
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
use crate::pg::ModulePackage;
use crate::pg::{_ModulePackage, layout_type::ViewPort};
@ -136,7 +137,7 @@ impl LayoutMod for MainLoad {
if ui.is_window_hovered() {
let cio = IO::new(ui);
apptyp.operation.deal_io(&cio);
apptyp.operation.deal_io(&apptyp.main_viewport, &cio);
}
});
});
@ -146,7 +147,7 @@ impl LayoutMod for MainLoad {
let typ = MainLoadAttach {
main_viewport: ViewPort::<NativeRenderbuffer>::new(gl, true),
packages: Vec::new(),
operation: Operation::new(Trackball::default(), 16.0 / 9.0, 45.0, 0.1, 1000.0),
operation: Operation::new(PlaneTrans::default(), 16.0 / 9.0, 45.0, 0.1, 1000.0),
};
typ
}
@ -159,7 +160,7 @@ impl MainLoad {
}
pub struct MainLoadAttach<'gl> {
operation: Operation<Trackball>,
operation: Operation<PlaneTrans>,
main_viewport: ViewPort,
packages: Vec<ModulePackage<'gl>>,
}

BIN
test.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 15 KiB