You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.2 KiB
92 lines
2.2 KiB
11 years ago
|
#pragma once
|
||
|
|
||
|
#include <moggle/core/gl.hpp>
|
||
|
#include "renderbuffer.hpp"
|
||
|
#include "texture.hpp"
|
||
|
|
||
|
#include <vector>
|
||
|
|
||
|
/*
|
||
|
* One can attach either an external renderbuffer/texture, or move one into fbo
|
||
|
* In the latter case, the fbo will own the renderbuffer/texture
|
||
|
*
|
||
|
* Attachment can be one of: GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, or GL_STENCIL_ATTACHMENT
|
||
|
*/
|
||
|
|
||
|
namespace moggle {
|
||
|
|
||
|
struct fbo {
|
||
|
explicit fbo(bool create_now = false) {
|
||
|
if(create_now) create();
|
||
|
}
|
||
|
|
||
|
~fbo() { destroy(); }
|
||
|
|
||
|
fbo(fbo const &) = delete;
|
||
|
fbo & operator=(fbo const&) = delete;
|
||
|
|
||
|
fbo(fbo && r) : id(r.id) { r.id = 0; }
|
||
|
fbo & operator=(fbo && r) { std::swap(id, r.id); return *this; }
|
||
|
|
||
|
bool created() const { return id; }
|
||
|
explicit operator bool() const { return created(); }
|
||
|
|
||
|
void create(){ if(!id) gl::generate_framebuffers(1, &id); }
|
||
|
void destroy(){ gl::delete_renderbuffers(1, &id); id = 0; }
|
||
|
|
||
|
void bind() {
|
||
|
create();
|
||
|
gl::bind_framebuffer(GL_FRAMEBUFFER, id);
|
||
|
}
|
||
|
|
||
|
GLuint get_id() const {
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
// Only well defined if the fbo owns the texture
|
||
|
texture & get_texture() {
|
||
|
return textures.front();
|
||
|
}
|
||
|
|
||
|
void attach(GLenum attachment, renderbuffer const & rb){
|
||
|
bind();
|
||
|
gl::framebuffer_renderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rb.get_id());
|
||
|
}
|
||
|
|
||
|
void attach(GLenum attachment, renderbuffer && rb){
|
||
|
renderbuffers.push_back(std::move(rb));
|
||
|
attach(attachment, renderbuffers.back());
|
||
|
}
|
||
|
|
||
|
void attach(GLenum attachment, GLenum textarget, texture const & t){
|
||
|
bind();
|
||
|
gl::framebuffer_texture_2d(GL_FRAMEBUFFER, attachment, textarget, t.get_id(), 0);
|
||
|
}
|
||
|
|
||
|
void attach(GLenum attachment, GLenum textarget, texture && t){
|
||
|
textures.push_back(std::move(t));
|
||
|
attach(attachment, textarget, textures.back());
|
||
|
}
|
||
|
|
||
|
void clear(GLenum bufferbits){
|
||
|
bind();
|
||
|
gl::clear(bufferbits);
|
||
|
}
|
||
|
|
||
|
static fbo create_default(GLsizei width, GLsizei height){
|
||
|
fbo f;
|
||
|
f.attach(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture::create(width, height, GL_RGBA32F));
|
||
|
f.attach(GL_DEPTH_ATTACHMENT, renderbuffer::create(width, height, 1, GL_DEPTH_COMPONENT16));
|
||
|
f.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
|
return f;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
std::vector<renderbuffer> renderbuffers;
|
||
|
std::vector<texture> textures;
|
||
|
|
||
|
GLuint id = 0;
|
||
|
};
|
||
|
|
||
|
}
|