Simple bridge library to render into a gtk-rs GLArea
using the Gfx (pre-ll) library.
Uses [epoxy] for Gl loading, and as such it doesn't require a Gl window/loading management such as glutin
or winit
Here's a short broken-down list to get the integration up and running:
[dependencies]
gfx_gtk = "0.3"
```rust extern crate gfx_gtk;
use gfxgtk::formats; use gfxgtk::GlRenderContext; ```
rust
const MSAA: gfx::texture::AaMode = formats::MSAA_4X;
type RenderColorFormat = formats::DefaultRenderColorFormat;
type RenderDepthFormat = formats::DefaultRenderDepthFormat;
You need to implement [GlRenderCallback] and [GlPostprocessCallback] traits (the latter can be made to use the default implementation)
```rust struct SimpleRenderCallback { ... }
impl gfxgtk::GlRenderCallback
impl gfx_gtk::GlPostprocessCallback
```rust gfx_gtk::load();
```
The rendering needs to be driven by a GlArea
widget because of its ability to create a Gl context.
The realize
, resize
and render
signals need to be connected. The [GlRenderContext]
and [GlRenderCallback] must be created in the closure that gets attached to GlArea::connect_realize()
after
the make_current()
call (otherwise it won't be possible to "bind" to the current GlArea
Gl context
```rust
let gfx_context: Rc
let render_callback: Rc
let glarea = gtk::GLArea::new();
glarea.connectrealize({ let gfxcontext = gfxcontext.clone(); let rendercallback = render_callback.clone();
move |widget| {
if widget.get_realized() {
widget.make_current();
}
let allocation = widget.get_allocation();
let mut new_context =
gfx_gtk::GlRenderContext::new(
MSAA,
allocation.width,
allocation.height,
None).ok();
if let Some(ref mut new_context) = new_context {
let ref vp = new_context.viewport();
let ref mut ctx = new_context.gfx_context_mut();
*render_callback.borrow_mut() = SimpleRenderCallback::new(ctx, vp).ok();
}
*gfx_context.borrow_mut() = new_context;
}
});
glarea.connectresize({ let gfxcontext = gfxcontext.clone(); let rendercallback = render_callback.clone();
move |_widget, width, height| {
if let Some(ref mut context) = *gfx_context.borrow_mut() {
if let Some(ref mut render_callback) = *render_callback.borrow_mut() {
context.resize(width, height, Some(render_callback)).ok();
}
}
}
});
glarea.connectrender({ let gfxcontext = gfxcontext.clone(); let rendercallback = render_callback.clone();
move |_widget, _gl_context| {
if let Some(ref mut context) = *gfx_context.borrow_mut() {
if let Some(ref mut render_callback) = *render_callback.borrow_mut() {
context.with_gfx(render_callback);
}
}
Inhibit(false)
}
});
``
After this, every time Gtk refreshes the
GlAreacontent, it will invoke the
render_callback` to paint itself.
See examples/setup.rs for a simple interactive
rendering example. On running it with cargo run --example setup
, it should look like this:
© 2018 Nico Orru https://www.itadinanta.net