ttt
This commit is contained in:
parent
04776b4f45
commit
acbc81b733
62
Cargo.lock
generated
62
Cargo.lock
generated
@ -422,6 +422,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"cairo-rs",
|
||||
"crossbeam",
|
||||
"epoxy",
|
||||
"euclid",
|
||||
"femtovg",
|
||||
@ -429,6 +430,7 @@ dependencies = [
|
||||
"geo-macros",
|
||||
"geo-types",
|
||||
"geojson 0.24.1",
|
||||
"gl",
|
||||
"glib",
|
||||
"glib-build-tools",
|
||||
"glib-macros",
|
||||
@ -631,47 +633,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.8"
|
||||
name = "crossbeam"
|
||||
version = "0.8.4"
|
||||
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 = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.15"
|
||||
version = "0.9.18"
|
||||
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 = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset 0.9.0",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.16"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
@ -1358,6 +1373,15 @@ dependencies = [
|
||||
"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]]
|
||||
name = "gl_generator"
|
||||
version = "0.9.0"
|
||||
@ -3846,7 +3870,7 @@ checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"xml-rs 0.7.0",
|
||||
"xml-rs 0.8.19",
|
||||
]
|
||||
|
||||
[[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"]}
|
||||
surfman = "0.8.1"
|
||||
euclid = "0.22.9"
|
||||
gl = "0.14.0"
|
||||
crossbeam = "0.8.4"
|
||||
# plotters-cairo = "0.5.0"
|
||||
|
||||
|
||||
|
||||
50
back.txt
50
back.txt
@ -343,3 +343,53 @@ pub enum CoordType {
|
||||
// .blue(250 as f32 / 255.0)
|
||||
// .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::render::{Target, CMS};
|
||||
// use crate::OFFSCREEN;
|
||||
use crate::{
|
||||
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
|
||||
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) {
|
||||
match message {
|
||||
MonitorInputMsg::AddLayer(layer) => {
|
||||
// let mut canvas = OFFSCREEN.lock().unwrap();
|
||||
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 p = layer.get_prepare();
|
||||
let mut _p = p.lock().unwrap();
|
||||
@ -94,9 +98,9 @@ impl Component for MonitorModel {
|
||||
|
||||
let map: Mapper = Mercator::default().into();
|
||||
let cms = CMS::new(map, (3000.0, 3000.0));
|
||||
let canvas = new_canvas.create_canvas();
|
||||
let canvas = Arc::new(Mutex::new(canvas));
|
||||
let c = f(imp, canvas, cms).await;
|
||||
|
||||
Some(c)
|
||||
// None
|
||||
} else {
|
||||
|
||||
@ -1,12 +1,8 @@
|
||||
mod utils;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{gio, glib, Application, ApplicationWindow};
|
||||
use pipeline::offscreen_renderer::OffscreenRenderer;
|
||||
use relm4::menu;
|
||||
use relm4::RelmApp;
|
||||
use std::ptr;
|
||||
use tokio::runtime::Runtime;
|
||||
use utils::creator;
|
||||
mod chart;
|
||||
mod components;
|
||||
mod coords;
|
||||
@ -19,13 +15,16 @@ mod render;
|
||||
mod window;
|
||||
use components::app::{AppMode, AppModel};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::Mutex;
|
||||
|
||||
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||
|
||||
static RUNTIME: Lazy<Runtime> =
|
||||
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() {
|
||||
// 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 num_traits::{Num, AsPrimitive, FromPrimitive};
|
||||
pub mod offscreen_renderer;
|
||||
mod utils;
|
||||
|
||||
use crate::{
|
||||
coords::Mapper,
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
use super::utils::*;
|
||||
use euclid::Size2D;
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
use lazy_static::__Deref;
|
||||
use std::borrow::BorrowMut;
|
||||
use gl;
|
||||
use gl::types::{GLchar, GLenum, GLint, GLuint, GLvoid};
|
||||
use glow::HasContext;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Mutex, RwLock};
|
||||
use std::{cell::RefCell, sync::Arc};
|
||||
use surfman::platform::system::connection;
|
||||
use surfman::{
|
||||
device, Adapter, Connection, Context, ContextAttributeFlags, Device, Error, GLApi,
|
||||
NativeConnection, NativeDevice,
|
||||
@ -16,66 +17,129 @@ pub struct OffscreenRenderer {
|
||||
context: Arc<RwLock<Context>>,
|
||||
device: Device,
|
||||
fbo: NonZeroU32,
|
||||
// canvas: Arc<Mutex<CanvasWrapper>>,
|
||||
glow_ctx: Option<glow::Context>,
|
||||
size: (i32, i32), // canvas: Arc<Mutex<CanvasWrapper>>,
|
||||
}
|
||||
|
||||
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 adapter = connection.create_hardware_adapter()?;
|
||||
let adapter = connection.create_adapter()?;
|
||||
let mut device = connection.create_device(&adapter)?;
|
||||
let api = connection.gl_api();
|
||||
|
||||
let descriptor = device.create_context_descriptor(&surfman::ContextAttributes {
|
||||
version: surfman::GLVersion::new(3, 3),
|
||||
flags: ContextAttributeFlags::DEPTH.union(ContextAttributeFlags::STENCIL),
|
||||
version: surfman::GLVersion::new(4, 1),
|
||||
flags: ContextAttributeFlags::empty(),
|
||||
})?;
|
||||
|
||||
let mut context = device.create_context(&descriptor, None)?;
|
||||
|
||||
let surface = device.create_surface(
|
||||
&context,
|
||||
surfman::SurfaceAccess::GPUCPU,
|
||||
surfman::SurfaceAccess::GPUOnly,
|
||||
surfman::SurfaceType::Generic {
|
||||
size: euclid::Size2D::new(3000, 3000),
|
||||
size: euclid::Size2D::new(width, height),
|
||||
},
|
||||
)?;
|
||||
|
||||
let surface_info = device.surface_info(&surface);
|
||||
device
|
||||
.bind_surface_to_context(&mut context, surface)
|
||||
.expect("Failed to bind surface to context");
|
||||
|
||||
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 {
|
||||
context: Arc::new(RwLock::new(context)),
|
||||
device,
|
||||
fbo: NonZeroU32::new(surface_info.framebuffer_object).unwrap(),
|
||||
glow_ctx: None,
|
||||
size: (width, height),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_canvas(&self) -> CanvasWrapper {
|
||||
use glow::HasContext;
|
||||
static LOAD_FN: fn(&str) -> *const std::ffi::c_void =
|
||||
|s| epoxy::get_proc_addr(s) as *const _;
|
||||
pub fn create_canvas(&mut self) -> CanvasWrapper {
|
||||
let (w, h) = self.size;
|
||||
let mut pixels: Vec<u8> = vec![0; w as usize * h as usize * 4];
|
||||
|
||||
let (mut renderer, fbo) = unsafe {
|
||||
let renderer = OpenGl::new_from_function(LOAD_FN).expect("Cannot create renderer");
|
||||
let ctx = glow::Context::from_loader_function(LOAD_FN);
|
||||
let (mut renderer, fbo, ctx) = unsafe {
|
||||
let renderer = OpenGl::new_from_function(|s| {
|
||||
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 cbo = ctx.create_buffer().expect("can't create color buffer");
|
||||
let ctx = glow::Context::from_loader_function(|s| {
|
||||
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)
|
||||
// .expect("No GTK provided framebuffer binding");
|
||||
let fbo = glow::NativeFramebuffer(self.fbo);
|
||||
ctx.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
// let fbo = glow::NativeFramebuffer(id);
|
||||
(renderer, fbo)
|
||||
(renderer, fbo, ctx)
|
||||
};
|
||||
|
||||
renderer.set_screen_target(Some(fbo));
|
||||
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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