fbo.c (3136B)
1 2 #include <assert.h> 3 #include "fbo.h" 4 #include "util.h" 5 6 void create_fbo(struct fbo *fbo, int width, int height) { 7 glGenFramebuffers(1, &fbo->handle); 8 glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); 9 check_gl(); 10 11 fbo->n_attachments = 0; 12 fbo->width = width; 13 fbo->height = height; 14 } 15 16 int fbo_attach_renderbuffer(struct fbo *fbo, 17 GLenum internalformat, GLenum attachment) { 18 assert(fbo->n_attachments < MAX_FBO_ATTACHMENTS); 19 GLuint *rbo = &fbo->attachments[fbo->n_attachments++]; 20 21 glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); 22 glGenRenderbuffers(1, rbo); 23 glBindRenderbuffer(GL_RENDERBUFFER, *rbo); 24 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, fbo->width, fbo->height); 25 glBindRenderbuffer(GL_RENDERBUFFER, 0); 26 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, *rbo); 27 glBindFramebuffer(GL_FRAMEBUFFER, 0); 28 29 return *rbo; 30 } 31 32 void init_fbo(struct fbo *fbo) { 33 fbo->n_attachments = 0; 34 fbo->handle = 0; 35 fbo->width = 0; 36 fbo->height = 0; 37 } 38 39 int fbo_attach_texture(struct fbo *fbo, GLint internalformat, GLint format, 40 GLenum attachment, GLenum type) { 41 assert(fbo->n_attachments < MAX_FBO_ATTACHMENTS); 42 GLuint *texture = &fbo->attachments[fbo->n_attachments++]; 43 44 glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); 45 glGenTextures(1, texture); 46 check_gl(); 47 glBindTexture(GL_TEXTURE_2D, *texture); 48 check_gl(); 49 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, fbo->width, fbo->height, 0, 50 format, type, NULL); 51 check_gl(); 52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 53 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 54 check_gl(); 55 if (attachment == GL_DEPTH_ATTACHMENT) { 56 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 58 } 59 check_gl(); 60 61 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, *texture, 62 0); 63 64 check_gl(); 65 glBindFramebuffer(GL_FRAMEBUFFER, 0); 66 check_gl(); 67 68 return *texture; 69 } 70 71 void check_fbo(struct fbo *fbo) { 72 glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); 73 check_gl(); 74 assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 75 glBindFramebuffer(GL_FRAMEBUFFER, 0); 76 check_gl(); 77 } 78 79 void delete_fbo(struct fbo *fbo) { 80 // TODO: delete attachments 81 82 glDeleteFramebuffers(1, &fbo->handle); 83 check_gl(); 84 } 85 86 87 void bind_fbo(struct fbo *fbo) { 88 glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); 89 check_gl(); 90 } 91 92 void unbind_fbo(struct fbo *fbo) { 93 glBindFramebuffer(GL_FRAMEBUFFER, 0); 94 check_gl(); 95 } 96 97 int fbo_attach_depth_texture(struct fbo *fbo) { 98 return fbo_attach_texture(fbo, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, 99 GL_DEPTH_ATTACHMENT, GL_FLOAT); 100 } 101 102 int fbo_attach_color_texture(struct fbo *fbo) { 103 return fbo_attach_texture(fbo, GL_RGB, GL_RGB, GL_COLOR_ATTACHMENT0, 104 GL_UNSIGNED_BYTE); 105 }