MRPT  1.9.9
CFBORender.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
12 #include <mrpt/opengl/CFBORender.h>
13 #include <mrpt/opengl/opengl_api.h>
14 
15 using namespace std;
16 using namespace mrpt;
17 using namespace mrpt::opengl;
18 using mrpt::img::CImage;
19 
20 /*---------------------------------------------------------------
21  Constructor
22 ---------------------------------------------------------------*/
23 CFBORender::CFBORender(
24  unsigned int width, unsigned int height, const bool skip_glut_window)
25  : m_width(width),
26  m_height(height),
27  m_win_used(!skip_glut_window),
28  m_default_bk_color(.6f, .6f, .6f, 1)
29 {
30 #if MRPT_HAS_OPENCV && MRPT_HAS_OPENGL_GLUT
31 
33 
34  if (m_win_used)
35  {
36  // check a previous initialization of the GLUT
37  if (!glutGet(GLUT_INIT_STATE))
38  {
39  // create the context (a little trick)
40  int argc = 1;
41  char* argv[1] = {nullptr};
42  glutInit(&argc, argv);
43  }
44 
45  // create a hidden window
46  m_win = glutCreateWindow("CFBORender");
47  glutHideWindow();
48  }
49 
50  // call after creating the hidden window
51  if (!isExtensionSupported("GL_EXT_framebuffer_object"))
52  THROW_EXCEPTION("Framebuffer Object extension unsupported");
53 
54 // In win32 we have to load the pointers to the functions:
55 #ifdef _WIN32
56  glGenFramebuffersEXT =
57  (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
58  glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress(
59  "glDeleteFramebuffersEXT");
60  glBindFramebufferEXT =
61  (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
62  glFramebufferTexture2DEXT =
63  (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress(
64  "glFramebufferTexture2DEXT");
65 
66  ASSERT_(glGenFramebuffersEXT != nullptr);
67  ASSERT_(glDeleteFramebuffersEXT != nullptr);
68  ASSERT_(glBindFramebufferEXT != nullptr);
69  ASSERT_(glFramebufferTexture2DEXT != nullptr);
70 #endif
71 
72  // gen the frambuffer object (FBO), similar manner as a texture
73  glGenFramebuffersEXT(1, &m_fbo);
74 
75  // bind the framebuffer, fbo, so operations will now occur on it
76  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
77 
78  // change viewport size (in pixels)
79  glViewport(0, 0, m_width, m_height);
80 
81  // make a texture
82  glGenTextures(1, &m_tex);
83 
84  // initialize texture that will store the framebuffer image
85  const GLenum texTarget =
86 #if defined(GL_TEXTURE_RECTANGLE_NV)
87  GL_TEXTURE_RECTANGLE_NV;
88 #elif defined(GL_TEXTURE_RECTANGLE_ARB)
89  GL_TEXTURE_RECTANGLE_ARB;
90 #else
91  GL_TEXTURE_RECTANGLE_EXT;
92 #endif
93 
94  glBindTexture(texTarget, m_tex);
95  glTexImage2D(
96  texTarget, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE,
97  nullptr);
98 
99  // bind this texture to the current framebuffer obj. as color_attachement_0
100  glFramebufferTexture2DEXT(
101  GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texTarget, m_tex, 0);
102 
103  //'unbind' the frambuffer object, so subsequent drawing ops are not drawn
104  // into the FBO.
105  // '0' means "windowing system provided framebuffer
106  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
107 
108  MRPT_END
109 
110 //#else
111 // THROW_EXCEPTION("MRPT compiled without OpenCV and/or OpenGL support!!");
112 #endif
113 }
114 
115 /*---------------------------------------------------------------
116  Destructor:
117  ---------------------------------------------------------------*/
119 {
120 #if MRPT_HAS_OPENGL_GLUT
121  // delete the current texture, the framebuffer object and the GLUT window
122  glDeleteTextures(1, &m_tex);
123  glDeleteFramebuffersEXT(1, &m_fbo);
124  if (m_win_used) glutDestroyWindow(m_win);
125 #endif
126 }
127 
128 /*---------------------------------------------------------------
129  Set the scene camera
130  ---------------------------------------------------------------*/
131 void CFBORender::setCamera(const COpenGLScene& scene, const CCamera& camera)
132 {
133  MRPT_START
134 
135  scene.getViewport("main")->getCamera() = camera;
136 
137  MRPT_END
138 }
139 
140 /*---------------------------------------------------------------
141  Get the scene camera
142  ---------------------------------------------------------------*/
144 {
145  MRPT_START
146 
147  return scene.getViewport("main")->getCamera();
148 
149  MRPT_END
150 }
151 
152 /*---------------------------------------------------------------
153  Render the scene and get the rendered rgb image. This
154  function resizes the image buffer if it is necessary
155  ---------------------------------------------------------------*/
156 void CFBORender::getFrame(const COpenGLScene& scene, CImage& buffer)
157 {
158 #if MRPT_HAS_OPENCV && MRPT_HAS_OPENGL_GLUT
159 
160  MRPT_START
161 
162  // resize the buffer if it is necessary
163  if (buffer.getWidth() != static_cast<size_t>(m_width) ||
164  buffer.getHeight() != static_cast<size_t>(m_height) ||
165  buffer.getChannelCount() != 3 || buffer.isOriginTopLeft() != false)
166  {
168  }
169 
170  // Go on.
171  getFrame2(scene, buffer);
172  ;
173 
174  MRPT_END
175 #else
176  MRPT_UNUSED_PARAM(scene);
177  MRPT_UNUSED_PARAM(buffer);
178 #endif
179 }
180 
181 /*---------------------------------------------------------------
182  Render the scene and get the rendered rgb image. This
183  function does not resize the image buffer.
184  ---------------------------------------------------------------*/
185 void CFBORender::getFrame2(const COpenGLScene& scene, CImage& buffer)
186 {
187 #if MRPT_HAS_OPENGL_GLUT
188 
189  MRPT_START
190 
191  // check the buffer size
192  ASSERT_EQUAL_(buffer.getWidth(), static_cast<size_t>(m_width));
193  ASSERT_EQUAL_(buffer.getHeight(), static_cast<size_t>(m_height));
194  ASSERT_EQUAL_(buffer.getChannelCount(), 3);
195  ASSERT_EQUAL_(buffer.isOriginTopLeft(), false);
196  // bind the framebuffer, fbo, so operations will now occur on it
197  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
198 
199  glClearColor(
202 
203  // Render opengl objects:
204  // ---------------------------
205  scene.render();
206 
207  // TODO NOTE: This should fail if the image has padding bytes. See
208  // glPixelStore() etc.
209  glReadPixels(
210  0, 0, m_width, m_height, GL_BGR_EXT, GL_UNSIGNED_BYTE, buffer(0, 0));
211 
212  //'unbind' the frambuffer object, so subsequent drawing ops are not drawn
213  // into the FBO.
214  // '0' means "windowing system provided framebuffer
215  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
216 
217  MRPT_END
218 #else
219  MRPT_UNUSED_PARAM(scene);
220  MRPT_UNUSED_PARAM(buffer);
221 #endif
222 }
223 
224 /*---------------------------------------------------------------
225  Resize the image size
226  ---------------------------------------------------------------*/
227 void CFBORender::resize(unsigned int width, unsigned int height)
228 {
229 #if MRPT_HAS_OPENCV && MRPT_HAS_OPENGL_GLUT
230 
231  MRPT_START
232 
233  // update members
234  m_width = width;
235  m_height = height;
236 
237  // bind the framebuffer, fbo, so operations will now occur on it
238  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
239 
240  // change viewport size (in pixels)
241  glViewport(0, 0, m_width, m_height);
242 
243  // change texture size
244  const GLenum texTarget =
245 #if defined(GL_TEXTURE_RECTANGLE_NV)
246  GL_TEXTURE_RECTANGLE_NV;
247 #elif defined(GL_TEXTURE_RECTANGLE_ARB)
248  GL_TEXTURE_RECTANGLE_ARB;
249 #else
250  GL_TEXTURE_RECTANGLE_EXT;
251 #endif
252 
253  glBindTexture(texTarget, m_tex);
254  glTexImage2D(
255  texTarget, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE,
256  nullptr);
257 
258  //'unbind' the frambuffer object, so subsequent drawing ops are not drawn
259  // into the FBO.
260  // '0' means "windowing system provided framebuffer
261  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
262 
263  MRPT_END
264 
265 //#else
266 // THROW_EXCEPTION("MRPT compiled without OpenCV and/or OpenGL support!!");
267 #else
268  MRPT_UNUSED_PARAM(width);
269  MRPT_UNUSED_PARAM(height);
270 #endif
271 }
272 
273 /*---------------------------------------------------------------
274  Provide information on Framebuffer object extension
275  ---------------------------------------------------------------*/
276 int CFBORender::isExtensionSupported(const char* extension)
277 {
278 #if MRPT_HAS_OPENGL_GLUT
279 
280  MRPT_START
281 
282  /* Extension names should not have spaces. */
283  auto where = strchr(extension, ' ');
284  if (where || *extension == '\0') return 0;
285  const auto extensions = glGetString(GL_EXTENSIONS);
286 
287  /* It takes a bit of care to be fool-proof about parsing the
288  OpenGL extensions string. Don't be fooled by sub-strings,
289  etc. */
290  auto start = reinterpret_cast<const char*>(extensions);
291  for (;;)
292  {
293  where = strstr(start, extension);
294  if (!where) break;
295  auto terminator = where + strlen(extension);
296  if (where == start || *(where - 1) == ' ')
297  if (*terminator == ' ' || *terminator == '\0') return 1;
298  start = terminator;
299  }
300 
301  MRPT_END
302 #else
303  MRPT_UNUSED_PARAM(extension);
304 #endif
305 
306  return 0;
307 }
#define MRPT_START
Definition: exceptions.h:241
int isExtensionSupported(const char *extension)
Provide information on Framebuffer object extension.
Definition: CFBORender.cpp:276
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
TImageChannels getChannelCount() const
Returns the number of channels, typically 1 (GRAY) or 3 (RGB)
Definition: CImage.cpp:878
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:849
void getFrame(const COpenGLScene &scene, mrpt::img::CImage &image)
Render the scene and get the rendered rgb image.
Definition: CFBORender.cpp:156
STL namespace.
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
mrpt::img::CImage CImage
Definition: utils/CImage.h:5
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:818
void resize(std::size_t width, std::size_t height, TImageChannels nChannels, PixelDepth depth=PixelDepth::D8U)
Changes the size of the image, erasing previous contents (does NOT scale its current content...
Definition: CImage.cpp:247
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
Definition: exceptions.h:137
CCamera & getCamera(const COpenGLScene &scene)
Get a reference to the scene camera.
Definition: CFBORender.cpp:143
virtual ~CFBORender()
Destructor.
Definition: CFBORender.cpp:118
void getFrame2(const COpenGLScene &scene, mrpt::img::CImage &image)
Render the scene and get the rendered rgb image.
Definition: CFBORender.cpp:185
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
const char * argv[]
COpenGLViewport::Ptr getViewport(const std::string &viewportName=std::string("main")) const
Returns the viewport with the given name, or nullptr if it does not exist; note that the default view...
void setCamera(const COpenGLScene &scene, const CCamera &camera)
Change the scene camera.
Definition: CFBORender.cpp:131
bool isOriginTopLeft() const
Returns true (as of MRPT v2.0.0, it&#39;s fixed)
Definition: CImage.cpp:888
void resize(unsigned int width, unsigned int height)
Resize the rendering canvas size.
Definition: CFBORender.cpp:227
void render() const
Render this scene.
#define MRPT_END
Definition: exceptions.h:245
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:56
const int argc
mrpt::img::TColorf m_default_bk_color
Definition: CFBORender.h:82
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:33
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:148
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 3a26b90fd Wed Mar 25 20:17:03 2020 +0100 at miƩ mar 25 23:05:41 CET 2020