ttt
This commit is contained in:
parent
04776b4f45
commit
acbc81b733
62
Cargo.lock
generated
62
Cargo.lock
generated
@ -422,6 +422,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
|
"crossbeam",
|
||||||
"epoxy",
|
"epoxy",
|
||||||
"euclid",
|
"euclid",
|
||||||
"femtovg",
|
"femtovg",
|
||||||
@ -429,6 +430,7 @@ dependencies = [
|
|||||||
"geo-macros",
|
"geo-macros",
|
||||||
"geo-types",
|
"geo-types",
|
||||||
"geojson 0.24.1",
|
"geojson 0.24.1",
|
||||||
|
"gl",
|
||||||
"glib",
|
"glib",
|
||||||
"glib-build-tools",
|
"glib-build-tools",
|
||||||
"glib-macros",
|
"glib-macros",
|
||||||
@ -631,47 +633,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam"
|
||||||
version = "0.5.8"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.3"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.15"
|
version = "0.9.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"memoffset 0.9.0",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.16"
|
version = "0.8.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crunchy"
|
name = "crunchy"
|
||||||
@ -1358,6 +1373,15 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gl"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404"
|
||||||
|
dependencies = [
|
||||||
|
"gl_generator 0.14.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gl_generator"
|
name = "gl_generator"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -3846,7 +3870,7 @@ checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.76",
|
"proc-macro2 1.0.76",
|
||||||
"quote 1.0.35",
|
"quote 1.0.35",
|
||||||
"xml-rs 0.7.0",
|
"xml-rs 0.8.19",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -47,6 +47,8 @@ once_cell = "1.19.0"
|
|||||||
relm4-icons = {version="0.6.0",features=["add-filled","delete-filled","chevron-up-filled","chevron-down-filled"]}
|
relm4-icons = {version="0.6.0",features=["add-filled","delete-filled","chevron-up-filled","chevron-down-filled"]}
|
||||||
surfman = "0.8.1"
|
surfman = "0.8.1"
|
||||||
euclid = "0.22.9"
|
euclid = "0.22.9"
|
||||||
|
gl = "0.14.0"
|
||||||
|
crossbeam = "0.8.4"
|
||||||
# plotters-cairo = "0.5.0"
|
# plotters-cairo = "0.5.0"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
50
back.txt
50
back.txt
@ -343,3 +343,53 @@ pub enum CoordType {
|
|||||||
// .blue(250 as f32 / 255.0)
|
// .blue(250 as f32 / 255.0)
|
||||||
// .build(),
|
// .build(),
|
||||||
// ];
|
// ];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// let texture = ctx.create_texture().expect("Cannot create texture");
|
||||||
|
|
||||||
|
// ctx.bind_texture(glow::TEXTURE_2D, Some(texture));
|
||||||
|
// ctx.tex_image_2d(
|
||||||
|
// glow::TEXTURE_2D,
|
||||||
|
// 0,
|
||||||
|
// glow::RGBA as i32,
|
||||||
|
// 3000,
|
||||||
|
// 3000,
|
||||||
|
// 0,
|
||||||
|
// glow::RGBA,
|
||||||
|
// glow::UNSIGNED_BYTE,
|
||||||
|
// None,
|
||||||
|
// );
|
||||||
|
// ctx.tex_parameter_i32(
|
||||||
|
// glow::TEXTURE_2D,
|
||||||
|
// glow::TEXTURE_MIN_FILTER,
|
||||||
|
// glow::LINEAR as i32,
|
||||||
|
// );
|
||||||
|
// ctx.tex_parameter_i32(
|
||||||
|
// glow::TEXTURE_2D,
|
||||||
|
// glow::TEXTURE_MAG_FILTER,
|
||||||
|
// glow::LINEAR as i32,
|
||||||
|
// );
|
||||||
|
// ctx.framebuffer_texture_2d(
|
||||||
|
// glow::FRAMEBUFFER,
|
||||||
|
// glow::COLOR_ATTACHMENT0,
|
||||||
|
// glow::TEXTURE_2D,
|
||||||
|
// Some(texture),
|
||||||
|
// 0,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// let depth_buffer = ctx
|
||||||
|
// .create_renderbuffer()
|
||||||
|
// .expect("Cannot create renderbuffer");
|
||||||
|
// ctx.bind_renderbuffer(glow::RENDERBUFFER, Some(depth_buffer));
|
||||||
|
// ctx.renderbuffer_storage(glow::RENDERBUFFER, glow::DEPTH_COMPONENT16, 3000, 3000);
|
||||||
|
// ctx.framebuffer_renderbuffer(
|
||||||
|
// glow::FRAMEBUFFER,
|
||||||
|
// glow::DEPTH_ATTACHMENT,
|
||||||
|
// glow::RENDERBUFFER,
|
||||||
|
// Some(depth_buffer),
|
||||||
|
// );
|
||||||
|
// // let id = NonZeroU32::new(ctx.get_parameter_i32(glow::DRAW_FRAMEBUFFER_BINDING) as u32)
|
||||||
|
// // .expect("No GTK provided framebuffer binding");
|
||||||
|
|
||||||
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
use crate::pipeline::offscreen_renderer::OffscreenRenderer;
|
use crate::pipeline::offscreen_renderer::OffscreenRenderer;
|
||||||
use crate::render::{Target, CMS};
|
use crate::render::{Target, CMS};
|
||||||
|
// use crate::OFFSCREEN;
|
||||||
use crate::{
|
use crate::{
|
||||||
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
|
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
|
||||||
coords::{proj::Mercator, Mapper},
|
coords::{proj::Mercator, Mapper},
|
||||||
@ -82,8 +83,11 @@ impl Component for MonitorModel {
|
|||||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
|
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
|
||||||
match message {
|
match message {
|
||||||
MonitorInputMsg::AddLayer(layer) => {
|
MonitorInputMsg::AddLayer(layer) => {
|
||||||
|
// let mut canvas = OFFSCREEN.lock().unwrap();
|
||||||
sender.oneshot_command(async move {
|
sender.oneshot_command(async move {
|
||||||
let new_canvas = OffscreenRenderer::new().unwrap();
|
let mut back = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
|
let canvas = back.create_canvas();
|
||||||
|
// let new_canvas = OffscreenRenderer::new().unwrap();
|
||||||
let f = {
|
let f = {
|
||||||
let p = layer.get_prepare();
|
let p = layer.get_prepare();
|
||||||
let mut _p = p.lock().unwrap();
|
let mut _p = p.lock().unwrap();
|
||||||
@ -94,9 +98,9 @@ impl Component for MonitorModel {
|
|||||||
|
|
||||||
let map: Mapper = Mercator::default().into();
|
let map: Mapper = Mercator::default().into();
|
||||||
let cms = CMS::new(map, (3000.0, 3000.0));
|
let cms = CMS::new(map, (3000.0, 3000.0));
|
||||||
let canvas = new_canvas.create_canvas();
|
|
||||||
let canvas = Arc::new(Mutex::new(canvas));
|
let canvas = Arc::new(Mutex::new(canvas));
|
||||||
let c = f(imp, canvas, cms).await;
|
let c = f(imp, canvas, cms).await;
|
||||||
|
|
||||||
Some(c)
|
Some(c)
|
||||||
// None
|
// None
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
mod utils;
|
mod utils;
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::{gio, glib, Application, ApplicationWindow};
|
use gtk::{gio, glib, Application, ApplicationWindow};
|
||||||
use pipeline::offscreen_renderer::OffscreenRenderer;
|
use pipeline::offscreen_renderer::OffscreenRenderer;
|
||||||
use relm4::menu;
|
|
||||||
use relm4::RelmApp;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use utils::creator;
|
|
||||||
mod chart;
|
mod chart;
|
||||||
mod components;
|
mod components;
|
||||||
mod coords;
|
mod coords;
|
||||||
@ -19,13 +15,16 @@ mod render;
|
|||||||
mod window;
|
mod window;
|
||||||
use components::app::{AppMode, AppModel};
|
use components::app::{AppMode, AppModel};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||||
|
|
||||||
static RUNTIME: Lazy<Runtime> =
|
static RUNTIME: Lazy<Runtime> =
|
||||||
Lazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
Lazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
||||||
|
|
||||||
// static OFFSCREEN: Lazy<OffscreenRenderer> = Lazy::new(|| OffscreenRenderer::new().expect("Can't create offscreen renderer."));
|
// static OFFSCREEN: Lazy<Mutex<OffscreenRenderer>> = Lazy::new(|| {
|
||||||
|
// Mutex::new(OffscreenRenderer::new(3000, 3000).expect("Can't create offscreen renderer."))
|
||||||
|
// });
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Load GL pointers from epoxy (GL context management library used by GTK).
|
// Load GL pointers from epoxy (GL context management library used by GTK).
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use ndarray::parallel::prelude::*;
|
|||||||
use ndarray::{Array2, ArrayView2};
|
use ndarray::{Array2, ArrayView2};
|
||||||
use num_traits::{Num, AsPrimitive, FromPrimitive};
|
use num_traits::{Num, AsPrimitive, FromPrimitive};
|
||||||
pub mod offscreen_renderer;
|
pub mod offscreen_renderer;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
coords::Mapper,
|
coords::Mapper,
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
|
use super::utils::*;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
use lazy_static::__Deref;
|
use gl;
|
||||||
use std::borrow::BorrowMut;
|
use gl::types::{GLchar, GLenum, GLint, GLuint, GLvoid};
|
||||||
|
use glow::HasContext;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::{Mutex, RwLock};
|
use std::sync::{Mutex, RwLock};
|
||||||
use std::{cell::RefCell, sync::Arc};
|
use std::{cell::RefCell, sync::Arc};
|
||||||
use surfman::platform::system::connection;
|
|
||||||
use surfman::{
|
use surfman::{
|
||||||
device, Adapter, Connection, Context, ContextAttributeFlags, Device, Error, GLApi,
|
device, Adapter, Connection, Context, ContextAttributeFlags, Device, Error, GLApi,
|
||||||
NativeConnection, NativeDevice,
|
NativeConnection, NativeDevice,
|
||||||
@ -16,66 +17,129 @@ pub struct OffscreenRenderer {
|
|||||||
context: Arc<RwLock<Context>>,
|
context: Arc<RwLock<Context>>,
|
||||||
device: Device,
|
device: Device,
|
||||||
fbo: NonZeroU32,
|
fbo: NonZeroU32,
|
||||||
// canvas: Arc<Mutex<CanvasWrapper>>,
|
glow_ctx: Option<glow::Context>,
|
||||||
|
size: (i32, i32), // canvas: Arc<Mutex<CanvasWrapper>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OffscreenRenderer {
|
impl OffscreenRenderer {
|
||||||
pub fn new() -> Result<Self, surfman::Error> {
|
pub fn new(width: i32, height: i32) -> Result<Self, surfman::Error> {
|
||||||
let connection = Connection::new()?;
|
let connection = Connection::new()?;
|
||||||
let adapter = connection.create_hardware_adapter()?;
|
let adapter = connection.create_adapter()?;
|
||||||
let mut device = connection.create_device(&adapter)?;
|
let mut device = connection.create_device(&adapter)?;
|
||||||
let api = connection.gl_api();
|
|
||||||
|
|
||||||
let descriptor = device.create_context_descriptor(&surfman::ContextAttributes {
|
let descriptor = device.create_context_descriptor(&surfman::ContextAttributes {
|
||||||
version: surfman::GLVersion::new(3, 3),
|
version: surfman::GLVersion::new(4, 1),
|
||||||
flags: ContextAttributeFlags::DEPTH.union(ContextAttributeFlags::STENCIL),
|
flags: ContextAttributeFlags::empty(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut context = device.create_context(&descriptor, None)?;
|
let mut context = device.create_context(&descriptor, None)?;
|
||||||
|
|
||||||
let surface = device.create_surface(
|
let surface = device.create_surface(
|
||||||
&context,
|
&context,
|
||||||
surfman::SurfaceAccess::GPUCPU,
|
surfman::SurfaceAccess::GPUOnly,
|
||||||
surfman::SurfaceType::Generic {
|
surfman::SurfaceType::Generic {
|
||||||
size: euclid::Size2D::new(3000, 3000),
|
size: euclid::Size2D::new(width, height),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let surface_info = device.surface_info(&surface);
|
|
||||||
device
|
device
|
||||||
.bind_surface_to_context(&mut context, surface)
|
.bind_surface_to_context(&mut context, surface)
|
||||||
.expect("Failed to bind surface to context");
|
.expect("Failed to bind surface to context");
|
||||||
|
|
||||||
device.make_context_current(&context).unwrap();
|
device.make_context_current(&context).unwrap();
|
||||||
|
|
||||||
|
let surface_info = device.context_surface_info(&context).unwrap().unwrap();
|
||||||
|
gl::load_with(|symbol_name| device.get_proc_address(&context, symbol_name));
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||||
|
gl::BindFramebuffer(gl::FRAMEBUFFER, surface_info.framebuffer_object);
|
||||||
|
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
context: Arc::new(RwLock::new(context)),
|
context: Arc::new(RwLock::new(context)),
|
||||||
device,
|
device,
|
||||||
fbo: NonZeroU32::new(surface_info.framebuffer_object).unwrap(),
|
fbo: NonZeroU32::new(surface_info.framebuffer_object).unwrap(),
|
||||||
|
glow_ctx: None,
|
||||||
|
size: (width, height),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_canvas(&self) -> CanvasWrapper {
|
pub fn create_canvas(&mut self) -> CanvasWrapper {
|
||||||
use glow::HasContext;
|
let (w, h) = self.size;
|
||||||
static LOAD_FN: fn(&str) -> *const std::ffi::c_void =
|
let mut pixels: Vec<u8> = vec![0; w as usize * h as usize * 4];
|
||||||
|s| epoxy::get_proc_addr(s) as *const _;
|
|
||||||
|
|
||||||
let (mut renderer, fbo) = unsafe {
|
let (mut renderer, fbo, ctx) = unsafe {
|
||||||
let renderer = OpenGl::new_from_function(LOAD_FN).expect("Cannot create renderer");
|
let renderer = OpenGl::new_from_function(|s| {
|
||||||
let ctx = glow::Context::from_loader_function(LOAD_FN);
|
self.device
|
||||||
|
.get_proc_address(&self.context.read().unwrap(), s) as *const _
|
||||||
|
})
|
||||||
|
.expect("Cannot create renderer");
|
||||||
|
|
||||||
let fbo = ctx.create_framebuffer().expect("can't create framebuffer");
|
let ctx = glow::Context::from_loader_function(|s| {
|
||||||
let cbo = ctx.create_buffer().expect("can't create color buffer");
|
self.device
|
||||||
|
.get_proc_address(&self.context.read().unwrap(), s) as *const _
|
||||||
|
});
|
||||||
|
|
||||||
// let id = NonZeroU32::new(ctx.get_parameter_i32(glow::DRAW_FRAMEBUFFER_BINDING) as u32)
|
let fbo = glow::NativeFramebuffer(self.fbo);
|
||||||
// .expect("No GTK provided framebuffer binding");
|
|
||||||
ctx.bind_framebuffer(glow::FRAMEBUFFER, None);
|
ctx.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||||
// let fbo = glow::NativeFramebuffer(id);
|
(renderer, fbo, ctx)
|
||||||
(renderer, fbo)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
renderer.set_screen_target(Some(fbo));
|
renderer.set_screen_target(Some(fbo));
|
||||||
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
||||||
canvas.set_size(3000, 3000, 1.0);
|
canvas.set_size(3000, 3000, 1.0);
|
||||||
|
|
||||||
|
let img = canvas
|
||||||
|
.create_image_empty(
|
||||||
|
3000,
|
||||||
|
3000,
|
||||||
|
femtovg::PixelFormat::Rgba8,
|
||||||
|
femtovg::ImageFlags::empty(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
canvas.set_render_target(femtovg::RenderTarget::Image(img));
|
||||||
|
let mut path = femtovg::Path::new();
|
||||||
|
path.rect(0.0, 0.0, 300.0, 300.0);
|
||||||
|
canvas.fill_path(
|
||||||
|
&mut path,
|
||||||
|
&femtovg::Paint::color(femtovg::Color::rgb(255, 0, 0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ctx.get_tex_image(
|
||||||
|
glow::TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
glow::RGBA,
|
||||||
|
glow::UNSIGNED_BYTE,
|
||||||
|
glow::PixelPackData::Slice(&mut pixels),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsafe {
|
||||||
|
// let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER);
|
||||||
|
// println!("status: {}", status);
|
||||||
|
// gl::ReadPixels(
|
||||||
|
// 0,
|
||||||
|
// 0,
|
||||||
|
// w,
|
||||||
|
// h,
|
||||||
|
// gl::RGBA,
|
||||||
|
// gl::UNSIGNED_BYTE,
|
||||||
|
// pixels.as_mut_ptr() as *mut GLvoid,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if let Some(max) = pixels.iter().max() {
|
||||||
|
println!("The maximum value is {}", max);
|
||||||
|
} else {
|
||||||
|
println!("The vector is empty");
|
||||||
|
}
|
||||||
|
|
||||||
CanvasWrapper::new(canvas)
|
CanvasWrapper::new(canvas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
171
src/pipeline/utils.rs
Normal file
171
src/pipeline/utils.rs
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// examples/common/mod.rs
|
||||||
|
//
|
||||||
|
// OpenGL convenience wrappers used in the examples.
|
||||||
|
|
||||||
|
use gl;
|
||||||
|
use gl::types::{GLchar, GLenum, GLint, GLuint};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::os::raw::c_void;
|
||||||
|
use std::ptr;
|
||||||
|
use surfman::GLApi;
|
||||||
|
|
||||||
|
pub struct Program {
|
||||||
|
pub object: GLuint,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
vertex_shader: Shader,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fragment_shader: Shader,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Program {
|
||||||
|
pub fn new(vertex_shader: Shader, fragment_shader: Shader) -> Program {
|
||||||
|
unsafe {
|
||||||
|
let program = gl::CreateProgram();
|
||||||
|
ck();
|
||||||
|
gl::AttachShader(program, vertex_shader.object);
|
||||||
|
ck();
|
||||||
|
gl::AttachShader(program, fragment_shader.object);
|
||||||
|
ck();
|
||||||
|
gl::LinkProgram(program);
|
||||||
|
ck();
|
||||||
|
Program {
|
||||||
|
object: program,
|
||||||
|
vertex_shader,
|
||||||
|
fragment_shader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Shader {
|
||||||
|
object: GLuint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Shader {
|
||||||
|
pub fn new(
|
||||||
|
name: &str,
|
||||||
|
kind: ShaderKind,
|
||||||
|
gl_api: GLApi,
|
||||||
|
gl_texture_target: GLenum,
|
||||||
|
resource_loader: &dyn ResourceLoader,
|
||||||
|
) -> Shader {
|
||||||
|
let mut source = vec![];
|
||||||
|
match gl_api {
|
||||||
|
GLApi::GL => source.extend_from_slice(b"#version 330\n"),
|
||||||
|
GLApi::GLES => source.extend_from_slice(b"#version 300 es\n"),
|
||||||
|
}
|
||||||
|
match gl_texture_target {
|
||||||
|
gl::TEXTURE_2D => {}
|
||||||
|
gl::TEXTURE_RECTANGLE => source.extend_from_slice(b"#define SAMPLER_RECT\n"),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
resource_loader.slurp(&mut source, &format!("{}.{}.glsl", name, kind.extension()));
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let shader = gl::CreateShader(kind.to_gl());
|
||||||
|
ck();
|
||||||
|
gl::ShaderSource(
|
||||||
|
shader,
|
||||||
|
1,
|
||||||
|
&(source.as_ptr() as *const GLchar),
|
||||||
|
&(source.len() as GLint),
|
||||||
|
);
|
||||||
|
ck();
|
||||||
|
gl::CompileShader(shader);
|
||||||
|
ck();
|
||||||
|
|
||||||
|
let mut compile_status = 0;
|
||||||
|
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status);
|
||||||
|
ck();
|
||||||
|
if compile_status != gl::TRUE as GLint {
|
||||||
|
let mut info_log_length = 0;
|
||||||
|
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut info_log_length);
|
||||||
|
let mut info_log = vec![0; info_log_length as usize + 1];
|
||||||
|
gl::GetShaderInfoLog(
|
||||||
|
shader,
|
||||||
|
info_log_length,
|
||||||
|
ptr::null_mut(),
|
||||||
|
info_log.as_mut_ptr() as *mut _,
|
||||||
|
);
|
||||||
|
eprintln!(
|
||||||
|
"Failed to compile shader:\n{}",
|
||||||
|
String::from_utf8_lossy(&info_log)
|
||||||
|
);
|
||||||
|
panic!("Shader compilation failed!");
|
||||||
|
}
|
||||||
|
debug_assert_eq!(compile_status, gl::TRUE as GLint);
|
||||||
|
|
||||||
|
Shader { object: shader }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Buffer {
|
||||||
|
pub object: GLuint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Buffer {
|
||||||
|
pub fn from_data(data: &[u8]) -> Buffer {
|
||||||
|
unsafe {
|
||||||
|
let mut buffer = 0;
|
||||||
|
gl::GenBuffers(1, &mut buffer);
|
||||||
|
ck();
|
||||||
|
gl::BindBuffer(gl::ARRAY_BUFFER, buffer);
|
||||||
|
ck();
|
||||||
|
gl::BufferData(
|
||||||
|
gl::ARRAY_BUFFER,
|
||||||
|
data.len() as isize,
|
||||||
|
data.as_ptr() as *const c_void,
|
||||||
|
gl::STATIC_DRAW,
|
||||||
|
);
|
||||||
|
ck();
|
||||||
|
Buffer { object: buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
pub enum ShaderKind {
|
||||||
|
Vertex,
|
||||||
|
Fragment,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShaderKind {
|
||||||
|
fn extension(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
ShaderKind::Vertex => "vs",
|
||||||
|
ShaderKind::Fragment => "fs",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_gl(self) -> GLenum {
|
||||||
|
match self {
|
||||||
|
ShaderKind::Vertex => gl::VERTEX_SHADER,
|
||||||
|
ShaderKind::Fragment => gl::FRAGMENT_SHADER,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ResourceLoader {
|
||||||
|
fn slurp(&self, dest: &mut Vec<u8>, filename: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct FilesystemResourceLoader;
|
||||||
|
|
||||||
|
impl ResourceLoader for FilesystemResourceLoader {
|
||||||
|
fn slurp(&self, dest: &mut Vec<u8>, filename: &str) {
|
||||||
|
let path = format!("resources/examples/{}", filename);
|
||||||
|
File::open(&path)
|
||||||
|
.expect("Failed to open file!")
|
||||||
|
.read_to_end(dest)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ck() {
|
||||||
|
unsafe {
|
||||||
|
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user