39 #include <OpenGL/glu.h> 44 #include <GL/freeglut.h> 51 #include <boost/thread.hpp> 98 throw runtime_error(
"near clipping plane distance needs to be larger than 0");
100 throw runtime_error(
"far clipping plane needs to be larger than near clipping plane distance");
120 glMatrixMode(GL_PROJECTION);
122 glFrustum(left, right, bottom, top,
near_,
far_);
124 glMatrixMode(GL_MODELVIEW);
126 gluLookAt(0, 0, 0, 0, 0, 1, 0, -1, 0);
132 glBindTexture(GL_TEXTURE_2D,
rgb_id_);
133 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
width_,
height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
134 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
135 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
138 glBindTexture(GL_TEXTURE_2D, 0);
142 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
width_,
height_, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
143 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
144 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
147 glBindTexture(GL_TEXTURE_2D, 0);
149 glGenFramebuffers(1, &
fbo_id_);
150 glBindFramebuffer(GL_FRAMEBUFFER,
fbo_id_);
151 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
rgb_id_, 0);
153 glGenRenderbuffers(1, &
rbo_id_);
154 glBindRenderbuffer(GL_RENDERBUFFER,
rbo_id_);
155 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
width_,
height_);
156 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
rbo_id_);
157 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
depth_id_, 0);
158 glBindRenderbuffer(GL_RENDERBUFFER, 0);
160 GLenum DrawBuffers[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
161 glDrawBuffers(2, DrawBuffers);
163 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
165 if (status != GL_FRAMEBUFFER_COMPLETE)
166 throw runtime_error(
"Couldn't create frame buffer");
168 glBindFramebuffer(GL_FRAMEBUFFER, 0);
174 glDeleteRenderbuffers(1, &
rbo_id_);
176 glDeleteFramebuffers(1, &
fbo_id_);
187 glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT);
188 glBindFramebuffer(GL_FRAMEBUFFER,
fbo_id_);
189 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
206 glBindFramebuffer(GL_FRAMEBUFFER, 0);
211 glBindFramebuffer(GL_FRAMEBUFFER,
fbo_id_);
212 glBindTexture(GL_TEXTURE_2D,
rgb_id_);
213 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
214 glBindFramebuffer(GL_FRAMEBUFFER, 0);
219 glBindFramebuffer(GL_FRAMEBUFFER,
fbo_id_);
221 glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
222 glBindFramebuffer(GL_FRAMEBUFFER, 0);
230 string vertex_source, fragment_source;
261 GLuint ShaderID = glCreateShader(shaderType);
264 char const* SourcePointer = ShaderCode.c_str();
265 glShaderSource(ShaderID, 1, &SourcePointer, NULL);
266 glCompileShader(ShaderID);
269 GLint Result = GL_FALSE;
270 glGetShaderiv(ShaderID, GL_COMPILE_STATUS, &Result);
271 if (Result != GL_TRUE)
274 glGetShaderiv(ShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
275 if (InfoLogLength > 0)
277 vector<char> ShaderErrorMessage(InfoLogLength + 1);
278 glGetShaderInfoLog(ShaderID, InfoLogLength, NULL, &ShaderErrorMessage[0]);
279 stringstream errorStream;
280 errorStream <<
"Could not compile shader: " << (
const char*)&ShaderErrorMessage[0];
282 glDeleteShader(ShaderID);
283 throw runtime_error(errorStream.str());
291 if (filename.empty())
296 fstream ShaderFile(filename.c_str(), ios::in);
297 if (ShaderFile.is_open())
300 buffer << ShaderFile.rdbuf();
301 shader = buffer.str();
305 stringstream errorStream;
306 errorStream <<
"Could not open shader code in file \"" << filename <<
"\"";
307 throw runtime_error(errorStream.str());
314 if (vertex_source.empty() && fragment_source.empty())
317 GLuint ProgramID = glCreateProgram();
318 GLuint VertexShaderID = 0;
319 GLuint FragmentShaderID = 0;
321 if (!vertex_source.empty())
323 GLuint VertexShaderID =
createShader(GL_VERTEX_SHADER, vertex_source);
324 glAttachShader(ProgramID, VertexShaderID);
327 if (!fragment_source.empty())
329 GLuint FragmentShaderID =
createShader(GL_FRAGMENT_SHADER, fragment_source);
330 glAttachShader(ProgramID, FragmentShaderID);
333 glLinkProgram(ProgramID);
336 GLint Result = GL_FALSE;
338 glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
339 glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
340 if (InfoLogLength > 0)
342 vector<char> ProgramErrorMessage(InfoLogLength + 1);
343 glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
344 std::size_t l = strnlen(&ProgramErrorMessage[0], ProgramErrorMessage.size());
346 ROS_ERROR(
"%s\n", &ProgramErrorMessage[0]);
350 glDeleteShader(VertexShaderID);
352 if (FragmentShaderID)
353 glDeleteShader(FragmentShaderID);
364 void nullDisplayFunction(){};
377 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
382 boost::thread::id threadID = boost::this_thread::get_id();
383 map<boost::thread::id, pair<unsigned, GLuint> >::iterator contextIt =
context_.find(threadID);
387 context_[threadID] = std::pair<unsigned, GLuint>(1, 0);
389 glutInitWindowPosition(glutGet(GLUT_SCREEN_WIDTH) + 30000, 0);
390 glutInitWindowSize(1, 1);
391 GLuint window_id = glutCreateWindow(
"mesh_filter");
392 glutDisplayFunc(nullDisplayFunction);
394 GLenum err = glewInit();
397 stringstream errorStream;
398 errorStream <<
"Unable to initialize GLEW: " << glewGetErrorString(err);
400 throw(runtime_error(errorStream.str()));
405 for (
int i = 0; i < 10; ++i)
408 context_[threadID] = std::pair<unsigned, GLuint>(1, window_id);
411 ++(contextIt->second.first);
417 boost::thread::id threadID = boost::this_thread::get_id();
418 map<boost::thread::id, pair<unsigned, GLuint> >::iterator contextIt =
context_.find(threadID);
421 stringstream errorMsg;
422 errorMsg <<
"No OpenGL context exists for Thread " << threadID;
423 throw runtime_error(errorMsg.str());
426 if (--(contextIt->second.first) == 0)
428 glutDestroyWindow(contextIt->second.second);
void getDepthBuffer(float *buffer) const
retrieves the depth buffer from OpenGL
const GLuint & getProgramID() const
GLuint loadShaders(const std::string &vertex_source, const std::string &fragment_source) const
Compiles, Links and adds the GLSL shaders from strings containing the source codes.
GLuint rgb_id_
handle to color buffer
float far_
distance of far clipping plane in meters
float fy_
focal length in y-direction of camera in pixels
static bool glutInitialized_
GLuint rbo_id_
handle to render buffer object
void callList(GLuint list) const
executes a OpenGL list
unsigned height_
height of frame buffer objects in pixels
const float & getFarClippingDistance() const
returns the distance of the far clipping plane in meters
GLuint setShadersFromString(const std::string &vertex_shader, const std::string &fragment_shader)
loads, compiles, links and adds GLSL shaders from string to the current OpenGL context.
void deleteFrameBuffers()
deletes the frame buffer objects
const unsigned getWidth() const
returns the width of the frame buffer objectsin pixels
const float & getNearClippingDistance() const
returns the distance of the near clipping plane in meters
GLuint fbo_id_
handle to frame buffer object
void initFrameBuffers()
initializes the frame buffer objects
float cx_
x-coordinate of principal point of camera in pixels
GLuint depth_id_
handle to depth buffer
static void deleteGLContext()
deletes OpenGL context for the current thread
float near_
distance of near clipping plane in meters
GLuint getColorTexture() const
returns the handle of the color buffer as an OpenGL texture object
void end() const
finalizes the frame buffers after rendering and/or manipulating
~GLRenderer()
destructor, destroys frame buffer objects and OpenGL context
GLuint createShader(GLuint shaderID, const std::string &source) const
create a OpenGL shader object from the shader source code
GLuint setShadersFromFile(const std::string &vertex_filename, const std::string &fragment_filename)
loads, compiles, links and adds GLSL shaders from files to the current OpenGL context.
static void createGLContext()
create the OpenGL context if required. Only on context is created for each thread ...
void setCameraParameters() const
sets the OpenGL camera parameters
void readShaderCodeFromFile(const std::string &filename, std::string &source) const
reads shader source code from file to a string
void begin() const
initializes the frame buffers for rendering and or manipulating
GLRenderer(unsigned width, unsigned height, float near=0.1, float far=10.0)
constructs the frame buffer object in a new OpenGL context.
static boost::mutex context_lock_
static std::map< boost::thread::id, std::pair< unsigned, GLuint > > context_
map from thread id to OpenGL context
const unsigned getHeight() const
returns the height of the frame buffer objects in pixels
float cy_
y-coordinate of principal point of camera in pixels
GLuint getDepthTexture() const
returns the handle of the depth buffer as an OpenGL texture object
GLuint program_
handle to program that is currently used
void setBufferSize(unsigned width, unsigned height)
set the size of fram buffers
float fx_
focal length in x-direction of camera in pixels
void setClippingRange(float near, float far)
sets the near and far clipping plane distances in meters
unsigned width_
width of frame buffer objects in pixels
void getColorBuffer(unsigned char *buffer) const
retrieves the color buffer from OpenGL