use gl::{self, types::*};
use texture::{self, Texture};
use cubemap::{self, CubeMap};
use state::StateRef;
use std::borrow::Borrow;
use std::hash::Hash;
use std::rc::Rc;
#[cfg(feature = "gles")]
use std::ptr;
use super::renderbuffer::{RenderBuffer, RenderBufferBuilder};
use super::framebuffer::FrameBuffer;
#[derive(Hash)]
pub enum ColorAttachmentId{
TextureLevel(u32, i32),
TextureLayerLevel(u32, i32, i32),
RenderBuffer(u32),
#[cfg(not(feature="webgl"))]
CubeMapLevel(u32, i32),
CubeMapFaceLevel(u32, u32, i32),
}
#[derive(Hash)]
pub enum DepthAttachmentId{
TextureLevel(u32, i32),
TextureLayerLevel(u32, i32, i32),
RenderBuffer(u32),
#[cfg(not(feature="webgl"))]
CubeMapLevel(u32, i32),
CubeMapFaceLevel(u32, u32, i32),
}
pub trait ColorAttach{
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint);
fn width(&self) -> u32;
fn height(&self) -> u32;
fn samples(&self) -> u32;
fn attachment_id(&self) -> ColorAttachmentId;
}
#[derive(Debug)]
pub enum ColorAttachment{
TextureLevel(Texture, i32),
RenderBuffer(RenderBuffer),
#[cfg(not(feature="webgl"))]
CubeMapLevel(CubeMap, i32),
CubeMapFaceLevel(CubeMap, u32, i32),
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
#[derive(Copy,Clone,Debug)]
#[repr(u32)]
pub enum ColorFormat{
R8 = gl::R8,
R16 = gl::R16,
R16F = gl::R16F,
R32F = gl::R32F,
RG8 = gl::RG8,
RG16 = gl::RG16,
RG16F = gl::RG16F,
RG32F = gl::RG32F,
RGB8 = gl::RGB8,
RGB16 = gl::RGB16,
RGB16F = gl::RGB16F,
RGB32F = gl::RGB32F,
RGBA8 = gl::RGBA8,
RGBA16 = gl::RGBA16,
RGBA16F = gl::RGBA16F,
RGBA32F = gl::RGBA32F,
}
#[cfg(any(feature = "gles", feature="webgl"))]
#[derive(Copy,Clone,Debug)]
#[repr(u32)]
pub enum ColorFormat{
R8 = gl::R8,
R16F = gl::R16F,
R32F = gl::R32F,
RG8 = gl::RG8,
RG16F = gl::RG16F,
RG32F = gl::RG32F,
RGB8 = gl::RGB8,
RGB16F = gl::RGB16F,
RGB32F = gl::RGB32F,
RGBA8 = gl::RGBA8,
RGBA16F = gl::RGBA16F,
RGBA32F = gl::RGBA32F,
}
impl Default for ColorFormat{
fn default() -> ColorFormat{
ColorFormat::RGBA8
}
}
impl ColorFormat{
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn from(internal_format: GLenum) -> Option<ColorFormat>{
let format = match internal_format{
gl::R8 => ColorFormat::R8,
gl::R16 => ColorFormat::R16,
gl::R32F => ColorFormat::R32F,
gl::RG8 => ColorFormat::RG8,
gl::RG16 => ColorFormat::RG16,
gl::RG32F => ColorFormat::RG32F,
gl::RGB8 => ColorFormat::RGB8,
gl::RGB16 => ColorFormat::RGB16,
gl::RGB16F => ColorFormat::RGB16F,
gl::RGB32F => ColorFormat::RGB32F,
gl::RGBA8 => ColorFormat::RGBA8,
gl::RGBA16 => ColorFormat::RGBA16,
gl::RGBA16F => ColorFormat::RGBA16F,
gl::RGBA32F => ColorFormat::RGBA32F,
_ => return None,
};
Some(format)
}
#[cfg(any(feature = "gles", feature="webgl"))]
pub fn from(internal_format: GLenum) -> Option<ColorFormat>{
let format = match internal_format{
gl::R8 => ColorFormat::R8,
gl::R16F => ColorFormat::R16F,
gl::R32F => ColorFormat::R32F,
gl::RG8 => ColorFormat::RG8,
gl::RG16F => ColorFormat::RG16F,
gl::RG32F => ColorFormat::RG32F,
gl::RGB8 => ColorFormat::RGB8,
gl::RGB16F => ColorFormat::RGB16F,
gl::RGB32F => ColorFormat::RGB32F,
gl::RGBA8 => ColorFormat::RGBA8,
gl::RGBA16F => ColorFormat::RGBA16F,
gl::RGBA32F => ColorFormat::RGBA32F,
_ => return None,
};
Some(format)
}
}
pub struct ColorAttachmentBuilder<'a>(pub(crate) &'a StateRef);
impl<'a> ColorAttachmentBuilder<'a>{
pub fn texture(&self, w: u32, h: u32, format: ColorFormat) -> ::Result<ColorAttachment>{
let tex = texture::Builder(self.0)
.from_format(texture::Format::Texture2D{
internal_format: format as GLenum,
width: w,
height: h,
levels: 1,
})?;
Ok(ColorAttachment::TextureLevel(tex, 0))
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn texture_multisampled(&self, w: u32, h: u32, samples: u32, format: ColorFormat) -> ::Result<ColorAttachment>{
let tex = texture::Builder(self.0)
.from_format(texture::Format::Texture2DMultisample{
internal_format: format as GLenum,
width: w,
height: h,
samples: samples,
})?;
Ok(ColorAttachment::TextureLevel(tex, 0))
}
pub fn render_buffer(&self, w: u32, h: u32, format: ColorFormat) -> ::Result<ColorAttachment>{
let buffer = RenderBufferBuilder(self.0).create(w, h, format as GLenum)?;
Ok(ColorAttachment::RenderBuffer(buffer))
}
pub fn render_buffer_multisampled(&self, w: u32, h: u32, samples: u32, format: ColorFormat) -> ::Result<ColorAttachment>{
let buffer = RenderBufferBuilder(self.0).create_multisampled(w, h, samples, format as GLenum)?;
Ok(ColorAttachment::RenderBuffer(buffer))
}
#[cfg(not(feature="webgl"))]
pub fn cubemap(&self, w: u32, h: u32, format: ColorFormat) -> ::Result<ColorAttachment>{
let cubemap = cubemap::Builder(self.0).from_format(cubemap::Format{
internal_format: format as GLenum,
width: w,
height: h,
levels: 1})?;
Ok(ColorAttachment::CubeMapLevel(cubemap, 0))
}
}
impl ColorAttachment{
pub fn width(&self) -> u32{
match self {
ColorAttachment::TextureLevel(tex,_) => tex.width(),
ColorAttachment::RenderBuffer(buff) => buff.width(),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(cubemap,_) => cubemap.width(),
ColorAttachment::CubeMapFaceLevel(cubemap, _, _) => cubemap.width(),
}
}
pub fn height(&self) -> u32{
match self {
ColorAttachment::TextureLevel(tex,_) => tex.height(),
ColorAttachment::RenderBuffer(buff) => buff.height(),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(cubemap,_) => cubemap.height(),
ColorAttachment::CubeMapFaceLevel(cubemap, _, _) => cubemap.height(),
}
}
pub fn samples(&self) -> u32{
match self {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
ColorAttachment::TextureLevel(tex,_) => tex.samples(),
#[cfg(any(feature = "gles", feature="webgl"))]
ColorAttachment::TextureLevel(_tex, _) => 0,
ColorAttachment::RenderBuffer(buff) => buff.samples(),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(_,_) => 0,
ColorAttachment::CubeMapFaceLevel(_, _, _) => 0,
}
}
}
impl ColorAttach for ColorAttachment{
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
match self {
ColorAttachment::TextureLevel(texture, level)
=> framebuffer.attach_texture(texture.id(), texture.target(), *level, target, attachment),
ColorAttachment::RenderBuffer(renderbuffer)
=> framebuffer.attach_render_buffer(renderbuffer.id(), target, attachment),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(cubemap, level)
=> framebuffer.attach_cubemap(cubemap.id(), *level, target, attachment),
ColorAttachment::CubeMapFaceLevel(cubemap, face, level)
=> framebuffer.attach_cubemap_face(cubemap.id(), *face, *level, target, attachment)
}
}
fn width(&self) -> u32{
match self {
ColorAttachment::TextureLevel(tex,_) => tex.width(),
ColorAttachment::RenderBuffer(buff) => buff.width(),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(cubemap,_) => cubemap.width(),
ColorAttachment::CubeMapFaceLevel(cubemap, _, _) => cubemap.width(),
}
}
fn height(&self) -> u32{
match self {
ColorAttachment::TextureLevel(tex,_) => tex.height(),
ColorAttachment::RenderBuffer(buff) => buff.height(),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(cubemap,_) => cubemap.height(),
ColorAttachment::CubeMapFaceLevel(cubemap, _, _) => cubemap.height(),
}
}
fn samples(&self) -> u32{
match self {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
ColorAttachment::TextureLevel(tex,_) => tex.samples(),
#[cfg(any(feature = "gles", feature="webgl"))]
ColorAttachment::TextureLevel(_tex, _) => 0,
ColorAttachment::RenderBuffer(buff) => buff.samples(),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(_,_) => 0,
ColorAttachment::CubeMapFaceLevel(_, _, _) => 0,
}
}
fn attachment_id(&self) -> ColorAttachmentId{
match self {
ColorAttachment::TextureLevel(tex,level)
=> ColorAttachmentId::TextureLevel(tex.id(), *level),
ColorAttachment::RenderBuffer(buff)
=> ColorAttachmentId::RenderBuffer(buff.id()),
#[cfg(not(feature="webgl"))]
ColorAttachment::CubeMapLevel(cubemap,level)
=> ColorAttachmentId::CubeMapLevel(cubemap.id(), *level),
ColorAttachment::CubeMapFaceLevel(cubemap, face, level)
=> ColorAttachmentId::CubeMapFaceLevel(cubemap.id(), *face, *level)
}
}
}
impl ColorAttach for Texture {
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint) {
framebuffer.attach_texture(self.id(), self.target(), 0, target, attachment)
}
fn width(&self) -> u32 {
self.width()
}
fn height(&self) -> u32 {
self.height()
}
fn samples(&self) -> u32 {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
{
self.samples()
}
#[cfg(any(feature = "gles", feature="webgl"))]
{
0
}
}
fn attachment_id(&self) -> ColorAttachmentId {
ColorAttachmentId::TextureLevel(self.id(), 0)
}
}
impl ColorAttach for RenderBuffer {
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
framebuffer.attach_render_buffer(self.id(), target, attachment)
}
fn width(&self) -> u32{
self.width()
}
fn height(&self) -> u32{
self.height()
}
fn samples(&self) -> u32{
self.samples()
}
fn attachment_id(&self) -> ColorAttachmentId{
ColorAttachmentId::RenderBuffer(self.id())
}
}
pub struct TextureLevelRef<T> {
texture: T,
level: i32
}
impl<T: Clone> Clone for TextureLevelRef<T>{
fn clone(&self) -> TextureLevelRef<T>{
TextureLevelRef{
texture: self.texture.clone(),
level: self.level
}
}
}
impl<T: Copy> Copy for TextureLevelRef<T>{}
impl<T: Borrow<Texture>> TextureLevelRef<T> {
pub fn new(texture: T, level: i32) -> TextureLevelRef<T> {
assert!(texture.borrow().levels() > level as u32);
TextureLevelRef{
texture,
level
}
}
pub fn texture(&self) -> &Texture{
self.texture.borrow()
}
pub fn level(&self) -> i32{
self.level
}
}
impl<T: Borrow<Texture>> ColorAttach for TextureLevelRef<T> {
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint) {
let texture = self.texture.borrow();
framebuffer.attach_texture(texture.id(), texture.target(), self.level, target, attachment)
}
fn width(&self) -> u32 {
self.texture.borrow().width() >> self.level
}
fn height(&self) -> u32 {
self.texture.borrow().height() >> self.level
}
fn samples(&self) -> u32 {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
{
self.texture.borrow().samples()
}
#[cfg(any(feature = "gles", feature="webgl"))]
{
0
}
}
fn attachment_id(&self) -> ColorAttachmentId {
ColorAttachmentId::TextureLevel(self.texture.borrow().id(), self.level)
}
}
pub struct TextureLayerLevelRef<T> {
texture: T,
layer: i32,
level: i32
}
impl<T: Clone> Clone for TextureLayerLevelRef<T>{
fn clone(&self) -> TextureLayerLevelRef<T>{
TextureLayerLevelRef{
texture: self.texture.clone(),
level: self.level,
layer: self.layer,
}
}
}
impl<T: Copy> Copy for TextureLayerLevelRef<T>{}
impl<T: Borrow<Texture>> TextureLayerLevelRef<T> {
pub fn new(texture: T, level: i32, layer: i32) -> TextureLayerLevelRef<T> {
assert!(texture.borrow().levels() > level as u32);
TextureLayerLevelRef{
texture,
level,
layer
}
}
pub fn texture(&self) -> &Texture{
self.texture.borrow()
}
pub fn level(&self) -> i32{
self.level
}
}
impl<T: Borrow<Texture>> ColorAttach for TextureLayerLevelRef<T> {
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, _target: GLenum, attachment: GLuint) {
let texture = self.texture.borrow();
framebuffer.attach_texture_layer(texture.id(), texture.target(), self.level, attachment, self.layer)
}
fn width(&self) -> u32 {
self.texture.borrow().width() >> self.level
}
fn height(&self) -> u32 {
self.texture.borrow().height() >> self.level
}
fn samples(&self) -> u32 {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
{
self.texture.borrow().samples()
}
#[cfg(any(feature = "gles", feature="webgl"))]
{
0
}
}
fn attachment_id(&self) -> ColorAttachmentId {
ColorAttachmentId::TextureLayerLevel(self.texture.borrow().id(), self.level, self.layer)
}
}
#[cfg(not(feature="webgl"))]
impl ColorAttach for CubeMap {
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint) {
framebuffer.attach_cubemap(self.id(), 0, target, attachment)
}
fn width(&self) -> u32 {
self.width()
}
fn height(&self) -> u32 {
self.height()
}
fn samples(&self) -> u32 {
0
}
fn attachment_id(&self) -> ColorAttachmentId {
ColorAttachmentId::CubeMapLevel(self.id(), 0)
}
}
#[cfg(not(feature="webgl"))]
pub struct CubemapLevelRef<C> {
cubemap: C,
level: i32
}
#[cfg(not(feature="webgl"))]
impl<T: Clone> Clone for CubemapLevelRef<T>{
fn clone(&self) -> CubemapLevelRef<T>{
CubemapLevelRef{
cubemap: self.cubemap.clone(),
level: self.level
}
}
}
#[cfg(not(feature="webgl"))]
impl<T: Copy> Copy for CubemapLevelRef<T>{}
#[cfg(not(feature="webgl"))]
impl<T: Borrow<::CubeMap>> CubemapLevelRef<T> {
pub fn new(cubemap: T, level: i32) -> CubemapLevelRef<T> {
assert!(cubemap.borrow().levels() > level as u32);
CubemapLevelRef{
cubemap,
level
}
}
pub fn cubemap(&self) -> &::CubeMap{
self.cubemap.borrow()
}
pub fn level(&self) -> i32{
self.level
}
}
#[cfg(not(feature="webgl"))]
impl<T: Borrow<::CubeMap>> ColorAttach for CubemapLevelRef<T> {
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
let cubemap = self.cubemap.borrow();
framebuffer.attach_cubemap(cubemap.id(), self.level, target, attachment)
}
fn width(&self) -> u32{
self.cubemap.borrow().width()
}
fn height(&self) -> u32{
self.cubemap.borrow().height()
}
fn samples(&self) -> u32{
0
}
fn attachment_id(&self) -> ColorAttachmentId{
ColorAttachmentId::CubeMapLevel(self.cubemap.borrow().id(), self.level)
}
}
pub struct CubemapFaceLevelRef<C> {
cubemap: C,
face: u32,
level: i32
}
impl<T: Borrow<::CubeMap>> CubemapFaceLevelRef<T> {
pub fn new(cubemap: T, face: u32, level: i32) -> CubemapFaceLevelRef<T> {
assert!(cubemap.borrow().levels() > level as u32);
CubemapFaceLevelRef{
cubemap,
face,
level
}
}
pub fn cubemap(&self) -> &::CubeMap{
self.cubemap.borrow()
}
pub fn level(&self) -> i32{
self.level
}
pub fn face(&self) -> u32{
self.face
}
}
impl<C: Borrow<CubeMap>> ColorAttach for CubemapFaceLevelRef<C>{
unsafe fn color_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
framebuffer.attach_cubemap_face(self.cubemap.borrow().id(), self.face, self.level, target, attachment)
}
fn width(&self) -> u32{
self.cubemap.borrow().width() >> self.level
}
fn height(&self) -> u32{
self.cubemap.borrow().height() >> self.level
}
fn samples(&self) -> u32{
0
}
fn attachment_id(&self) -> ColorAttachmentId{
ColorAttachmentId::CubeMapFaceLevel(self.cubemap.borrow().id(), self.face, self.level)
}
}
pub trait BorrowColorAttach{
type ColorAttach: ColorAttach;
fn borrow_color_attachment(&self) -> &Self::ColorAttach;
}
impl<'a> BorrowColorAttach for &'a ColorAttachment {
type ColorAttach = ColorAttachment;
fn borrow_color_attachment(&self) -> &ColorAttachment {
self
}
}
impl BorrowColorAttach for Rc<ColorAttachment> {
type ColorAttach = ColorAttachment;
fn borrow_color_attachment(&self) -> &ColorAttachment {
self
}
}
impl<'a> BorrowColorAttach for &'a Texture {
type ColorAttach = Texture;
fn borrow_color_attachment(&self) -> &Texture {
self
}
}
impl BorrowColorAttach for Rc<Texture> {
type ColorAttach = Texture;
fn borrow_color_attachment(&self) -> &Texture {
self
}
}
impl<'a> BorrowColorAttach for &'a RenderBuffer {
type ColorAttach = RenderBuffer;
fn borrow_color_attachment(&self) -> &RenderBuffer {
self
}
}
impl BorrowColorAttach for Rc<RenderBuffer> {
type ColorAttach = RenderBuffer;
fn borrow_color_attachment(&self) -> &RenderBuffer {
self
}
}
impl<'a, T: Borrow<Texture>> BorrowColorAttach for &'a TextureLevelRef<T> {
type ColorAttach = TextureLevelRef<T>;
fn borrow_color_attachment(&self) -> &TextureLevelRef<T> {
self
}
}
impl<T: Borrow<Texture>> BorrowColorAttach for Rc<TextureLevelRef<T>> {
type ColorAttach = TextureLevelRef<T>;
fn borrow_color_attachment(&self) -> &TextureLevelRef<T> {
self
}
}
#[cfg(not(feature="webgl"))]
impl<'a, T: Borrow<CubeMap>> BorrowColorAttach for &'a CubemapLevelRef<T> {
type ColorAttach = CubemapLevelRef<T>;
fn borrow_color_attachment(&self) -> &CubemapLevelRef<T> {
self
}
}
#[cfg(not(feature="webgl"))]
impl<T: Borrow<CubeMap>> BorrowColorAttach for Rc<CubemapLevelRef<T>> {
type ColorAttach = CubemapLevelRef<T>;
fn borrow_color_attachment(&self) -> &CubemapLevelRef<T> {
self
}
}
impl<'a, T: Borrow<CubeMap>> BorrowColorAttach for &'a CubemapFaceLevelRef<T> {
type ColorAttach = CubemapFaceLevelRef<T>;
fn borrow_color_attachment(&self) -> &CubemapFaceLevelRef<T> {
self
}
}
impl<T: Borrow<CubeMap>> BorrowColorAttach for Rc<CubemapFaceLevelRef<T>> {
type ColorAttach = CubemapFaceLevelRef<T>;
fn borrow_color_attachment(&self) -> &CubemapFaceLevelRef<T> {
self
}
}
impl<C: ColorAttach> BorrowColorAttach for C {
type ColorAttach = C;
fn borrow_color_attachment(&self) -> &Self::ColorAttach {
self
}
}
#[derive(Debug)]
pub enum DepthAttachment{
TextureLevel(Texture, i32),
RenderBuffer(RenderBuffer),
#[cfg(not(feature="webgl"))]
CubeMapLevel(CubeMap, i32),
CubeMapFaceLevel(CubeMap, u32, i32),
}
#[derive(Copy,Clone,Debug)]
#[repr(u32)]
pub enum DepthFormat{
_16 = gl::DEPTH_COMPONENT16,
_24 = gl::DEPTH_COMPONENT24,
_32 = gl::DEPTH_COMPONENT32F,
}
impl Default for DepthFormat{
fn default() -> DepthFormat{
DepthFormat::_24
}
}
impl DepthFormat{
pub fn from(internal_format: GLenum) -> Option<DepthFormat>{
let format = match internal_format{
gl::DEPTH_COMPONENT16 => DepthFormat::_16,
gl::DEPTH_COMPONENT24 => DepthFormat::_24,
gl::DEPTH_COMPONENT32F => DepthFormat::_32,
_ => return None,
};
Some(format)
}
}
pub trait DepthAttach{
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint);
fn width(&self) -> u32;
fn height(&self) -> u32;
fn samples(&self) -> u32;
fn attachment_id(&self) -> DepthAttachmentId;
}
pub struct DepthAttachmentBuilder<'a>(pub(crate) &'a StateRef);
impl<'a> DepthAttachmentBuilder<'a>{
pub fn texture(&self, w: u32, h: u32, format: DepthFormat) -> ::Result<DepthAttachment>{
let tex = texture::Builder(self.0)
.from_format(texture::Format::Texture2D{
internal_format: format as GLenum,
width: w,
height: h,
levels: 1,
})?;
Ok(DepthAttachment::TextureLevel(tex, 0))
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn texture_multisampled(&self, w: u32, h: u32, samples: u32, format: DepthFormat) -> ::Result<DepthAttachment>{
let tex = texture::Builder(self.0)
.from_format(texture::Format::Texture2DMultisample{
internal_format: format as GLenum,
width: w,
height: h,
samples: samples,
})?;
Ok(DepthAttachment::TextureLevel(tex, 0))
}
pub fn render_buffer(&self, w: u32, h: u32, format: DepthFormat) -> ::Result<DepthAttachment>{
let buffer = RenderBufferBuilder(self.0).create(w, h, format as GLenum)?;
Ok(DepthAttachment::RenderBuffer(buffer))
}
pub fn render_buffer_multisampled(&self, w: u32, h: u32, samples: u32, format: DepthFormat) -> ::Result<DepthAttachment>{
let buffer = RenderBufferBuilder(self.0).create_multisampled(w, h, samples, format as GLenum)?;
Ok(DepthAttachment::RenderBuffer(buffer))
}
#[cfg(not(feature="webgl"))]
pub fn cubemap(&self, w: u32, h: u32, format: DepthFormat) -> ::Result<DepthAttachment>{
let cubemap = cubemap::Builder(self.0).from_format(cubemap::Format{
internal_format: format as GLenum,
width: w,
height: h,
levels: 1})?;
Ok(DepthAttachment::CubeMapLevel(cubemap, 0))
}
}
impl DepthAttachment{
pub fn width(&self) -> u32{
match self{
DepthAttachment::TextureLevel(tex, _) => tex.width(),
DepthAttachment::RenderBuffer(buff) => buff.width(),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(cm, _) => cm.width(),
DepthAttachment::CubeMapFaceLevel(cm, _, _) => cm.width(),
}
}
pub fn height(&self) -> u32{
match self{
DepthAttachment::TextureLevel(tex, _) => tex.height(),
DepthAttachment::RenderBuffer(buff) => buff.height(),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(cm, _) => cm.height(),
DepthAttachment::CubeMapFaceLevel(cm, _, _) => cm.height(),
}
}
pub fn samples(&self) -> u32{
match self {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
DepthAttachment::TextureLevel(tex, _) => tex.samples(),
#[cfg(any(feature = "gles", feature="webgl"))]
DepthAttachment::TextureLevel(_tex, _) => 0,
DepthAttachment::RenderBuffer(buff) => buff.samples(),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(_, _) => 0,
DepthAttachment::CubeMapFaceLevel(_, _, _) => 0,
}
}
}
impl DepthAttach for DepthAttachment{
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
match self {
DepthAttachment::TextureLevel(texture, level)
=> framebuffer.attach_texture(texture.id(), texture.target(), *level, target, attachment),
DepthAttachment::RenderBuffer(renderbuffer)
=> framebuffer.attach_render_buffer(renderbuffer.id(), target, attachment),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(cubemap, level)
=> framebuffer.attach_cubemap(cubemap.id(), *level, target, attachment),
DepthAttachment::CubeMapFaceLevel(cubemap, face, level)
=> framebuffer.attach_cubemap_face(cubemap.id(), *face, *level, target, attachment)
}
}
fn width(&self) -> u32{
match self {
DepthAttachment::TextureLevel(tex, _) => tex.width(),
DepthAttachment::RenderBuffer(buff) => buff.width(),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(cubemap, _) => cubemap.width(),
DepthAttachment::CubeMapFaceLevel(cubemap, _, _) => cubemap.width(),
}
}
fn height(&self) -> u32{
match self {
DepthAttachment::TextureLevel(tex, _) => tex.height(),
DepthAttachment::RenderBuffer(buff) => buff.height(),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(cubemap, _) => cubemap.height(),
DepthAttachment::CubeMapFaceLevel(cubemap, _, _) => cubemap.height(),
}
}
fn samples(&self) -> u32{
match self {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
DepthAttachment::TextureLevel(tex, _) => tex.samples(),
#[cfg(any(feature = "gles", feature="webgl"))]
DepthAttachment::TextureLevel(_tex, _) => 0,
DepthAttachment::RenderBuffer(buff) => buff.samples(),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(_, _) => 0,
DepthAttachment::CubeMapFaceLevel(_, _, _) => 0,
}
}
fn attachment_id(&self) -> DepthAttachmentId{
match self {
DepthAttachment::TextureLevel(tex, level)
=> DepthAttachmentId::TextureLevel(tex.height(), *level),
DepthAttachment::RenderBuffer(buff)
=> DepthAttachmentId::RenderBuffer(buff.height()),
#[cfg(not(feature="webgl"))]
DepthAttachment::CubeMapLevel(cubemap, level)
=> DepthAttachmentId::CubeMapLevel(cubemap.height(), *level),
DepthAttachment::CubeMapFaceLevel(cubemap, face, level)
=> DepthAttachmentId::CubeMapFaceLevel(cubemap.height(), *face, *level),
}
}
}
impl DepthAttach for Texture {
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
framebuffer.attach_texture(self.id(), self.target(), 0, target, attachment)
}
fn width(&self) -> u32{
self.width()
}
fn height(&self) -> u32{
self.height()
}
fn samples(&self) -> u32{
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
{
self.samples()
}
#[cfg(any(feature = "gles", feature="webgl"))]
{
0
}
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::TextureLevel(self.id(), 0)
}
}
impl DepthAttach for RenderBuffer {
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
framebuffer.attach_render_buffer(self.id(), target, attachment)
}
fn width(&self) -> u32{
self.width()
}
fn height(&self) -> u32{
self.height()
}
fn samples(&self) -> u32{
self.samples()
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::RenderBuffer(self.id())
}
}
impl<T: Borrow<::Texture>> DepthAttach for TextureLevelRef<T>{
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
let texture = self.texture.borrow();
framebuffer.attach_texture(texture.id(), texture.target(), self.level, target, attachment)
}
fn width(&self) -> u32{
self.texture.borrow().width()
}
fn height(&self) -> u32{
self.texture.borrow().height()
}
fn samples(&self) -> u32{
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
{
self.texture.borrow().samples()
}
#[cfg(any(feature = "gles", feature="webgl"))]
{
0
}
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::TextureLevel(self.texture.borrow().id(), self.level)
}
}
impl<T: Borrow<::Texture>> DepthAttach for TextureLayerLevelRef<T>{
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, _target: GLenum, attachment: GLuint){
let texture = self.texture.borrow();
framebuffer.attach_texture_layer(texture.id(), texture.target(), self.level, attachment, self.layer)
}
fn width(&self) -> u32{
self.texture.borrow().width()
}
fn height(&self) -> u32{
self.texture.borrow().height()
}
fn samples(&self) -> u32{
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
{
self.texture.borrow().samples()
}
#[cfg(any(feature = "gles", feature="webgl"))]
{
0
}
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::TextureLayerLevel(self.texture.borrow().id(), self.level, self.layer)
}
}
#[cfg(not(feature="webgl"))]
impl DepthAttach for CubeMap {
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
framebuffer.attach_cubemap(self.id(), 0, target, attachment)
}
fn width(&self) -> u32{
self.width()
}
fn height(&self) -> u32{
self.height()
}
fn samples(&self) -> u32{
0
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::CubeMapLevel(self.id(), 0)
}
}
#[cfg(not(feature="webgl"))]
impl<T: Borrow<::CubeMap>> DepthAttach for CubemapLevelRef<T> {
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
let cubemap = self.cubemap.borrow();
framebuffer.attach_cubemap(cubemap.id(), self.level, target, attachment)
}
fn width(&self) -> u32{
self.cubemap.borrow().width()
}
fn height(&self) -> u32{
self.cubemap.borrow().height()
}
fn samples(&self) -> u32{
0
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::CubeMapLevel(self.cubemap.borrow().id(), self.level)
}
}
impl<'a, C: Borrow<::CubeMap>> DepthAttach for CubemapFaceLevelRef<C>{
unsafe fn depth_attach(&self, framebuffer: &FrameBuffer, target: GLenum, attachment: GLuint){
framebuffer.attach_cubemap_face(self.cubemap.borrow().id(), self.face, self.level, target, attachment)
}
fn width(&self) -> u32{
self.cubemap.borrow().width() >> self.level
}
fn height(&self) -> u32{
self.cubemap.borrow().height() >> self.level
}
fn samples(&self) -> u32{
0
}
fn attachment_id(&self) -> DepthAttachmentId{
DepthAttachmentId::CubeMapFaceLevel(self.cubemap.borrow().id(), self.face, self.level)
}
}
pub trait BorrowDepthAttach{
type DepthAttach: DepthAttach;
fn borrow_depth_attachment(&self) -> &Self::DepthAttach;
}
impl<'a> BorrowDepthAttach for &'a DepthAttachment {
type DepthAttach = DepthAttachment;
fn borrow_depth_attachment(&self) -> &DepthAttachment {
self
}
}
impl BorrowDepthAttach for Rc<DepthAttachment> {
type DepthAttach = DepthAttachment;
fn borrow_depth_attachment(&self) -> &DepthAttachment {
self
}
}
impl<'a> BorrowDepthAttach for &'a Texture {
type DepthAttach = Texture;
fn borrow_depth_attachment(&self) -> &Texture {
self
}
}
impl BorrowDepthAttach for Rc<Texture> {
type DepthAttach = Texture;
fn borrow_depth_attachment(&self) -> &Texture {
self
}
}
impl<'a> BorrowDepthAttach for &'a RenderBuffer {
type DepthAttach = RenderBuffer;
fn borrow_depth_attachment(&self) -> &RenderBuffer {
self
}
}
impl BorrowDepthAttach for Rc<RenderBuffer> {
type DepthAttach = RenderBuffer;
fn borrow_depth_attachment(&self) -> &RenderBuffer {
self
}
}
impl<'a, T: Borrow<Texture>> BorrowDepthAttach for &'a TextureLevelRef<T> {
type DepthAttach = TextureLevelRef<T>;
fn borrow_depth_attachment(&self) -> &TextureLevelRef<T> {
self
}
}
impl<T: Borrow<Texture>> BorrowDepthAttach for Rc<TextureLevelRef<T>> {
type DepthAttach = TextureLevelRef<T>;
fn borrow_depth_attachment(&self) -> &TextureLevelRef<T> {
self
}
}
#[cfg(not(feature="webgl"))]
impl<'a, T: Borrow<CubeMap>> BorrowDepthAttach for &'a CubemapLevelRef<T> {
type DepthAttach = CubemapLevelRef<T>;
fn borrow_depth_attachment(&self) -> &CubemapLevelRef<T> {
self
}
}
#[cfg(not(feature="webgl"))]
impl<T: Borrow<CubeMap>> BorrowDepthAttach for Rc<CubemapLevelRef<T>> {
type DepthAttach = CubemapLevelRef<T>;
fn borrow_depth_attachment(&self) -> &CubemapLevelRef<T> {
self
}
}
impl<'a, T: Borrow<CubeMap>> BorrowDepthAttach for &'a CubemapFaceLevelRef<T> {
type DepthAttach = CubemapFaceLevelRef<T>;
fn borrow_depth_attachment(&self) -> &CubemapFaceLevelRef<T> {
self
}
}
impl<T: Borrow<CubeMap>> BorrowDepthAttach for Rc<CubemapFaceLevelRef<T>> {
type DepthAttach = CubemapFaceLevelRef<T>;
fn borrow_depth_attachment(&self) -> &CubemapFaceLevelRef<T> {
self
}
}
impl<C: DepthAttach> BorrowDepthAttach for C {
type DepthAttach = C;
fn borrow_depth_attachment(&self) -> &Self::DepthAttach {
self
}
}