-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathframebuffer.h
134 lines (113 loc) · 5.59 KB
/
framebuffer.h
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#pragma once
#include "icg_helper.h"
class FrameBuffer {
private:
int width_;
int height_;
GLuint framebuffer_object_id_;
GLuint depth_render_buffer_id_;
GLuint color_texture_id_;
GLuint tmp_texture_id_;
public:
// warning: overrides viewport!!
void Bind() {
glViewport(0, 0, width_, height_);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id_);
const GLenum buffers[] = { GL_COLOR_ATTACHMENT0
};
glDrawBuffers(1 /*length of buffers[]*/, buffers);
}
void Unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
std::tuple<int, int> Init(int image_width, int image_height, bool use_interpolation = false) {
this->width_ = image_width;
this->height_ = image_height;
// create color attachment
{
glGenTextures(1, &color_texture_id_);
glBindTexture(GL_TEXTURE_2D, color_texture_id_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if(use_interpolation){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
// create texture for the color attachment
// see Table.2 on
// khronos.org/opengles/sdk/docs/man3/docbook4/xhtml/glTexImage2D.xml
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width_, height_, 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL);
// how to load from buffer
}
// create second color attachement for temp texture
{
glGenTextures(1, &tmp_texture_id_);
glBindTexture(GL_TEXTURE_2D, tmp_texture_id_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if(use_interpolation){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
// On some intel OpenGL drivers, GL_RGB32F isn't supported inside
// a framebuffer, but using GL_RGB16F is
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width_, height_, 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
// create render buffer (for depth channel)
{
glGenRenderbuffers(1, &depth_render_buffer_id_);
glBindRenderbuffer(GL_RENDERBUFFER, depth_render_buffer_id_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width_, height_);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
// tie it all together
{
glGenFramebuffers(1, &framebuffer_object_id_);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id_);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0 /*location = 0*/,
GL_TEXTURE_2D, color_texture_id_,
0 /*level*/);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1 /*location = 1*/,
GL_TEXTURE_2D, tmp_texture_id_,
0 /*level*/);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_render_buffer_id_);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
GL_FRAMEBUFFER_COMPLETE) {
cerr << "!!!ERROR: Framebuffer not OK :(" << endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // avoid pollution
}
cout << color_texture_id_ << endl;
cout << tmp_texture_id_ << endl;
return std::make_tuple(color_texture_id_, tmp_texture_id_);
}
void Clear() {
glViewport(0, 0, width_, height_);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id_);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Cleanup() {
glDeleteTextures(1, &color_texture_id_);
glDeleteTextures(1, &tmp_texture_id_);
glDeleteRenderbuffers(1, &depth_render_buffer_id_);
glBindFramebuffer(GL_FRAMEBUFFER, 0 /*UNBIND*/);
glDeleteFramebuffers(1, &framebuffer_object_id_);
}
};