use std::ops::{Deref, DerefMut};
use rin::graphics::mvp;
use rin::gl;
use rin::gl::types::*;
use rin::math::Mat4;
use crate::{
material::{
MaterialRef,
texture::{TextureRef, CubemapRef, SamplerRef, Sampler, Wrap, Filter}
},
};
use super::geometry::GpuGeometryRef;
use densevec::KeyedDenseVec;
use std::ops::{Index, IndexMut};
use std::collections::HashMap;
use std::rc::Rc;
use glin::OffscreenBuffer;
use std::cell::{UnsafeCell, Cell, RefCell};
use super::memory::VaoId;
pub struct CameraUBO{
pub ubo: gl::Buffer<mvp::CameraData>,
pub dirty: bool,
}
impl Deref for CameraUBO{
type Target = gl::Buffer<mvp::CameraData>;
fn deref(&self) -> &gl::Buffer<mvp::CameraData>{
&self.ubo
}
}
impl DerefMut for CameraUBO{
fn deref_mut(&mut self) -> &mut gl::Buffer<mvp::CameraData>{
&mut self.ubo
}
}
pub struct LightingUBO{
pub ubo: gl::Buffer<u8>,
pub dirty: bool,
}
impl Deref for LightingUBO{
type Target = gl::Buffer<u8>;
fn deref(&self) -> &gl::Buffer<u8>{
&self.ubo
}
}
impl DerefMut for LightingUBO{
fn deref_mut(&mut self) -> &mut gl::Buffer<u8>{
&mut self.ubo
}
}
#[derive(Debug)]
pub struct LightingUniforms{
pub uniforms: Vec<glin::program::Uniform>,
pub dirty: bool,
}
impl Deref for LightingUniforms{
type Target = Vec<glin::program::Uniform>;
fn deref(&self) -> &Vec<glin::program::Uniform>{
&self.uniforms
}
}
impl DerefMut for LightingUniforms{
fn deref_mut(&mut self) -> &mut Vec<glin::program::Uniform>{
&mut self.uniforms
}
}
pub struct LightData(pub super::shader_data::Data);
impl Deref for LightData{
type Target = super::shader_data::Data;
fn deref(&self) -> &super::shader_data::Data{
&self.0
}
}
impl DerefMut for LightData{
fn deref_mut(&mut self) -> &mut super::shader_data::Data{
&mut self.0
}
}
pub struct TexturesPool{
textures: KeyedDenseVec<TextureRef, glin::Texture>,
cubemaps: KeyedDenseVec<CubemapRef, glin::CubeMap>,
samplers: KeyedDenseVec<SamplerRef, glin::Sampler>,
name_texture_index: HashMap<String, TextureRef>,
name_cubemap_index: HashMap<String, CubemapRef>,
name_sampler_index: HashMap<String, SamplerRef>,
}
impl TexturesPool{
pub fn new() -> TexturesPool{
TexturesPool{
textures: KeyedDenseVec::new(),
cubemaps: KeyedDenseVec::new(),
samplers: KeyedDenseVec::new(),
name_texture_index: HashMap::new(),
name_cubemap_index: HashMap::new(),
name_sampler_index: HashMap::new(),
}
}
pub fn insert_texture(&mut self, texture: glin::Texture) -> TextureRef{
let mut format = glin::texture::DataFormat::default();
if format.fill_defaults_from(&texture).is_ok(){
trace!("Registering texture with {}Mb", format.bytes().unwrap() / 1024 / 1024 );
}
self.textures.insert_key_gen(texture)
}
pub fn insert_cubemap(&mut self, cubemap: glin::CubeMap) -> CubemapRef{
self.cubemaps.insert_key_gen(cubemap)
}
pub fn insert_sampler<R>(&mut self, sampler: Sampler, renderer: &glin::Context<R>) -> SamplerRef
where R: glin::RenderSurface
{
self.samplers.insert_key_gen(self.to_gl_sampler(sampler, renderer))
}
pub fn insert_named_texture(&mut self, name: &str, texture: glin::Texture) -> TextureRef{
let mut format = glin::texture::DataFormat::default();
if format.fill_defaults_from(&texture).is_ok(){
trace!("Registering texture {} with {}Mb", name, format.bytes().unwrap() / 1024 / 1024 );
}
if let Some(textureref) = self.name_texture_index.get(name){
self.textures.insert(*textureref, texture);
*textureref
}else{
let textureref = self.textures.insert_key_gen(texture);
self.name_texture_index.insert(name.to_owned(), textureref);
textureref
}
}
pub fn insert_named_cubemap(&mut self, name: &str, cubemap: glin::CubeMap) -> CubemapRef{
if let Some(cubemapref) = self.name_cubemap_index.get(name){
self.cubemaps.insert(*cubemapref, cubemap);
*cubemapref
}else{
let cubemapref = self.cubemaps.insert_key_gen(cubemap);
self.name_cubemap_index.insert(name.to_owned(), cubemapref);
cubemapref
}
}
pub fn insert_named_sampler<R: glin::RenderSurface>(&mut self,
name: &str,
sampler: Sampler,
renderer: &glin::Context<R>) -> SamplerRef
{
let sampler = self.to_gl_sampler(sampler, renderer);
if let Some(samplerref) = self.name_sampler_index.get(name){
self.samplers.insert(*samplerref, sampler);
*samplerref
}else{
let samplerref = self.samplers.insert_key_gen(sampler);
self.name_sampler_index.insert(name.to_owned(), samplerref);
samplerref
}
}
pub fn find_named_texture(&self, name: &str) -> Option<TextureRef>{
self.name_texture_index.get(name).cloned()
}
pub fn insert_texture_from_data_format<T,R>(&mut self,
format: glin::texture::LoadDataFormat,
data: &[T],
renderer: &glin::Context<R>) -> Result<TextureRef, glin::Error>
where T: 'static, R: glin::RenderSurface
{
renderer.new_texture().from_data_format(format, data)
.map(|texture| self.insert_texture(texture))
}
pub fn insert_image<I,R>(&mut self, img: &I, renderer: &glin::Context<R>) -> glin::Result<TextureRef>
where I: glin::Image, R: glin::RenderSurface
{
renderer
.new_texture()
.from_image(img, gl::TEXTURE_2D)
.map(|texture| self.insert_texture(texture))
}
#[cfg(feature="squish")]
fn compress<I,R>(img: &I, renderer: &glin::Context<R>) -> glin::Result<glin::Texture>
where I: glin::Image<DataType=u8>, R: glin::RenderSurface
{
let bytes = squish::Format::Bc1.compressed_size(img.width(0), img.height(0));
let mut output = vec![0; bytes];
squish::Format::Bc1.compress(
img.data(),
img.width(0),
img.height(0),
squish::Params::default(),
&mut output);
let data_format = glin::texture::CompressedDataFormat{
width: img.width(0) as u32,
height: img.height(0) as u32,
level: 0,
format: gl::COMPRESSED_RGBA_S3TC_DXT1_EXT,
.. Default::default()
};
let format = glin::texture::Format{
target: gl::TEXTURE_2D,
internal_format: gl::COMPRESSED_RGBA_S3TC_DXT1_EXT,
width: img.width(0) as u32,
height: img.height(0) as u32,
levels: 1,
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
samples: 0,
};
renderer
.new_texture()
.from_format(format)
.and_then(|mut texture| {
texture.load_compressed_data(&output, data_format)?;
Ok(texture)
})
}
#[cfg(feature="squish")]
pub fn insert_compress_image<I,R>(&mut self, img: &I, renderer: &glin::Context<R>) -> glin::Result<TextureRef>
where I: glin::Image<DataType=u8>, R: glin::RenderSurface
{
Self::compress(img, renderer).map(|texture| self.insert_texture(texture))
}
#[cfg(feature="squish")]
pub fn insert_compress_named_image<I,R>(&mut self,
name: &str,
img: &I,
renderer: &glin::Context<R>) -> glin::Result<TextureRef>
where I: glin::Image<DataType=u8>, R: glin::RenderSurface
{
Self::compress(img, renderer).map(|texture| self.insert_named_texture(name, texture))
}
pub fn insert_named_texture_from_data_format<R,T>(&mut self,
name: &str,
format: glin::texture::LoadDataFormat,
data: &[T],
renderer: &glin::Context<R>) -> glin::Result<TextureRef>
where T: 'static, R: glin::RenderSurface
{
renderer.new_texture().from_data_format(format, data)
.map(|texture| self.insert_named_texture(name, texture))
}
pub fn insert_named_image<I,R>(&mut self,
name: &str,
img: &I,
renderer: &glin::Context<R>) -> glin::Result<TextureRef>
where I: glin::Image, R: glin::RenderSurface
{
renderer
.new_texture()
.from_image(img, gl::TEXTURE_2D)
.map(|texture| self.insert_named_texture(name, texture))
}
pub fn to_gl_sampler<R>(&self, sampler: Sampler, renderer: &glin::Context<R>) -> glin::Sampler
where R: glin::RenderSurface
{
let mut glsampler = renderer.new_sampler();
let wrap = match sampler.wrap {
Wrap::Repeat => gl::REPEAT,
Wrap::Extend => gl::MIRRORED_REPEAT,
Wrap::Clip => gl::CLAMP_TO_EDGE,
};
glsampler.set_wrap_r(wrap);
glsampler.set_wrap_s(wrap);
glsampler.set_wrap_t(wrap);
let minfilter = match sampler.minfilter{
Filter::Nearest => gl::NEAREST,
Filter::Linear => gl::LINEAR,
Filter::NearestMipNearest => gl::NEAREST_MIPMAP_NEAREST,
Filter::NearestMipLinear => gl::NEAREST_MIPMAP_LINEAR,
Filter::LinearMipNearest => gl::LINEAR_MIPMAP_NEAREST,
Filter::LinearMipLinear => gl::LINEAR_MIPMAP_LINEAR,
};
let magfilter = match sampler.magfilter{
Filter::Nearest => gl::NEAREST,
Filter::Linear => gl::LINEAR,
Filter::NearestMipNearest => gl::NEAREST_MIPMAP_NEAREST,
Filter::NearestMipLinear => gl::NEAREST_MIPMAP_LINEAR,
Filter::LinearMipNearest => gl::LINEAR_MIPMAP_NEAREST,
Filter::LinearMipLinear => gl::LINEAR_MIPMAP_LINEAR,
};
glsampler.set_min_mag_filters(minfilter, magfilter);
glsampler
}
pub fn texture(&self, textureref: TextureRef) -> Option<&glin::Texture>{
self.textures.get(textureref)
}
pub fn texture_mut(&mut self, textureref: TextureRef) -> Option<&mut glin::Texture>{
self.textures.get_mut(textureref)
}
}
impl Index<TextureRef> for TexturesPool{
type Output = glin::Texture;
fn index(&self, textureref: TextureRef) -> &glin::Texture{
&self.textures[textureref]
}
}
impl IndexMut<TextureRef> for TexturesPool{
fn index_mut(&mut self, textureref: TextureRef) -> &mut glin::Texture{
&mut self.textures[textureref]
}
}
impl Index<CubemapRef> for TexturesPool{
type Output = glin::CubeMap;
fn index(&self, cubemapref: CubemapRef) -> &glin::CubeMap{
&self.cubemaps[cubemapref]
}
}
impl IndexMut<CubemapRef> for TexturesPool{
fn index_mut(&mut self, cubemapref: CubemapRef) -> &mut glin::CubeMap{
&mut self.cubemaps[cubemapref]
}
}
impl Index<SamplerRef> for TexturesPool{
type Output = glin::Sampler;
fn index(&self, samplerref: SamplerRef) -> &glin::Sampler{
&self.samplers[samplerref]
}
}
impl IndexMut<SamplerRef> for TexturesPool{
fn index_mut(&mut self, samplerref: SamplerRef) -> &mut glin::Sampler{
&mut self.samplers[samplerref]
}
}
pub struct ModelMatricesData{
pub data: Vec<(Mat4, Mat4)>,
pub has_changed: bool,
}
impl Deref for ModelMatricesData{
type Target = Vec<(Mat4, Mat4)>;
fn deref(&self) -> &Vec<(Mat4, Mat4)>{
&self.data
}
}
impl DerefMut for ModelMatricesData{
fn deref_mut(&mut self) -> &mut Vec<(Mat4, Mat4)>{
&mut self.data
}
}
pub struct AllModelMatricesData{
pub data: Vec<Mat4>,
pub has_changed: bool,
}
impl Deref for AllModelMatricesData{
type Target = Vec<Mat4>;
fn deref(&self) -> &Vec<Mat4>{
&self.data
}
}
impl DerefMut for AllModelMatricesData{
fn deref_mut(&mut self) -> &mut Vec<Mat4>{
&mut self.data
}
}
pub struct StaticModelMatricesData{
pub data: Vec<Mat4>,
pub has_changed: bool,
}
impl Deref for StaticModelMatricesData{
type Target = Vec<Mat4>;
fn deref(&self) -> &Vec<Mat4>{
&self.data
}
}
impl DerefMut for StaticModelMatricesData{
fn deref_mut(&mut self) -> &mut Vec<Mat4>{
&mut self.data
}
}
pub struct DynamicModelMatricesData{
pub data: Vec<Mat4>,
pub has_changed: bool,
}
impl Deref for DynamicModelMatricesData{
type Target = Vec<Mat4>;
fn deref(&self) -> &Vec<Mat4>{
&self.data
}
}
impl DerefMut for DynamicModelMatricesData{
fn deref_mut(&mut self) -> &mut Vec<Mat4>{
&mut self.data
}
}
pub struct ModelMatricesBuffer(pub gl::SharedBuffer<(Mat4, Mat4)>);
pub struct AllModelMatricesBuffer(pub gl::SharedBuffer<Mat4>);
pub struct StaticModelMatricesBuffer(pub gl::SharedBuffer<Mat4>);
pub struct DynamicModelMatricesBuffer(pub gl::SharedBuffer<Mat4>);
impl Deref for ModelMatricesBuffer{
type Target = gl::SharedBuffer<(Mat4, Mat4)>;
fn deref(&self) -> &gl::SharedBuffer<(Mat4, Mat4)>{
&self.0
}
}
impl DerefMut for ModelMatricesBuffer{
fn deref_mut(&mut self) -> &mut gl::SharedBuffer<(Mat4, Mat4)>{
&mut self.0
}
}
impl Deref for StaticModelMatricesBuffer{
type Target = gl::SharedBuffer<Mat4>;
fn deref(&self) -> &gl::SharedBuffer<Mat4>{
&self.0
}
}
impl DerefMut for StaticModelMatricesBuffer{
fn deref_mut(&mut self) -> &mut gl::SharedBuffer<Mat4>{
&mut self.0
}
}
impl Deref for DynamicModelMatricesBuffer{
type Target = gl::SharedBuffer<Mat4>;
fn deref(&self) -> &gl::SharedBuffer<Mat4>{
&self.0
}
}
impl DerefMut for DynamicModelMatricesBuffer{
fn deref_mut(&mut self) -> &mut gl::SharedBuffer<Mat4>{
&mut self.0
}
}
impl Deref for AllModelMatricesBuffer{
type Target = gl::SharedBuffer<Mat4>;
fn deref(&self) -> &gl::SharedBuffer<Mat4>{
&self.0
}
}
impl DerefMut for AllModelMatricesBuffer{
fn deref_mut(&mut self) -> &mut gl::SharedBuffer<Mat4>{
&mut self.0
}
}
#[derive(Clone)]
pub struct GeometryIndex{
pub entities: Vec<rinecs::Entity>,
pub name: String,
pub geometryref: GpuGeometryRef,
pub materialref: MaterialRef,
pub submesh: usize,
pub vao_id: VaoId,
pub additional_uniforms: Vec<glin::program::Uniform>,
pub renderplane: Option<rinecs::Entity>,
}
impl GeometryIndex{
pub fn num_instances(&self) -> usize{
self.entities.len()
}
}
#[derive(Clone, Debug)]
pub struct ShadowGeometryIndex{
pub entities: Vec<rinecs::Entity>,
pub geometryref: GpuGeometryRef,
pub vao_id: VaoId,
pub primitive_type: GLenum,
}
impl ShadowGeometryIndex{
pub fn num_instances(&self) -> usize{
self.entities.len()
}
}
#[derive(Clone)]
pub struct OpaqueSortedGeometry{
index: Vec<GeometryIndex>,
has_changed: bool,
}
impl OpaqueSortedGeometry{
pub fn new() -> OpaqueSortedGeometry{
OpaqueSortedGeometry{
index: vec![],
has_changed: false,
}
}
pub fn geometryrefs(&self) -> impl Iterator<Item = GpuGeometryRef> + '_ {
self.index.iter().map(|geom| geom.geometryref)
}
pub fn reset_has_changed(&mut self) {
self.has_changed = false
}
pub fn has_changed(&self) -> bool {
self.has_changed
}
}
impl Deref for OpaqueSortedGeometry {
type Target = Vec<GeometryIndex>;
fn deref(&self) -> &Vec<GeometryIndex>{
&self.index
}
}
impl DerefMut for OpaqueSortedGeometry {
fn deref_mut(&mut self) -> &mut Vec<GeometryIndex>{
self.has_changed = true;
&mut self.index
}
}
#[derive(Clone)]
pub struct TranslucentSortedGeometry{
index: Vec<GeometryIndex>,
has_changed: bool,
}
impl TranslucentSortedGeometry{
pub fn new() -> TranslucentSortedGeometry{
TranslucentSortedGeometry{
index: vec![],
has_changed: false,
}
}
pub fn geometryrefs(&self) -> impl Iterator<Item = GpuGeometryRef> + '_ {
self.index.iter().map(|geom| geom.geometryref)
}
pub fn reset_has_changed(&mut self) {
self.has_changed = false
}
pub fn has_changed(&self) -> bool {
self.has_changed
}
}
impl Deref for TranslucentSortedGeometry {
type Target = Vec<GeometryIndex>;
fn deref(&self) -> &Vec<GeometryIndex>{
&self.index
}
}
impl DerefMut for TranslucentSortedGeometry {
fn deref_mut(&mut self) -> &mut Vec<GeometryIndex>{
self.has_changed = true;
&mut self.index
}
}
#[derive(Clone, Debug)]
pub struct DynamicShadowsSortedGeometry{
index: Vec<ShadowGeometryIndex>,
has_changed: bool,
}
impl DynamicShadowsSortedGeometry{
pub fn new() -> DynamicShadowsSortedGeometry{
DynamicShadowsSortedGeometry{
index: vec![],
has_changed: false,
}
}
pub fn geometryrefs(&self) -> impl Iterator<Item = GpuGeometryRef> + '_ {
self.index.iter().map(|geom| geom.geometryref)
}
pub fn has_changed(&self) -> bool {
self.has_changed
}
pub fn reset_has_changed(&mut self) {
self.has_changed = false
}
}
impl Deref for DynamicShadowsSortedGeometry {
type Target = Vec<ShadowGeometryIndex>;
fn deref(&self) -> &Vec<ShadowGeometryIndex>{
&self.index
}
}
impl DerefMut for DynamicShadowsSortedGeometry {
fn deref_mut(&mut self) -> &mut Vec<ShadowGeometryIndex>{
self.has_changed = true;
&mut self.index
}
}
#[derive(Clone, Debug)]
pub struct StaticShadowsSortedGeometry{
index: Vec<ShadowGeometryIndex>,
has_changed: bool,
}
impl StaticShadowsSortedGeometry{
pub fn new() -> StaticShadowsSortedGeometry{
StaticShadowsSortedGeometry{
index: vec![],
has_changed: false,
}
}
pub fn geometryrefs(&self) -> impl Iterator<Item = GpuGeometryRef> + '_ {
self.index.iter().map(|geom| geom.geometryref)
}
pub fn has_changed(&self) -> bool {
self.has_changed
}
pub fn reset_has_changed(&mut self) {
self.has_changed = false
}
}
impl Deref for StaticShadowsSortedGeometry {
type Target = Vec<ShadowGeometryIndex>;
fn deref(&self) -> &Vec<ShadowGeometryIndex>{
&self.index
}
}
impl DerefMut for StaticShadowsSortedGeometry {
fn deref_mut(&mut self) -> &mut Vec<ShadowGeometryIndex>{
self.has_changed = true;
&mut self.index
}
}
#[derive(Clone, Debug)]
pub struct AllShadowsSortedGeometry{
index: Vec<ShadowGeometryIndex>,
has_changed: bool,
}
impl AllShadowsSortedGeometry{
pub fn new() -> AllShadowsSortedGeometry{
AllShadowsSortedGeometry{
index: vec![],
has_changed: false,
}
}
pub fn geometryrefs(&self) -> impl Iterator<Item = GpuGeometryRef> + '_ {
self.index.iter().map(|geom| geom.geometryref)
}
pub fn has_changed(&self) -> bool {
self.has_changed
}
pub fn reset_has_changed(&mut self) {
self.has_changed = false
}
}
impl Deref for AllShadowsSortedGeometry {
type Target = Vec<ShadowGeometryIndex>;
fn deref(&self) -> &Vec<ShadowGeometryIndex>{
&self.index
}
}
impl DerefMut for AllShadowsSortedGeometry {
fn deref_mut(&mut self) -> &mut Vec<ShadowGeometryIndex>{
self.has_changed = true;
&mut self.index
}
}
enum BufferType{
Simple(gl::SimpleFbo),
Rc{
render_buffer: glin::Fbo<Rc<glin::fbo::ColorAttachment>, Rc<glin::fbo::DepthAttachment>>,
blit_buffer: Option<UnsafeCell<glin::Fbo>>,
changed: Cell<bool>,
}
}
pub struct ScreenRenderBuffer{
render_buffer: BufferType,
depth_prepass: Option<glin::Fbo<glin::fbo::ColorAttachment, Rc<glin::fbo::DepthAttachment>>>,
}
impl ScreenRenderBuffer{
pub fn new(gl: &gl::Renderer, w: u32, h: u32, format: glin::fbo::ColorFormat) -> glin::Result<ScreenRenderBuffer>{
let render_surface = gl.new_simple_fbo(w, h, format)?;
Ok(ScreenRenderBuffer{
render_buffer: BufferType::Simple(render_surface),
depth_prepass: None,
})
}
pub fn new_multisampled(gl: &gl::Renderer, w: u32, h: u32, samples: u32, format: glin::fbo::ColorFormat) -> glin::Result<ScreenRenderBuffer>{
let render_surface = gl.new_simple_fbo_multisampled(w, h, samples, format)?;
Ok(ScreenRenderBuffer{
render_buffer: BufferType::Simple(render_surface),
depth_prepass: None,
})
}
pub fn new_with_depth_prepass(gl: &gl::Renderer, w: u32, h: u32, format: glin::fbo::ColorFormat) -> glin::Result<ScreenRenderBuffer>{
let color = gl.new_fbo_color_attachment()
.texture(w, h, format)?;
let depth = gl.new_fbo_depth_attachment()
.render_buffer(w, h, glin::fbo::DepthFormat::_24)?;
let color = Rc::new(color);
let depth = Rc::new(depth);
let render_buffer = gl.new_fbo().from_color_depth(color, depth.clone())?;
let depth_prepass = gl.new_fbo().from_depth(depth)?;
Ok(ScreenRenderBuffer{
render_buffer: BufferType::Rc{
render_buffer,
blit_buffer: None,
changed: Cell::new(false),
},
depth_prepass: Some(depth_prepass),
})
}
pub fn new_multisampled_with_depth_prepass(gl: &gl::Renderer, w: u32, h: u32, samples: u32, format: glin::fbo::ColorFormat) -> glin::Result<ScreenRenderBuffer>{
let color = gl.new_fbo_color_attachment()
.texture_multisampled(w, h, samples, format)?;
let depth = gl.new_fbo_depth_attachment()
.render_buffer_multisampled(w, h, samples, glin::fbo::DepthFormat::_24)?;
let color = Rc::new(color);
let depth = Rc::new(depth);
let render_buffer = gl.new_fbo().from_color_depth(color, depth.clone())?;
let depth_prepass = gl.new_fbo().from_depth(depth)?;
let blit_color = gl.new_fbo_color_attachment()
.texture(w, h, format)?;
let blit_buffer = gl.new_fbo().from_color_no_depth(blit_color)?;
Ok(ScreenRenderBuffer{
render_buffer: BufferType::Rc{
render_buffer,
blit_buffer: Some(UnsafeCell::new(blit_buffer)),
changed: Cell::new(false),
},
depth_prepass: Some(depth_prepass),
})
}
pub fn color_attachment(&self) -> &glin::fbo::ColorAttachment{
match &self.render_buffer{
BufferType::Simple(fbo) => fbo.color_attachment(0).unwrap(),
BufferType::Rc{render_buffer, blit_buffer, changed} => {
if let Some(blit_buffer) = blit_buffer {
let blit_buffer = unsafe{ &mut *blit_buffer.get() };
if changed.get() {
render_buffer.blit(blit_buffer, &render_buffer.viewport(), &blit_buffer.viewport())
}
blit_buffer.color_attachment(0).unwrap()
}else{
render_buffer.color_attachment(0).unwrap()
}
}
}
}
pub fn depth_prepass(&self) -> Option<&glin::Fbo<glin::fbo::ColorAttachment, Rc<glin::fbo::DepthAttachment>>>{
self.depth_prepass.as_ref()
}
}
unsafe impl glin::UntypedOffscreenBuffer for ScreenRenderBuffer{
fn id(&self) -> u32{
match &self.render_buffer{
BufferType::Simple(buffer) => buffer.id(),
BufferType::Rc{render_buffer, changed, ..} => {
changed.set(true);
render_buffer.id()
}
}
}
fn viewport(&self) -> glin::Rect{
match &self.render_buffer{
BufferType::Simple(buffer) => buffer.viewport(),
BufferType::Rc{render_buffer, ..} => render_buffer.viewport(),
}
}
}
pub(crate) struct DepthPrepass;
pub struct GeometryWithModelsIndex(pub Vec<(Rc<RefCell<glin::Vao>>, GLenum)>);
impl Deref for GeometryWithModelsIndex {
type Target = Vec<(Rc<RefCell<glin::Vao>>, GLenum)>;
fn deref(&self) -> &Vec<(Rc<RefCell<glin::Vao>>, GLenum)>{
&self.0
}
}
impl DerefMut for GeometryWithModelsIndex {
fn deref_mut(&mut self) -> &mut Vec<(Rc<RefCell<glin::Vao>>, GLenum)>{
&mut self.0
}
}