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.
111 lines
2.9 KiB
111 lines
2.9 KiB
13 years ago
|
#ifndef FBO_H
|
||
|
#define FBO_H
|
||
|
|
||
|
#include <stdexcept>
|
||
|
|
||
|
#include <GL/glew.h>
|
||
|
#include <GL/freeglut.h>
|
||
|
|
||
|
|
||
|
class fbo {
|
||
|
int width, height;
|
||
|
GLuint fbo_number;
|
||
|
std::map<GLenum, GLuint> renderbuffers;
|
||
|
GLuint texture_id;
|
||
|
|
||
|
public:
|
||
|
fbo(int width, int height) : width(width), height(height) {
|
||
|
check_status();
|
||
|
glGenBuffers(1, &fbo_number);
|
||
|
begin();
|
||
|
|
||
|
// generate texture
|
||
|
glGenTextures(1, &texture_id);
|
||
|
glEnable(GL_TEXTURE_2D);
|
||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_BYTE, 0);
|
||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
|
||
|
|
||
|
// attach depth
|
||
|
create_attach_renderbuffer(GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT);
|
||
|
|
||
|
// attach stencil
|
||
|
create_attach_renderbuffer(GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT);
|
||
|
|
||
|
check_status();
|
||
|
}
|
||
|
~fbo() {
|
||
|
end();
|
||
|
|
||
|
glDeleteFramebuffers(1, &fbo_number);
|
||
|
|
||
|
for(auto& it : renderbuffers){
|
||
|
glDeleteFramebuffers(1, &it.second);
|
||
|
}
|
||
|
|
||
|
glDeleteTextures(1, &texture_id);
|
||
|
}
|
||
|
|
||
|
void begin(){
|
||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo_number);
|
||
|
}
|
||
|
|
||
|
void end(){
|
||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
void create_attach_renderbuffer(GLenum format, GLenum attachment_point) {
|
||
|
GLuint buffer;
|
||
|
glGenRenderbuffers(1, &buffer);
|
||
|
glBindRenderbuffer(GL_RENDERBUFFER, buffer);
|
||
|
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
|
||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_point, GL_RENDERBUFFER, buffer);
|
||
|
|
||
|
renderbuffers[format] = buffer;
|
||
|
}
|
||
|
|
||
|
void check_status() {
|
||
|
GLenum status = glGetError();
|
||
|
if(status != GL_NO_ERROR) {
|
||
|
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||
|
switch(status) {
|
||
|
case GL_FRAMEBUFFER_COMPLETE:
|
||
|
std::cout << "FRAMEBUFFER_COMPLETE - OK" << std::endl;
|
||
|
return;
|
||
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||
|
std::cout << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT" << std::endl;
|
||
|
break;
|
||
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||
|
std::cout << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" << std::endl;
|
||
|
break;
|
||
|
/*case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
|
||
|
std::cout << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS" << std::endl;
|
||
|
break;
|
||
|
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
|
||
|
std::cout << "FRAMEBUFFER_INCOMPLETE_FORMATS" << std::endl;
|
||
|
break;*/
|
||
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
|
||
|
std::cout << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" << std::endl;
|
||
|
break;
|
||
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
|
||
|
std::cout << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER" << std::endl;
|
||
|
break;
|
||
|
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||
|
std::cout << "FRAMEBUFFER_UNSUPPORTED" << std::endl;
|
||
|
break;
|
||
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
|
||
|
std::cout << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << std::endl;
|
||
|
break;
|
||
|
default:
|
||
|
std::cout << "UNKNOWN FRAMEBUFFER ERROR" << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
throw std::runtime_error("I will not continu..");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif // FBO_H
|