RobotKernal-UESTC/Code/MowingRobot/PIBot_ROS/third_party/libfreenect2/examples/viewer.cpp

245 lines
7.2 KiB
C++
Raw Normal View History

2023-12-14 23:56:56 +08:00
#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
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, 2);
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;
}