14 #include <assimp/Importer.hpp> 15 #include <assimp/scene.h> 16 #include <assimp/postprocess.h> 18 #include <glm/gtc/matrix_transform.hpp> 19 #include <glm/gtc/type_ptr.hpp> 21 #include <opencv2/imgproc/imgproc.hpp> 31 const GLsizei cam_width,
32 const GLsizei cam_height,
38 SICAD(objfile_map, cam_width, cam_height, cam_fx, cam_fy, cam_cx, cam_cy, 1,
"__prc/shader", { 1.0f, 0.0f, 0.0f, 0.0f })
45 const GLsizei cam_width,
46 const GLsizei cam_height,
51 const GLint num_images
53 SICAD(objfile_map, cam_width, cam_height, cam_fx, cam_fy, cam_cx, cam_cy, num_images,
"__prc/shader", { 1.0f, 0.0f, 0.0f, 0.0f })
60 const GLsizei cam_width,
61 const GLsizei cam_height,
66 const GLint num_images,
67 const std::string& shader_folder
69 SICAD(objfile_map, cam_width, cam_height, cam_fx, cam_fy, cam_cx, cam_cy, num_images, shader_folder, { 1.0f, 0.0f, 0.0f, 0.0f })
76 const GLsizei cam_width,
77 const GLsizei cam_height,
82 const GLint num_images,
83 const std::string& shader_folder,
84 const std::vector<float>& ogl_to_cam
87 if (ogl_to_cam.size() != 4)
88 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tWrong size provided for ogl_to_cam.\n\tShould be 4, was given " + std::to_string(ogl_to_cam.size()) +
".");
91 std::cout << log_ID_ <<
"Start setting up OpenGL rendering facilities." << std::endl;
95 if (glfwInit() == GL_FALSE)
96 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tFailed to initialize GLFW.");
100 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
101 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
102 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
103 glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
104 glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
105 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
106 glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_NONE);
108 glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GL_FALSE);
113 window_ = glfwCreateWindow(1, 1,
"OpenGL window",
nullptr,
nullptr);
114 if (window_ ==
nullptr)
117 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tFailed to create GLFW window.");
121 glfwMakeContextCurrent(window_);
125 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &renderbuffer_size_);
126 std::cout << log_ID_ <<
"Max renderbuffer size is " + std::to_string(renderbuffer_size_) +
"x" + std::to_string(renderbuffer_size_) +
" size." << std::endl;
130 image_width_ = cam_width;
131 image_height_ = cam_height;
132 std::cout << log_ID_ <<
"Given image size " + std::to_string(image_width_) +
"x" + std::to_string(image_height_) +
"." << std::endl;
136 factorize_int(num_images, std::floor(renderbuffer_size_ / image_width_), std::floor(renderbuffer_size_ / image_height_), tiles_cols_, tiles_rows_);
137 tiles_num_ = tiles_rows_ * tiles_cols_;
138 std::cout << log_ID_ <<
"Required to render " + std::to_string(num_images) +
" image(s)." << std::endl;
139 std::cout << log_ID_ <<
"Allowed number or rendered images is " + std::to_string(tiles_num_) +
" (" + std::to_string(tiles_rows_) +
"x" + std::to_string(tiles_cols_) +
" grid)." << std::endl;
142 framebuffer_width_ = image_width_ * tiles_cols_;
143 framebuffer_height_ = image_height_ * tiles_rows_;
146 tile_img_width_ = framebuffer_width_ / tiles_cols_;
147 tile_img_height_ = framebuffer_height_ / tiles_rows_;
148 std::cout << log_ID_ <<
"The rendered image size is " + std::to_string(tile_img_width_) +
"x" + std::to_string(tile_img_height_) +
"." << std::endl;
152 glewExperimental = GL_TRUE;
153 if (glewInit() != GLEW_OK)
154 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tFailed to initialize GLEW.");
159 main_thread_id_ = std::this_thread::get_id();
162 std::cout << log_ID_ <<
"Succesfully set up OpenGL facilities!" << std::endl;
165 std::cout << log_ID_ <<
"Setting up OpenGL shaders, buffers and textures." << std::endl;
169 ogl_to_cam_ = glm::mat3(glm::rotate(glm::mat4(1.0f), ogl_to_cam[3], glm::make_vec3(ogl_to_cam.data())));
173 glGenFramebuffers(1, &fbo_);
174 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
176 glGenTextures(1, &texture_color_buffer_);
177 glBindTexture(GL_TEXTURE_2D, texture_color_buffer_);
178 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, framebuffer_width_, framebuffer_height_, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
181 glBindTexture(GL_TEXTURE_2D, 0);
183 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_color_buffer_, 0);
186 glGenTextures(1, &texture_depth_buffer_);
187 glBindTexture(GL_TEXTURE_2D, texture_depth_buffer_);
188 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, framebuffer_width_, framebuffer_height_, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
191 glBindTexture(GL_TEXTURE_2D, 0);
193 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture_depth_buffer_, 0);
196 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
197 throw std::runtime_error(
"ERROR::SICAD::CTOR::\nERROR:\n\tCustom framebuffer could not be created.");
201 glEnable(GL_DEPTH_TEST);
202 glEnable(GL_SCISSOR_TEST);
206 glBindFramebuffer(GL_FRAMEBUFFER, 0);
210 glGenVertexArrays(1, &vao_frame_);
211 glBindVertexArray(vao_frame_);
213 glGenBuffers(1, &vbo_frame_);
214 glBindBuffer(GL_ARRAY_BUFFER, vbo_frame_);
216 GLfloat vert_frame[] = {
217 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
218 0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
219 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
220 0.0f, 0.1f, 0.0f, 0.0f, 1.0f, 0.0f,
221 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
222 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f };
224 glBufferData(GL_ARRAY_BUFFER,
sizeof(vert_frame), vert_frame, GL_STATIC_DRAW);
226 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 *
sizeof(GLfloat), (GLvoid*)(0));
227 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 *
sizeof(GLfloat), (GLvoid*)(3 *
sizeof(GLfloat)));
229 glEnableVertexAttribArray(0);
230 glEnableVertexAttribArray(1);
232 glBindVertexArray(0);
236 glGenTextures(1, &texture_background_);
239 glGenVertexArrays(1, &vao_background_);
240 glBindVertexArray(vao_background_);
242 glGenBuffers(1, &vbo_background_);
243 glBindBuffer(GL_ARRAY_BUFFER, vbo_background_);
245 GLfloat vert_background[] = {
246 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
247 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
248 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
249 -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f };
251 glBufferData(GL_ARRAY_BUFFER,
sizeof(vert_background), vert_background, GL_STATIC_DRAW);
253 glGenBuffers(1, &ebo_background_);
254 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_background_);
256 GLuint indices[] = { 0, 1, 3,
259 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices), indices, GL_STATIC_DRAW);
261 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 7 *
sizeof(GLfloat), (GLvoid*)(0));
262 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 7 *
sizeof(GLfloat), (GLvoid*)(2 *
sizeof(GLfloat)));
263 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 7 *
sizeof(GLfloat), (GLvoid*)(5 *
sizeof(GLfloat)));
265 glEnableVertexAttribArray(0);
266 glEnableVertexAttribArray(1);
267 glEnableVertexAttribArray(2);
269 glBindVertexArray(0);
273 glGenBuffers(2, pbo_);
274 unsigned int number_of_channel = 3;
276 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[0]);
277 glBufferData(GL_PIXEL_PACK_BUFFER, framebuffer_width_ * framebuffer_height_ * number_of_channel, 0, GL_STREAM_READ);
279 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[1]);
280 glBufferData(GL_PIXEL_PACK_BUFFER, framebuffer_width_ * framebuffer_height_ * number_of_channel, 0, GL_STREAM_READ);
282 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
291 std::cout << log_ID_ <<
"Setting up background shader." << std::endl;
295 shader_background_ =
new (std::nothrow)
Shader((shader_folder +
"/shader_background.vert").c_str(), (shader_folder +
"/shader_background.frag").c_str());
297 catch (
const std::runtime_error& e)
299 throw std::runtime_error(e.what());
301 if (shader_background_ ==
nullptr)
302 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tBackground shader source file not found!");
304 std::cout << log_ID_ <<
"Background shader succesfully set up!" << std::endl;
308 std::cout << log_ID_ <<
"Setting up shader for mesh models." << std::endl;
312 shader_cad_ =
new (std::nothrow)
Shader((shader_folder +
"/shader_model.vert").c_str(), (shader_folder +
"/shader_model.frag").c_str());
314 catch (
const std::runtime_error& e)
316 throw std::runtime_error(e.what());
318 if (shader_cad_ ==
nullptr)
319 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\t3D model shader source file not found!");
321 std::cout << log_ID_ <<
"Shader for mesh models succesfully set up!" << std::endl;
325 std::cout << log_ID_ <<
"Setting up shader for textured mesh model." << std::endl;
329 shader_mesh_texture_ = std::unique_ptr<Shader>(
new Shader((shader_folder +
"/shader_model.vert").c_str(), (shader_folder +
"/shader_model_texture.frag").c_str()));
331 catch (
const std::runtime_error& e)
333 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tFailed to create shader program for textured meshes.\n" + std::string(e.what()));
336 std::cout << log_ID_ <<
"Shader for textured mesh models succesfully set up!" << std::endl;
340 std::cout << log_ID_ <<
"Setting up maxis frame shader." << std::endl;
344 shader_frame_ =
new (std::nothrow)
Shader((shader_folder +
"/shader_frame.vert").c_str(), (shader_folder +
"/shader_frame.frag").c_str());
346 catch (
const std::runtime_error& e)
348 throw std::runtime_error(e.what());
350 if (shader_frame_ ==
nullptr)
351 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tAxis frame shader source file not found!");
353 std::cout << log_ID_ <<
"Axis frame shader succesfully set up!" << std::endl;
359 auto search = model_obj_.find(pair.first);
360 if(search == model_obj_.end())
362 std::cout << log_ID_ <<
"Loading " + pair.first +
" model for OpenGL rendering from " << pair.second <<
"." << std::endl;
364 model_obj_[pair.first] =
new (std::nothrow)
Model(pair.second.c_str());
366 if (model_obj_[pair.first] ==
nullptr)
367 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\t" + pair.first +
" model file from " + pair.second +
" not found!");
371 std::cout << log_ID_ <<
"Skipping " + pair.first +
" model for OpenGL rendering. Object name already exists." << std::endl;
372 std::cout << log_ID_ <<
"If you want to update " + pair.first +
" model for OpenGL rendering, use the updateModel function." << std::endl;
376 back_proj_ = glm::ortho(-1.001f, 1.001f, -1.001f, 1.001f, 0.0f, far_*100.f);
378 glfwMakeContextCurrent(
nullptr);
381 std::cout << log_ID_ <<
"Succesfully set up OpenGL shaders, buffers and textures." << std::endl;
385 std::cout << log_ID_ <<
"Setting up projection matrix." << std::endl;
387 if (!setProjectionMatrix(cam_width, cam_height, cam_fx, cam_fy, cam_cx, cam_cy))
388 throw std::runtime_error(
"ERROR::SICAD::CTOR\nERROR:\n\tFailed to set projection matrix.");
395 std::cout << log_ID_ <<
"Initialization completed!" << std::endl;
401 std::cout <<
log_ID_ <<
"Deallocating OpenGL resources..." << std::endl;
404 glfwMakeContextCurrent(
window_);
409 std::cout <<
log_ID_ <<
"Deleting OpenGL "+ pair.first+
" model." << std::endl;
416 glDeleteFramebuffers(1, &
fbo_);
423 glDeleteBuffers(2,
pbo_);
426 std::cout <<
log_ID_ <<
"Deleting OpenGL shaders." << std::endl;
432 std::cout <<
log_ID_ <<
"Closing OpenGL window/context." << std::endl;
433 glfwSetWindowShouldClose(
window_, GL_TRUE);
434 glfwMakeContextCurrent(
nullptr);
440 std::cout <<
log_ID_ <<
"Terminating GLFW." << std::endl;
445 std::cout <<
log_ID_ <<
"OpenGL resource deallocation completed!" << std::endl;
451 return (glfwWindowShouldClose(
window_) == GL_TRUE ?
true :
false);
457 glfwSetWindowShouldClose(
window_, GL_TRUE);
471 glfwMakeContextCurrent(window_);
473 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
476 glViewport(0, framebuffer_height_ - tile_img_height_,
477 tile_img_width_, tile_img_height_ );
478 glScissor (0, framebuffer_height_ - tile_img_height_,
479 tile_img_width_, tile_img_height_ );
482 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
483 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
486 if (getBackgroundOpt())
487 renderBackground(img);
490 setWireframe(getWireframeOpt());
493 glm::mat4 view = getViewTransformationMatrix(cam_x, cam_o);
496 shader_cad_->install();
497 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
498 shader_cad_->uninstall();
500 shader_mesh_texture_->install();
501 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
502 shader_mesh_texture_->uninstall();
504 shader_frame_->install();
505 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
506 shader_frame_->uninstall();
511 const double* pose = pair.second.data();
513 glm::mat4 model = glm::rotate(glm::mat4(1.0f), static_cast<float>(pose[6]), glm::vec3(static_cast<float>(pose[3]), static_cast<float>(pose[4]), static_cast<float>(pose[5])));
514 model[3][0] = pose[0];
515 model[3][1] = pose[1];
516 model[3][2] = pose[2];
518 auto iter_model = model_obj_.find(pair.first);
519 if (iter_model != model_obj_.end())
521 if ((iter_model->second)->has_texture())
523 shader_mesh_texture_->install();
524 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
526 (iter_model->second)->Draw(*shader_mesh_texture_);
528 shader_mesh_texture_->uninstall();
532 shader_cad_->install();
533 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
535 (iter_model->second)->Draw(*shader_cad_);
537 shader_cad_->uninstall();
540 else if (pair.first ==
"frame")
542 shader_frame_->install();
543 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
544 glBindVertexArray(vao_frame_);
545 glDrawArrays(GL_LINES, 0, 6);
546 glBindVertexArray(0);
547 shader_frame_->uninstall();
554 cv::Mat ogl_pixel(framebuffer_height_ / tiles_rows_, framebuffer_width_ / tiles_cols_, CV_8UC3);
555 glReadBuffer(GL_COLOR_ATTACHMENT0);
556 glPixelStorei(GL_PACK_ALIGNMENT, (ogl_pixel.step & 3) ? 1 : 4);
557 glPixelStorei(GL_PACK_ROW_LENGTH, ogl_pixel.step/ogl_pixel.elemSize());
558 glReadPixels(0, framebuffer_height_ - tile_img_height_, tile_img_width_, tile_img_height_, GL_BGR, GL_UNSIGNED_BYTE, ogl_pixel.data);
560 cv::flip(ogl_pixel, img, 0);
563 glfwSwapBuffers(window_);
567 glBindFramebuffer(GL_FRAMEBUFFER, 0);
569 glfwMakeContextCurrent(
nullptr);
577 const std::vector<ModelPoseContainer>& objpos_multimap,
584 const int objpos_num = objpos_multimap.size();
585 if (objpos_num != tiles_num_)
return false;
587 glfwMakeContextCurrent(window_);
589 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
592 glm::mat4 view = getViewTransformationMatrix(cam_x, cam_o);
595 shader_cad_->install();
596 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
597 shader_cad_->uninstall();
599 shader_mesh_texture_->install();
600 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
601 shader_mesh_texture_->uninstall();
603 shader_frame_->install();
604 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
605 shader_frame_->uninstall();
607 for (
unsigned int i = 0; i < tiles_rows_; ++i)
609 for (
unsigned int j = 0; j < tiles_cols_; ++j)
612 int idx = i * tiles_cols_ + j;
615 glViewport(tile_img_width_ * j, framebuffer_height_ - (tile_img_height_ * (i + 1)),
616 tile_img_width_ , tile_img_height_ );
617 glScissor (tile_img_width_ * j, framebuffer_height_ - (tile_img_height_ * (i + 1)),
618 tile_img_width_ , tile_img_height_ );
621 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
622 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
625 if (getBackgroundOpt())
626 renderBackground(img);
629 setWireframe(getWireframeOpt());
634 const double* pose = pair.second.data();
636 glm::mat4 model = glm::rotate(glm::mat4(1.0f), static_cast<float>(pose[6]), glm::vec3(static_cast<float>(pose[3]), static_cast<float>(pose[4]), static_cast<float>(pose[5])));
637 model[3][0] =
static_cast<float>(pose[0]);
638 model[3][1] =
static_cast<float>(pose[1]);
639 model[3][2] =
static_cast<float>(pose[2]);
641 auto iter_model = model_obj_.find(pair.first);
642 if (iter_model != model_obj_.end())
644 if ((iter_model->second)->has_texture())
646 shader_mesh_texture_->install();
647 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
649 (iter_model->second)->Draw(*shader_mesh_texture_);
651 shader_mesh_texture_->uninstall();
655 shader_cad_->install();
656 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
658 (iter_model->second)->Draw(*shader_cad_);
660 shader_cad_->uninstall();
663 else if (pair.first ==
"frame")
665 shader_frame_->install();
666 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
667 glBindVertexArray(vao_frame_);
668 glDrawArrays(GL_LINES, 0, 6);
669 glBindVertexArray(0);
670 shader_frame_->uninstall();
679 cv::Mat ogl_pixel(framebuffer_height_, framebuffer_width_, CV_8UC3);
680 glReadBuffer(GL_COLOR_ATTACHMENT0);
681 glPixelStorei(GL_PACK_ALIGNMENT, (ogl_pixel.step & 3) ? 1 : 4);
682 glPixelStorei(GL_PACK_ROW_LENGTH, ogl_pixel.step/ogl_pixel.elemSize());
683 glReadPixels(0, 0, framebuffer_width_, framebuffer_height_, GL_BGR, GL_UNSIGNED_BYTE, ogl_pixel.data);
685 cv::flip(ogl_pixel, img, 0);
688 glfwSwapBuffers(window_);
692 glBindFramebuffer(GL_FRAMEBUFFER, 0);
694 glfwMakeContextCurrent(
nullptr);
706 const GLsizei cam_width,
707 const GLsizei cam_height,
708 const GLfloat cam_fx,
709 const GLfloat cam_fy,
710 const GLfloat cam_cx,
714 if (!setProjectionMatrix(cam_width, cam_height, cam_fx, cam_fy, cam_cx, cam_cy))
717 return superimpose(objpos_map, cam_x, cam_o, img);
723 const std::vector<ModelPoseContainer>& objpos_multimap,
727 const GLsizei cam_width,
728 const GLsizei cam_height,
729 const GLfloat cam_fx,
730 const GLfloat cam_fy,
731 const GLfloat cam_cx,
735 if (!setProjectionMatrix(cam_width, cam_height, cam_fx, cam_fy, cam_cx, cam_cy))
738 return superimpose(objpos_multimap, cam_x, cam_o, img);
747 const size_t pbo_index
750 if (!(pbo_index < pbo_number_))
752 std::cerr <<
"ERROR::SICAD::SUPERIMPOSE\nERROR:\n\tSICAD PBO index out of bound." << std::endl;
757 glfwMakeContextCurrent(window_);
759 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
762 glViewport(0, framebuffer_height_ - tile_img_height_,
763 tile_img_width_, tile_img_height_ );
764 glScissor (0, framebuffer_height_ - tile_img_height_,
765 tile_img_width_, tile_img_height_ );
768 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
769 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
772 setWireframe(getWireframeOpt());
775 glm::mat4 view = getViewTransformationMatrix(cam_x, cam_o);
778 shader_cad_->install();
779 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
780 shader_cad_->uninstall();
782 shader_mesh_texture_->install();
783 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
784 shader_mesh_texture_->uninstall();
786 shader_frame_->install();
787 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
788 shader_frame_->uninstall();
793 const double* pose = pair.second.data();
795 glm::mat4 model = glm::rotate(glm::mat4(1.0f), static_cast<float>(pose[6]), glm::vec3(static_cast<float>(pose[3]), static_cast<float>(pose[4]), static_cast<float>(pose[5])));
796 model[3][0] = pose[0];
797 model[3][1] = pose[1];
798 model[3][2] = pose[2];
800 auto iter_model = model_obj_.find(pair.first);
801 if (iter_model != model_obj_.end())
803 if ((iter_model->second)->has_texture())
805 shader_mesh_texture_->install();
806 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
808 (iter_model->second)->Draw(*shader_mesh_texture_);
810 shader_mesh_texture_->uninstall();
814 shader_cad_->install();
815 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
817 (iter_model->second)->Draw(*shader_cad_);
819 shader_cad_->uninstall();
822 else if (pair.first ==
"frame")
824 shader_frame_->install();
825 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
826 glBindVertexArray(vao_frame_);
827 glDrawArrays(GL_LINES, 0, 6);
828 glBindVertexArray(0);
829 shader_frame_->uninstall();
833 glReadBuffer(GL_COLOR_ATTACHMENT0);
834 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[pbo_index]);
835 glReadPixels(0, framebuffer_height_ - tile_img_height_, tile_img_width_, tile_img_height_, GL_BGR, GL_UNSIGNED_BYTE, 0);
838 glfwSwapBuffers(window_);
842 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
843 glBindFramebuffer(GL_FRAMEBUFFER, 0);
854 const size_t pbo_index,
858 if (!(pbo_index < pbo_number_))
860 std::cerr <<
"ERROR::SICAD::SUPERIMPOSE\nERROR:\n\tSICAD PBO index out of bound." << std::endl;
865 glfwMakeContextCurrent(window_);
867 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
870 glViewport(0, framebuffer_height_ - tile_img_height_,
871 tile_img_width_, tile_img_height_ );
872 glScissor (0, framebuffer_height_ - tile_img_height_,
873 tile_img_width_, tile_img_height_ );
876 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
877 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
880 if (getBackgroundOpt())
881 renderBackground(img);
884 setWireframe(getWireframeOpt());
887 glm::mat4 view = getViewTransformationMatrix(cam_x, cam_o);
890 shader_cad_->install();
891 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
892 shader_cad_->uninstall();
894 shader_mesh_texture_->install();
895 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
896 shader_mesh_texture_->uninstall();
898 shader_frame_->install();
899 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
900 shader_frame_->uninstall();
905 const double* pose = pair.second.data();
907 glm::mat4 model = glm::rotate(glm::mat4(1.0f), static_cast<float>(pose[6]), glm::vec3(static_cast<float>(pose[3]), static_cast<float>(pose[4]), static_cast<float>(pose[5])));
908 model[3][0] = pose[0];
909 model[3][1] = pose[1];
910 model[3][2] = pose[2];
912 auto iter_model = model_obj_.find(pair.first);
913 if (iter_model != model_obj_.end())
915 if ((iter_model->second)->has_texture())
917 shader_mesh_texture_->install();
918 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
920 (iter_model->second)->Draw(*shader_mesh_texture_);
922 shader_mesh_texture_->uninstall();
926 shader_cad_->install();
927 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
929 (iter_model->second)->Draw(*shader_cad_);
931 shader_cad_->uninstall();
934 else if (pair.first ==
"frame")
936 shader_frame_->install();
937 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
938 glBindVertexArray(vao_frame_);
939 glDrawArrays(GL_LINES, 0, 6);
940 glBindVertexArray(0);
941 shader_frame_->uninstall();
945 glReadBuffer(GL_COLOR_ATTACHMENT0);
946 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[pbo_index]);
947 glReadPixels(0, framebuffer_height_ - tile_img_height_, tile_img_width_, tile_img_height_, GL_BGR, GL_UNSIGNED_BYTE, 0);
950 glfwSwapBuffers(window_);
954 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
955 glBindFramebuffer(GL_FRAMEBUFFER, 0);
963 const std::vector<ModelPoseContainer>& objpos_multimap,
966 const size_t pbo_index
969 if (!(pbo_index < pbo_number_))
971 std::cerr <<
"ERROR::SICAD::SUPERIMPOSE\nERROR:\n\tSICAD PBO index out of bound." << std::endl;
977 const int objpos_num = objpos_multimap.size();
978 if (objpos_num != tiles_num_)
return false;
980 glfwMakeContextCurrent(window_);
982 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
985 glm::mat4 view = getViewTransformationMatrix(cam_x, cam_o);
988 shader_cad_->install();
989 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
990 shader_cad_->uninstall();
992 shader_mesh_texture_->install();
993 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
994 shader_mesh_texture_->uninstall();
996 shader_frame_->install();
997 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
998 shader_frame_->uninstall();
1000 for (
unsigned int i = 0; i < tiles_rows_; ++i)
1002 for (
unsigned int j = 0; j < tiles_cols_; ++j)
1005 int idx = i * tiles_cols_ + j;
1008 glViewport(tile_img_width_ * j, framebuffer_height_ - (tile_img_height_ * (i + 1)),
1009 tile_img_width_, tile_img_height_ );
1010 glScissor (tile_img_width_ * j, framebuffer_height_ - (tile_img_height_ * (i + 1)),
1011 tile_img_width_, tile_img_height_ );
1014 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1015 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1018 setWireframe(getWireframeOpt());
1023 const double* pose = pair.second.data();
1025 glm::mat4 model = glm::rotate(glm::mat4(1.0f), static_cast<float>(pose[6]), glm::vec3(static_cast<float>(pose[3]), static_cast<float>(pose[4]), static_cast<float>(pose[5])));
1026 model[3][0] =
static_cast<float>(pose[0]);
1027 model[3][1] =
static_cast<float>(pose[1]);
1028 model[3][2] =
static_cast<float>(pose[2]);
1030 auto iter_model = model_obj_.find(pair.first);
1031 if (iter_model != model_obj_.end())
1033 if ((iter_model->second)->has_texture())
1035 shader_mesh_texture_->install();
1036 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
1038 (iter_model->second)->Draw(*shader_mesh_texture_);
1040 shader_mesh_texture_->uninstall();
1044 shader_cad_->install();
1045 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
1047 (iter_model->second)->Draw(*shader_cad_);
1049 shader_cad_->uninstall();
1052 else if (pair.first ==
"frame")
1054 shader_frame_->install();
1055 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
1056 glBindVertexArray(vao_frame_);
1057 glDrawArrays(GL_LINES, 0, 6);
1058 glBindVertexArray(0);
1059 shader_frame_->uninstall();
1065 glReadBuffer(GL_COLOR_ATTACHMENT0);
1066 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[pbo_index]);
1067 glReadPixels(0, 0, framebuffer_width_, framebuffer_height_, GL_BGR, GL_UNSIGNED_BYTE, 0);
1070 glfwSwapBuffers(window_);
1074 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1075 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1083 const std::vector<ModelPoseContainer>& objpos_multimap,
1084 const double* cam_x,
1085 const double* cam_o,
1086 const size_t pbo_index,
1090 if (!(pbo_index < pbo_number_))
1092 std::cerr <<
"ERROR::SICAD::SUPERIMPOSE\nERROR:\n\tSICAD PBO index out of bound." << std::endl;
1098 const int objpos_num = objpos_multimap.size();
1099 if (objpos_num != tiles_num_)
return false;
1101 glfwMakeContextCurrent(window_);
1103 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
1106 glm::mat4 view = getViewTransformationMatrix(cam_x, cam_o);
1109 shader_cad_->install();
1110 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
1111 shader_cad_->uninstall();
1113 shader_mesh_texture_->install();
1114 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
1115 shader_mesh_texture_->uninstall();
1117 shader_frame_->install();
1118 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"view"), 1, GL_FALSE, glm::value_ptr(view));
1119 shader_frame_->uninstall();
1121 for (
unsigned int i = 0; i < tiles_rows_; ++i)
1123 for (
unsigned int j = 0; j < tiles_cols_; ++j)
1126 int idx = i * tiles_cols_ + j;
1129 glViewport(tile_img_width_ * j, framebuffer_height_ - (tile_img_height_ * (i + 1)),
1130 tile_img_width_, tile_img_height_ );
1131 glScissor (tile_img_width_ * j, framebuffer_height_ - (tile_img_height_ * (i + 1)),
1132 tile_img_width_, tile_img_height_ );
1135 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1136 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1139 if (getBackgroundOpt())
1140 renderBackground(img);
1143 setWireframe(getWireframeOpt());
1148 const double* pose = pair.second.data();
1150 glm::mat4 model = glm::rotate(glm::mat4(1.0f), static_cast<float>(pose[6]), glm::vec3(static_cast<float>(pose[3]), static_cast<float>(pose[4]), static_cast<float>(pose[5])));
1151 model[3][0] =
static_cast<float>(pose[0]);
1152 model[3][1] =
static_cast<float>(pose[1]);
1153 model[3][2] =
static_cast<float>(pose[2]);
1155 auto iter_model = model_obj_.find(pair.first);
1156 if (iter_model != model_obj_.end())
1158 if ((iter_model->second)->has_texture())
1160 shader_mesh_texture_->install();
1161 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
1163 (iter_model->second)->Draw(*shader_mesh_texture_);
1165 shader_mesh_texture_->uninstall();
1169 shader_cad_->install();
1170 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
1172 (iter_model->second)->Draw(*shader_cad_);
1174 shader_cad_->uninstall();
1177 else if (pair.first ==
"frame")
1179 shader_frame_->install();
1180 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"model"), 1, GL_FALSE, glm::value_ptr(model));
1181 glBindVertexArray(vao_frame_);
1182 glDrawArrays(GL_LINES, 0, 6);
1183 glBindVertexArray(0);
1184 shader_frame_->uninstall();
1190 glReadBuffer(GL_COLOR_ATTACHMENT0);
1191 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[pbo_index]);
1192 glReadPixels(0, 0, framebuffer_width_, framebuffer_height_, GL_BGR, GL_UNSIGNED_BYTE, 0);
1195 glfwSwapBuffers(window_);
1199 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1200 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1208 glfwMakeContextCurrent(
nullptr);
1214 glfwMakeContextCurrent(
window_);
1224 glfwMakeContextCurrent(
window_);
1226 return std::make_pair(
true,
pbo_[pbo_index]);
1229 return std::make_pair(
false, 0);
1235 const GLsizei cam_width,
1236 const GLsizei cam_height,
1237 const GLfloat cam_fx,
1238 const GLfloat cam_fy,
1239 const GLfloat cam_cx,
1240 const GLfloat cam_cy
1243 glfwMakeContextCurrent(window_);
1266 projection_ = glm::mat4(2.0f*(cam_fx/cam_width), 0, 0, 0,
1267 0, 2.0f*(cam_fy/cam_height), 0, 0,
1268 1-2.0f*(cam_cx/cam_width), 2.0f*(cam_cy/cam_height)-1, -(far_+near_)/(far_-near_), -1,
1269 0, 0, -2.0f*(far_*near_)/(far_-near_), 0 );
1272 shader_cad_->install();
1273 glUniformMatrix4fv(glGetUniformLocation(shader_cad_->get_program(),
"projection"), 1, GL_FALSE, glm::value_ptr(projection_));
1274 shader_cad_->uninstall();
1276 shader_mesh_texture_->install();
1277 glUniformMatrix4fv(glGetUniformLocation(shader_mesh_texture_->get_program(),
"projection"), 1, GL_FALSE, glm::value_ptr(projection_));
1278 shader_mesh_texture_->uninstall();
1280 shader_frame_->install();
1281 glUniformMatrix4fv(glGetUniformLocation(shader_frame_->get_program(),
"projection"), 1, GL_FALSE, glm::value_ptr(projection_));
1282 shader_frame_->uninstall();
1284 glfwSwapBuffers(window_);
1285 glfwMakeContextCurrent(
nullptr);
1348 glm::mat4 root_cam_t = glm::translate(glm::mat4(1.0f),
1349 glm::vec3(static_cast<float>(cam_x[0]), static_cast<float>(cam_x[1]), static_cast<float>(cam_x[2])));
1350 glm::mat4 cam_to_root = glm::rotate(glm::mat4(1.0f),
1351 static_cast<float>(cam_o[3]), glm::vec3(static_cast<float>(cam_o[0]), static_cast<float>(cam_o[1]), static_cast<float>(cam_o[2])));
1353 glm::mat4 view = glm::lookAt(glm::vec3(root_cam_t[3].x, root_cam_t[3].y, root_cam_t[3].z),
1354 glm::vec3(root_cam_t[3].x, root_cam_t[3].y, root_cam_t[3].z) + glm::mat3(cam_to_root) *
ogl_to_cam_ * glm::vec3(0.0f, 0.0f, -1.0f),
1355 glm::mat3(cam_to_root) *
ogl_to_cam_ * glm::vec3(0.0f, 1.0f, 0.0f));
1366 glfwPostEmptyEvent();
1378 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1379 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1383 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1384 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1387 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.cols, img.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, img.data);
1388 glGenerateMipmap(GL_TEXTURE_2D);
1390 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1397 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
1398 glBindVertexArray(0);
1400 glBindTexture(GL_TEXTURE_2D, 0);
1407 glPolygonMode(GL_FRONT_AND_BACK, mode);
1414 const GLsizei width_limit,
1415 const GLsizei height_limit,
1420 double sqrt_area = std::floor(std::sqrt(static_cast<double>(area)));
1421 height = std::min(static_cast<int>(sqrt_area), height_limit);
1422 width = std::min(area / height, width_limit);
std::unordered_map< std::string, std::string > ModelPathContainer
GLuint texture_background_
void install()
Activate the shader program.
ModelContainer model_obj_
void renderBackground(const cv::Mat &img) const
std::pair< std::string, std::string > ModelPathElement
Shader * shader_background_
static int class_counter_
void setBackgroundOpt(bool show_background)
std::thread::id main_thread_id_
int getTilesNumber() const
bool getBackgroundOpt() const
std::pair< bool, GLuint > getPBO(const size_t pbo_index) const
Returns pbo_index-th Pixel Buffer Object (PBO) value.
static GLsizei renderbuffer_size_
std::pair< std::string, Model * > ModelElement
SICAD(const ModelPathContainer &objfile_map, const GLsizei cam_width, const GLsizei cam_height, const GLfloat cam_fx, const GLfloat cam_fy, const GLfloat cam_cx, const GLfloat cam_cy)
Create a SICAD object with a dedicated OpenGL context and default shaders.
bool setProjectionMatrix(const GLsizei cam_width, const GLsizei cam_height, const GLfloat cam_fx, const GLfloat cam_fy, const GLfloat cam_cx, const GLfloat cam_cy)
void setWireframeOpt(bool show_mesh_wires)
bool superimpose(const ModelPoseContainer &objpos_map, const double *cam_x, const double *cam_o, cv::Mat &img) override
Render the mesh models in the pose specified in objpos_map and move the virtual camera in cam_x posit...
void setOglWindowShouldClose(bool should_close)
std::pair< std::string, ModelPose > ModelPoseContainerElement
GLenum getWireframeOpt() const
A Superimpose derived class to superimpose mesh models on images.
bool getOglWindowShouldClose()
std::multimap< std::string, ModelPose > ModelPoseContainer
GLuint texture_depth_buffer_
void setWireframe(GLenum mode)
glm::mat4 getViewTransformationMatrix(const double *cam_x, const double *cam_o)
virtual void releaseContext() const
Make the current thread OpenGL context not current.
std::pair< const GLuint *, size_t > getPBOs() const
Returns the Pixel Buffer Object (PBO) vector and its size.
const GLuint get_program()
void setMipmapsOpt(const MIPMaps &mipmaps)
void factorize_int(const GLsizei area, const GLsizei width_limit, const GLsizei height_limit, GLsizei &width, GLsizei &height)
GLuint texture_color_buffer_
MIPMaps getMipmapsOpt() const
const std::string log_ID_
void uninstall()
Deactivate the shader program.