39 #include <OpenGL/glu.h>
44 #include <GL/freeglut.h>
75 glDeleteProgram(program_);
82 if (width_ != width || height_ != height)
94 throw runtime_error(
"near clipping plane distance needs to be larger than 0");
96 throw runtime_error(
"far clipping plane needs to be larger than near clipping plane distance");
111 float left = near_ * -cx_ / fx_;
112 float right = near_ * (width_ - cx_) / fx_;
113 float top = near_ * cy_ / fy_;
114 float bottom = near_ * (cy_ - height_) / fy_;
116 glMatrixMode(GL_PROJECTION);
118 glFrustum(left, right, bottom, top, near_, far_);
120 glMatrixMode(GL_MODELVIEW);
122 gluLookAt(0, 0, 0, 0, 0, 1, 0, -1, 0);
127 glGenTextures(1, &rgb_id_);
128 glBindTexture(GL_TEXTURE_2D, rgb_id_);
129 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
130 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
131 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
134 glBindTexture(GL_TEXTURE_2D, 0);
136 glGenTextures(1, &depth_id_);
137 glBindTexture(GL_TEXTURE_2D, depth_id_);
138 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width_, height_, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
nullptr);
139 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
140 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
143 glBindTexture(GL_TEXTURE_2D, 0);
145 glGenFramebuffers(1, &fbo_id_);
146 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
147 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgb_id_, 0);
149 glGenRenderbuffers(1, &rbo_id_);
150 glBindRenderbuffer(GL_RENDERBUFFER, rbo_id_);
151 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width_, height_);
152 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_id_);
153 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_id_, 0);
154 glBindRenderbuffer(GL_RENDERBUFFER, 0);
156 GLenum draw_buffers[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
157 glDrawBuffers(2, draw_buffers);
159 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
161 if (status != GL_FRAMEBUFFER_COMPLETE)
162 throw runtime_error(
"Couldn't create frame buffer");
164 glBindFramebuffer(GL_FRAMEBUFFER, 0);
170 glDeleteRenderbuffers(1, &rbo_id_);
172 glDeleteFramebuffers(1, &fbo_id_);
174 glDeleteTextures(1, &depth_id_);
176 glDeleteTextures(1, &rgb_id_);
178 rbo_id_ = fbo_id_ = depth_id_ = rgb_id_ = 0;
183 glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT | GL_PIXEL_MODE_BIT);
184 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
185 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
186 glViewport(0, 0, width_, height_);
187 glUseProgram(program_);
188 setCameraParameters();
202 glBindFramebuffer(GL_FRAMEBUFFER, 0);
207 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
208 glBindTexture(GL_TEXTURE_2D, rgb_id_);
209 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
210 glBindFramebuffer(GL_FRAMEBUFFER, 0);
215 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
216 glBindTexture(GL_TEXTURE_2D, depth_id_);
217 glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
218 glBindFramebuffer(GL_FRAMEBUFFER, 0);
224 glDeleteProgram(program_);
226 string vertex_source, fragment_source;
227 readShaderCodeFromFile(vertex_filename, vertex_source);
228 readShaderCodeFromFile(fragment_filename, fragment_source);
230 program_ = loadShaders(vertex_source, fragment_source);
236 program_ = loadShaders(vertex_source, fragment_source);
257 GLuint shader_id = glCreateShader(shaderType);
260 char const* source_pointer = ShaderCode.c_str();
261 glShaderSource(shader_id, 1, &source_pointer,
nullptr);
262 glCompileShader(shader_id);
265 GLint result = GL_FALSE;
266 glGetShaderiv(shader_id, GL_COMPILE_STATUS, &result);
267 if (result != GL_TRUE)
270 glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &info_log_length);
271 if (info_log_length > 0)
273 vector<char> shader_error_message(info_log_length + 1);
274 glGetShaderInfoLog(shader_id, info_log_length,
nullptr, &shader_error_message[0]);
275 stringstream error_stream;
276 error_stream <<
"Could not compile shader: " << (
const char*)&shader_error_message[0];
278 glDeleteShader(shader_id);
279 throw runtime_error(error_stream.str());
287 if (filename.empty())
292 fstream shader_file(filename.c_str(), ios::in);
293 if (shader_file.is_open())
296 buffer << shader_file.rdbuf();
297 shader = buffer.str();
301 stringstream error_stream;
302 error_stream <<
"Could not open shader code in file \"" << filename <<
"\"";
303 throw runtime_error(error_stream.str());
310 if (vertex_source.empty() && fragment_source.empty())
313 GLuint program_id = glCreateProgram();
314 GLuint vertex_shader_id = 0;
315 GLuint fragment_shader_id = 0;
317 if (!vertex_source.empty())
319 GLuint vertex_shader_id = createShader(GL_VERTEX_SHADER, vertex_source);
320 glAttachShader(program_id, vertex_shader_id);
323 if (!fragment_source.empty())
325 GLuint fragment_shader_id = createShader(GL_FRAGMENT_SHADER, fragment_source);
326 glAttachShader(program_id, fragment_shader_id);
329 glLinkProgram(program_id);
332 GLint result = GL_FALSE;
333 GLint info_log_length;
334 glGetProgramiv(program_id, GL_LINK_STATUS, &result);
335 glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &info_log_length);
336 if (info_log_length > 0)
338 vector<char> program_error_message(info_log_length + 1);
339 glGetProgramInfoLog(program_id, info_log_length,
nullptr, &program_error_message[0]);
340 std::size_t l = strnlen(&program_error_message[0], program_error_message.size());
342 ROS_ERROR(
"%s\n", &program_error_message[0]);
345 if (vertex_shader_id)
346 glDeleteShader(vertex_shader_id);
348 if (fragment_shader_id)
349 glDeleteShader(fragment_shader_id);
360 void nullDisplayFunction(){};
365 std::unique_lock<std::mutex> _(context_lock_);
366 if (!glutInitialized_)
373 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
374 glutInitialized_ =
true;
378 std::thread::id thread_id = std::this_thread::get_id();
379 map<std::thread::id, pair<unsigned, GLuint> >::iterator context_it = context_.find(thread_id);
381 if (context_it == context_.end())
383 context_[thread_id] = std::pair<unsigned, GLuint>(1, 0);
385 glutInitWindowPosition(glutGet(GLUT_SCREEN_WIDTH) + 30000, 0);
386 glutInitWindowSize(1, 1);
387 GLuint window_id = glutCreateWindow(
"mesh_filter");
388 glutDisplayFunc(nullDisplayFunction);
390 GLenum err = glewInit();
393 stringstream error_stream;
394 error_stream <<
"Unable to initialize GLEW: " << glewGetErrorString(err);
396 throw(runtime_error(error_stream.str()));
401 for (
int i = 0; i < 10; ++i)
404 context_[thread_id] = std::pair<unsigned, GLuint>(1, window_id);
407 ++(context_it->second.first);
412 std::unique_lock<std::mutex> _(context_lock_);
413 std::thread::id thread_id = std::this_thread::get_id();
414 map<std::thread::id, pair<unsigned, GLuint> >::iterator context_it = context_.find(thread_id);
415 if (context_it == context_.end())
417 stringstream error_msg;
418 error_msg <<
"No OpenGL context exists for Thread " << thread_id;
419 throw runtime_error(error_msg.str());
422 if (--(context_it->second.first) == 0)
424 glutDestroyWindow(context_it->second.second);
425 context_.erase(context_it);