-
Notifications
You must be signed in to change notification settings - Fork 762
/
Copy pathviewer.cpp
244 lines (191 loc) · 7.21 KB
/
viewer.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
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#include "viewer.h"
#include <cstdlib>
Viewer::Viewer() : shader_folder("src/shader/"),
win_width(600),
win_height(400)
{
}
static void glfwErrorCallback(int error, const char* description)
{
std::cerr << "GLFW error " << error << " " << description << std::endl;
}
void Viewer::initialize()
{
// init glfw - if already initialized nothing happens
int init = glfwInit();
GLFWerrorfun prev_func = glfwSetErrorCallback(glfwErrorCallback);
if (prev_func)
glfwSetErrorCallback(prev_func);
// setup context
glfwDefaultWindowHints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
#ifdef __APPLE__
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#else
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
#endif
//glfwWindowHint(GLFW_VISIBLE, debug ? GL_TRUE : GL_FALSE);
window = glfwCreateWindow(win_width*2, win_height*2, "Viewer (press ESC to exit)", 0, NULL);
if (window == NULL)
{
std::cerr << "Failed to create opengl window." << std::endl;
exit(-1);
}
glfwMakeContextCurrent(window);
OpenGLBindings *b = new OpenGLBindings();
flextInit(b);
gl(b);
std::string vertexshadersrc = ""
"#version 330\n"
"in vec2 Position;"
"in vec2 TexCoord;"
"out VertexData{"
"vec2 TexCoord;"
"} VertexOut;"
"void main(void)"
"{"
" gl_Position = vec4(Position, 0.0, 1.0);"
" VertexOut.TexCoord = TexCoord;"
"}";
std::string grayfragmentshader = ""
"#version 330\n"
"uniform sampler2DRect Data;"
"vec4 tempColor;"
"in VertexData{"
" vec2 TexCoord;"
"} FragmentIn;"
"layout(location = 0) out vec4 Color;"
"void main(void)"
"{"
"ivec2 uv = ivec2(FragmentIn.TexCoord.x, FragmentIn.TexCoord.y);"
"tempColor = texelFetch(Data, uv);"
"Color = vec4(tempColor.x/4500, tempColor.x/4500, tempColor.x/4500, 1);"
"}";
std::string fragmentshader = ""
"#version 330\n"
"uniform sampler2DRect Data;"
"in VertexData{"
" vec2 TexCoord;"
"} FragmentIn;"
"layout(location = 0) out vec4 Color;"
"void main(void)"
"{"
" ivec2 uv = ivec2(FragmentIn.TexCoord.x, FragmentIn.TexCoord.y);"
" Color = texelFetch(Data, uv);"
"}";
renderShader.setVertexShader(vertexshadersrc);
renderShader.setFragmentShader(fragmentshader);
renderShader.build();
renderGrayShader.setVertexShader(vertexshadersrc);
renderGrayShader.setFragmentShader(grayfragmentshader);
renderGrayShader.build();
glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(window, Viewer::key_callbackstatic);
glfwSetWindowSizeCallback(window, Viewer::winsize_callbackstatic);
shouldStop = false;
}
void Viewer::winsize_callbackstatic(GLFWwindow* window, int w, int h)
{
Viewer* viewer = reinterpret_cast<Viewer*>(glfwGetWindowUserPointer(window));
viewer->winsize_callback(window, w, h);
}
void Viewer::winsize_callback(GLFWwindow* window, int w, int h)
{
win_width = w/2;
win_height = h/2;
}
void Viewer::key_callbackstatic(GLFWwindow* window, int key, int scancode, int action, int mods)
{
Viewer* viewer = reinterpret_cast<Viewer*>(glfwGetWindowUserPointer(window));
viewer->key_callback(window, key, scancode, action, mods);
}
void Viewer::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
shouldStop = true;
}
void Viewer::onOpenGLBindingsChanged(OpenGLBindings *b)
{
renderShader.gl(b);
renderGrayShader.gl(b);
rgb.gl(b);
ir.gl(b);
}
bool Viewer::render()
{
// wipe the drawing surface clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLint x = 0, y = 0;
int fb_width, fb_width_half, fb_height, fb_height_half;
std::map<std::string, libfreenect2::Frame*>::iterator iter;
for (iter = frames.begin(); iter != frames.end(); ++iter)
{
libfreenect2::Frame* frame = iter->second;
// Using the frame buffer size to account for screens where window.size != framebuffer.size, e.g. retina displays
glfwGetFramebufferSize(window, &fb_width, &fb_height);
fb_width_half = (fb_width + 1) / 2;
fb_height_half = (fb_height + 1) / 2;
glViewport(x, y, fb_width_half, fb_height_half);
x += fb_width_half;
if (x >= (fb_width - 1))
{
x = 0;
y += fb_height_half;
}
float w = static_cast<float>(frame->width);
float h = static_cast<float>(frame->height);
Vertex bl = { -1.0f, -1.0f, 0.0f, 0.0f };
Vertex br = { 1.0f, -1.0f, w, 0.0f };
Vertex tl = { -1.0f, 1.0f, 0.0f, h };
Vertex tr = { 1.0f, 1.0f, w, h };
Vertex vertices[] = {
bl, tl, tr,
tr, br, bl
};
gl()->glGenBuffers(1, &triangle_vbo);
gl()->glGenVertexArrays(1, &triangle_vao);
gl()->glBindVertexArray(triangle_vao);
gl()->glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo);
gl()->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLint position_attr = renderShader.getAttributeLocation("Position");
gl()->glVertexAttribPointer(position_attr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
gl()->glEnableVertexAttribArray(position_attr);
GLint texcoord_attr = renderShader.getAttributeLocation("TexCoord");
gl()->glVertexAttribPointer(texcoord_attr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(2 * sizeof(float)));
gl()->glEnableVertexAttribArray(texcoord_attr);
if (iter->first == "RGB" || iter->first == "registered")
{
renderShader.use();
rgb.allocate(frame->width, frame->height);
std::copy(frame->data, frame->data + frame->width * frame->height * frame->bytes_per_pixel, rgb.data);
rgb.flipY();
rgb.upload();
glDrawArrays(GL_TRIANGLES, 0, 6);
rgb.deallocate();
}
else
{
renderGrayShader.use();
ir.allocate(frame->width, frame->height);
std::copy(frame->data, frame->data + frame->width * frame->height * frame->bytes_per_pixel, ir.data);
ir.flipY();
ir.upload();
glDrawArrays(GL_TRIANGLES, 0, 6);
ir.deallocate();
}
gl()->glDeleteBuffers(1, &triangle_vbo);
gl()->glDeleteVertexArrays(1, &triangle_vao);
}
// put the stuff we've been drawing onto the display
glfwSwapBuffers(window);
// update other events like input handling
glfwPollEvents();
return shouldStop || glfwWindowShouldClose(window);
}
void Viewer::addFrame(std::string id, libfreenect2::Frame* frame)
{
frames[id] = frame;
}