-
Notifications
You must be signed in to change notification settings - Fork 0
/
fbo.cpp
103 lines (84 loc) · 3.52 KB
/
fbo.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
#include <sstream>
#include "fbo.h"
//#include "globals.h"
using namespace std;
/* Frame buffer object demonstration class by Perry Kivolowitz, University of Wisconsin Madison.
Note this class provides the option of allocating multiple color attachments per frame buffer
object as well as the option to attach a depth buffer to the frame buffer object.
*/
FrameBufferObject::FrameBufferObject()
{
this->framebuffer_handle = GLuint(-1);
this->depth_buffer_handle = GLuint(-1);
this->texture_handles = NULL;
}
void FrameBufferObject::Bind(int color_attachment_index)
{
assert(color_attachment_index <= this->number_of_color_attachments);
assert(this->framebuffer_handle != GLuint(-1));
glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer_handle);
glDrawBuffer(GL_COLOR_ATTACHMENT0 + color_attachment_index);
}
void FrameBufferObject::Unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBufferObject::TakeDown()
{
if (this->framebuffer_handle != GLuint(-1))
glDeleteFramebuffers(1, &this->framebuffer_handle);
if (this->depth_buffer_handle != GLuint(-1))
glDeleteFramebuffers(1, &this->depth_buffer_handle);
if (this->texture_handles != NULL)
{
glDeleteTextures(this->number_of_color_attachments, this->texture_handles);
delete [] this->texture_handles;
}
}
bool FrameBufferObject::Initialize(glm::ivec2 size, int number_of_color_attachments, bool allocate_depth_buffer)
{
this->size = size;
this->number_of_color_attachments = number_of_color_attachments;
this->texture_handles = new GLuint[number_of_color_attachments];
for (int i = 0; i < number_of_color_attachments; i++)
this->texture_handles[i] = GLuint(-1);
glGenFramebuffers(1, &this->framebuffer_handle);
glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer_handle);
/*if (!CheckGLErrors("FrameBufferObject::Initialize - purging errors prior to initializing textures."))
return false;*/
glGenTextures(number_of_color_attachments, this->texture_handles);
for (int i = 0; i < number_of_color_attachments; i++)
{
glBindTexture(GL_TEXTURE_2D, this->texture_handles[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, this->size.x, this->size.y, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, this->texture_handles[i], 0);
}
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
/*if (status != GL_FRAMEBUFFER_COMPLETE)
{
cout << "FrameBufferObject::Initialize failed to complete texture buffer " << FramebufferCompletenessError(status) << endl;
return false;
}*/
if (allocate_depth_buffer)
{
glGenRenderbuffers(1, &this->depth_buffer_handle);
glBindRenderbuffer(GL_RENDERBUFFER, this->depth_buffer_handle);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, this->size.x, this->size.y);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->depth_buffer_handle);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
//if (status != GL_FRAMEBUFFER_COMPLETE)
//{
// cout << "FrameBufferObject::Initialize failed to complete depth buffer " << FramebufferCompletenessError(status) << endl;
// return false;
//}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}