I'm running into a conceptual block with Rust that I just can't see my way around. But since folks write significant software with Rust everyday, I feel like I must just be misunderstanding something fundamental.
I'm using a 3rd-party crate (in this case, https://crates.io/crates/glium glium), which defines some resources (framebuffers) which depend on other resource types (i.e. textures) by reference. In a trivial program, this is fine - I create all my textures in main()
, and then declare my framebuffers inside {}
(to introduce a new lexical scope and keep the borrow-checked happy).
The problem comes when I want to make a non-trivial program, and try to store those textures and framebuffers inside a struct. Since the framebuffer stores a reference to the textures, I can't store them in the same struct (Rust doesn't allow self-referential structures). I can store them in different structs, but I can't nest those two structs in any other type (for the same reason), so I'm left having to allocate all my types manually in the main function. This is a problem if need to allocate any structs dynamically.
Here's the (obviously non-working) example I'm trying to work out a way forward with:
extern crate glium;
use glium::backend::Facade;
use glium::texture::{MipmapsOption, Texture2d, DepthTexture2d, UncompressedFloatFormat, DepthFormat};
use glium::framebuffer::MultiOutputFrameBuffer;
pub struct Renderable<'a> {
position: Texture2d,
normal: Texture2d,
depth: DepthTexture2d,
framebuffer: MultiOutputFrameBuffer<'a>,
}
impl<'a> Renderable<'a> {
pub fn new(display : &Facade, width : u32, height : u32) -> Self {
let position = Texture2d::empty_with_format(display, UncompressedFloatFormat::F32F32F32F32, MipmapsOption::NoMipmap, width, height).unwrap();
let normal = Texture2d::empty_with_format(display, UncompressedFloatFormat::F32F32F32F32, MipmapsOption::NoMipmap, width, height).unwrap();
let depth = DepthTexture2d::empty_with_format(display, DepthFormat::F32, MipmapsOption::NoMipmap, width, height).unwrap();
let outputs = &[("color", &position), ("normal", &normal)];
Self{
position,
normal,
depth,
framebuffer: MultiOutputFrameBuffer::with_depth_buffer(display, outputs.iter().cloned(), &depth).unwrap(),
}
}
}
Any ideas as to how to encapsulate types that contain references? Any reading material you can point me at?
Much obliged,
- Tristam