align-gl.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2017 Intel Corporation. All Rights Reserved.
3 
7 
8 #include "../proc/synthetic-stream.h"
9 #include "align-gl.h"
10 #include "option.h"
11 #include "rendering.h"
12 
13 
14 #ifndef NOMINMAX
15 #define NOMINMAX
16 #endif // NOMINMAX
17 
18 #include <glad/glad.h>
19 
20 #include <iostream>
21 
22 #include <chrono>
23 #include <strstream>
24 
25 #include "synthetic-stream-gl.h"
26 
27 using namespace rs2;
28 using namespace librealsense::gl;
29 
30 rs2_extension align_gl::select_extension(const rs2::frame& input)
31 {
33  return ext;
34 }
35 
36 void align_gl::cleanup_gpu_resources()
37 {
38  _renderer.reset();
39  _pc.reset();
40  _other_texture.reset();
41  _upload.reset();
42  _enabled = 0;
43 }
44 
45 void align_gl::create_gpu_resources()
46 {
47  _renderer = std::make_shared<rs2::gl::pointcloud_renderer>();
48  _pc = std::make_shared<rs2::gl::pointcloud>();
49  _other_texture = std::make_shared<rs2::texture_buffer>();
50  _upload = std::make_shared<rs2::gl::uploader>();
51  _enabled = glsl_enabled() ? 1 : 0;
52 }
53 
54 void align_gl::align_z_to_other(rs2::video_frame& aligned,
55  const rs2::video_frame& depth,
57  float z_scale)
58 {
59  auto width = aligned.get_width();
60  auto height = aligned.get_height();
61 
62  _pc->map_to(depth);
63  auto p = _pc->calculate(depth);
64 
65  auto frame_ref = dynamic_cast<librealsense::depth_frame*>((librealsense::frame_interface*)aligned.get());
66  auto gf = dynamic_cast<gpu_addon_interface*>(frame_ref);
67 
69 
70  // Set the depth origin of new depth frame to the old depth frame
71  auto depth_ptr = dynamic_cast<librealsense::depth_frame*>((librealsense::frame_interface*)depth.get());
72  frame_ref->set_sensor(depth_ptr->get_sensor());
73  depth_ptr->acquire();
74  frame_holder h{ depth_ptr };
75  frame_ref->set_original(std::move(h));
76 
77  uint32_t aligned_tex;
78  auto format = depth.get_profile().format();
79  auto tex_type = rs_format_to_gl_format(format);
80  gf->get_gpu_section().output_texture(0, &aligned_tex, tex_type.type);
81  glTexImage2D(GL_TEXTURE_2D, 0, tex_type.internal_format,
82  width, height, 0, tex_type.gl_format, tex_type.data_type, nullptr);
83 
84  auto prof = depth.get_profile();
85  auto intr = other_profile.get_intrinsics();
86  auto extr = prof.get_extrinsics_to(other_profile);
87 
88  render(p, depth, intr, extr, aligned_tex);
89 
90  //aligned.get_data();
91  aligned = _upload->process(aligned);
92  aligned = _upload->process(aligned);
93 }
94 
95 // From: https://jamesgregson.blogspot.com/2011/11/matching-calibrated-cameras-with-opengl.html
97  int *viewport, double alpha, double beta, double skew,
98  double u0, double v0, int img_width, int img_height, double near_clip, double far_clip )
99 {
100 
101  // These parameters define the final viewport that is rendered into by
102  // the camera.
103  int L = 0;
104  int R = img_width;
105  int B = 0;
106  int T = img_height;
107 
108  // near and far clipping planes, these only matter for the mapping from
109  // world-space z-coordinate into the depth coordinate for OpenGL
110  double N = near_clip;
111  double F = far_clip;
112 
113  // set the viewport parameters
114  viewport[0] = L;
115  viewport[1] = B;
116  viewport[2] = R-L;
117  viewport[3] = T-B;
118 
119  // construct an orthographic matrix which maps from projected
120  // coordinates to normalized device coordinates in the range
121  // [-1, 1]. OpenGL then maps coordinates in NDC to the current
122  // viewport
123  matrix4 ortho;
124  ortho(0,0) = 2.f/(R-L); ortho(0,3) = float(-(R+L)/(R-L));
125  ortho(1,1) = 2.f/(T-B); ortho(1,3) = float(-(T+B)/(T-B));
126  ortho(2,2) = -2.f/float(F-N); ortho(2,3) = float(-(F+N)/(F-N));
127  ortho(3,3) = 1.f;
128 
129  // construct a projection matrix, this is identical to the
130  // projection matrix computed for the intrinsicx, except an
131  // additional row is inserted to map the z-coordinate to
132  // OpenGL.
133  matrix4 tproj;
134  tproj(0,0) = float(alpha); tproj(0,1) = float(skew); tproj(0,2) = 0.f;
135  tproj(1,1) = float(beta); tproj(1,2) = float(v0);
136  tproj(2,2) = float(-(N+F)); tproj(2,3) = float(-N*F);
137  tproj(3,2) = 1.f;
138 
139  // resulting OpenGL frustum is the product of the orthographic
140  // mapping to normalized device coordinates and the augmented
141  // camera intrinsic matrix
142  frustum = ortho*tproj;
143 }
144 
145 void align_gl::render(const rs2::points& model,
146  const rs2::video_frame& tex,
147  const rs2_intrinsics& intr,
148  const rs2_extrinsics& extr,
149  uint32_t output_texture)
150 {
151  perform_gl_action([&] {
152  auto width = intr.width;
153  auto height = intr.height;
154 
156  if (auto input_frame = tex.as<rs2::gl::gpu_frame>())
157  {
158  texture = input_frame.get_texture_id(0);
159  }
160  else
161  {
162  _other_texture->upload(tex, tex.get_profile().format());
163  texture = _other_texture->get_gl_handle();
164  }
165 
166  fbo fbo(width, height);
167 
168  glBindTexture(GL_TEXTURE_2D, output_texture);
169 
170  auto format = tex.get_profile().format();
171  auto textype = rs_format_to_gl_format(format);
172  glTexImage2D(GL_TEXTURE_2D, 0, textype.internal_format,
173  width, height, 0, textype.gl_format, textype.data_type, nullptr);
174 
179 
182 
183  glBindTexture(GL_TEXTURE_2D, output_texture);
184  fbo.createTextureAttachment(output_texture);
185 
186  fbo.bind();
187  glClearColor(0, 0, 0, 1);
189 
190  matrix4 projection;
191  int viewport[4];
192  build_opengl_projection_for_intrinsics(projection, viewport,
193  intr.fx, intr.fy, 0.0, intr.width - intr.ppx, intr.height - intr.ppy, width, height, 0.001, 100);
194  projection(3, 2) *= -1.f;
195  projection(2, 3) *= -1.f;
196  projection(2, 2) *= -1.f;
197  float pm[16];
198  projection.to_column_major(pm);
199  _renderer->set_matrix(RS2_GL_MATRIX_PROJECTION, pm);
201  view(2, 2) = -1.f;
202  _renderer->set_matrix(RS2_GL_MATRIX_CAMERA, (float*)&view.mat);
203 
204  matrix4 other = matrix4::identity();
205  for (int i = 0; i < 3; i++)
206  {
207  for (int j = 0; j < 3; j++)
208  other(i,j) = extr.rotation[i*3 + j];
209  other(3, i) = extr.translation[i];
210  }
211  _renderer->set_matrix(RS2_GL_MATRIX_TRANSFORMATION, (float*)&other.mat);
212 
213  glBindTexture(GL_TEXTURE_2D, texture);
214  _renderer->process(model);
215 
216  fbo.unbind();
217 
219  }, [&] {
220  _enabled = false;
221  });
222 }
223 
224 void align_gl::align_other_to_z(rs2::video_frame& aligned,
225  const rs2::video_frame& depth,
226  const rs2::video_frame& other,
227  float z_scale)
228 {
229  auto width = aligned.get_width();
230  auto height = aligned.get_height();
231 
232  _pc->map_to(other);
233  auto p = _pc->calculate(depth);
234 
235  auto frame_ref = (frame_interface*)aligned.get();
236  auto gf = dynamic_cast<gpu_addon_interface*>(frame_ref);
237 
238  uint32_t output_rgb;
239  auto format = other.get_profile().format();
240  auto tex_type = rs_format_to_gl_format(format);
241 
242  gf->get_gpu_section().output_texture(0, &output_rgb, tex_type.type);
243  glTexImage2D(GL_TEXTURE_2D, 0, tex_type.internal_format,
244  width, height, 0, tex_type.gl_format, tex_type.data_type, nullptr);
245 
246  gf->get_gpu_section().set_size(width, height);
247 
248  auto prof = depth.get_profile();
249  auto intr = prof.as<video_stream_profile>().get_intrinsics();
250  auto extr = prof.get_extrinsics_to(prof);
251  render(p, other, intr, extr, output_rgb);
252 }
253 
254 align_gl::align_gl(rs2_stream to_stream) : align(to_stream, "Align (GLSL)")
255 {
258 
259  auto opt = std::make_shared<librealsense::ptr_option<int>>(
260  0, 1, 0, 1, &_enabled, "GLSL enabled");
262 
263  initialize();
264 }
265 
267 {
268  perform_gl_action([&]()
269  {
271  }, []{});
272 }
#define GL_TEXTURE_MAG_FILTER
static matrix4 identity()
Definition: matrix4.h:25
void add_extension(rs2_extension ex)
Definition: source.h:45
#define GL_TEXTURE_2D
rs2_format format() const
Definition: rs_frame.hpp:44
void build_opengl_projection_for_intrinsics(matrix4 &frustum, int *viewport, double alpha, double beta, double skew, double u0, double v0, int img_width, int img_height, double near_clip, double far_clip)
Definition: align-gl.cpp:96
float translation[3]
Definition: rs_sensor.h:101
matrix4 frustum(float left, float right, float bottom, float top, float zNear, float zFar, float ox, float oy)
Definition: pc-shader.cpp:206
texture_mapping & rs_format_to_gl_format(rs2_format type)
#define GL_CLAMP_TO_EDGE
GLint GLint GLsizei GLsizei GLsizei depth
Definition: animated.h:9
bool is() const
Definition: rs_frame.hpp:572
GLfloat v0
#define glTexImage2D
float rotation[9]
Definition: rs_sensor.h:100
#define GL_TEXTURE_WRAP_T
void bind()
Definition: opengl3.cpp:638
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
GLfloat GLfloat GLfloat alpha
#define GL_COLOR_BUFFER_BIT
#define glBindFramebuffer
#define glTexParameteri
double p[GRIDW][GRIDH]
Definition: wave.c:109
unsigned int uint32_t
Definition: stdint.h:80
#define glClear
GLint GLsizei GLsizei height
GLint GLint GLsizei GLint GLenum format
void set_size(uint32_t width, uint32_t height, bool preloaded=false)
GLfloat beta
Definition: wave.c:31
void unbind()
Definition: opengl3.cpp:650
#define GL_TEXTURE_MIN_FILTER
T as() const
Definition: rs_frame.hpp:582
void cleanup_gpu_resources() override
Definition: align-gl.cpp:36
GLint j
float mat[4][4]
Definition: matrix4.h:18
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:42
int get_height() const
Definition: rs_frame.hpp:673
void set_sensor(std::shared_ptr< sensor_interface > s) override
Definition: frame.cpp:64
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
Definition: rs_sensor.h:98
int get_width() const
Definition: rs_frame.hpp:661
void createTextureAttachment(uint32_t texture)
Definition: opengl3.cpp:615
#define RS2_EXTENSION_VIDEO_FRAME_GL
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:166
rs2_extrinsics extr
Definition: test-pose.cpp:252
#define glBindTexture
void perform_gl_action(T action, S fallback)
virtual gpu_section & get_gpu_section()=0
typename ::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
Video stream intrinsics.
Definition: rs_types.h:58
#define glClearColor
#define RS2_EXTENSION_DEPTH_FRAME_GL
#define GL_COLOR_ATTACHMENT0
GLuint texture
int i
void to_column_major(float column_major[16])
Definition: matrix4.h:135
#define glDrawBuffer
uint32_t get() const
Definition: opengl3.h:330
#define GL_NEAREST
int h
Definition: sw.py:17
rs2_intrinsics get_intrinsics() const
Definition: rs_frame.hpp:240
#define GL_TEXTURE_WRAP_S
rs2_frame * get() const
Definition: rs_frame.hpp:592
#define GL_FRAMEBUFFER
GLint GLsizei width
stream_profile get_profile() const
Definition: rs_frame.hpp:559


librealsense2
Author(s): LibRealSense ROS Team
autogenerated on Thu Dec 22 2022 03:41:41