examples/gl/rs-gl.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015-2017 Intel Corporation. All Rights Reserved.
3 
4 #include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
5 #include "example.hpp" // Include short list of convenience functions for rendering
6 #include <librealsense2-gl/rs_processing_gl.hpp> // Include GPU-Processing API
7 
8 // Helper functions
9 void register_glfw_callbacks(window& app, glfw_state& app_state);
10 void prepare_matrices(glfw_state& app_state, float width, float height, float* projection, float* view);
11 bool handle_input(window& app, bool& use_gpu_processing);
12 // This helper class will be used to keep track of FPS and print instructions:
14 {
16  void print_instructions(window& app, bool use_gpu_processing);
17 
18  std::chrono::high_resolution_clock::time_point last_clock;
20  int last_fps;
21 };
22 
23 int main(int argc, char * argv[]) try
24 {
25  // The following toggle is going to control
26  // if we will use CPU or GPU for depth data processing
27  bool use_gpu_processing = true;
28 
29  // Create a simple OpenGL window for rendering:
30  window app(1280, 720, "RealSense GPU-Processing Example");
31 
32  // Once we have a window, initialize GL module
33  // Pass our window to enable sharing of textures between processed frames and the window
34  rs2::gl::init_processing(app, use_gpu_processing);
35  // Initialize rendering module:
37 
38  // Construct an object to manage view state
39  glfw_state app_state;
40  // register callbacks to allow manipulation of the pointcloud
41  register_glfw_callbacks(app, app_state);
42 
43  texture tex; // For when not using GPU frames, we will need standard texture object
44  // to render pointcloud texture (similar to pointcloud example)
45 
46  instructions_printer printer;
47 
48  // Every iteration the demo will render 3D pointcloud that will be stored in points object:
50  // The pointcloud will use colorized depth as a texture:
51  rs2::frame depth_texture;
52 
53  // ---- Declare GL processing blocks ----
54  rs2::gl::pointcloud pc; // similar to rs2::pointcloud
55  rs2::gl::colorizer colorizer; // similar to rs2::colorizer
56  rs2::gl::uploader upload; // used to explicitly copy frame to the GPU
57 
58  // ---- Declare rendering block ----
59  rs2::gl::pointcloud_renderer pc_renderer; // Will handle rendering points object to the screen
60 
61  // We will manage two matrices - projection and view
62  // to handle mouse input and perspective
63  float proj_matrix[16];
64  float view_matrix[16];
65 
66  // Enable pipeline
69  // For this example, we are only interested in depth:
71  pipe.start(cfg);
72 
73  while (app) // Application still alive?
74  {
75  // Any new frames?
77  if (pipe.poll_for_frames(&frames))
78  {
79  auto depth = frames.get_depth_frame();
80 
81  // Since both colorizer and pointcloud are going to use depth
82  // It helps to explicitly upload it to the GPU
83  // Otherwise, each block will upload the same depth to GPU separately
84  // [ This step is optional, but can speed things up on some cards ]
85  // The result of this step is still a rs2::depth_frame,
86  // but now it is also extendible to rs2::gl::gpu_frame
87  depth = upload.process(depth);
88 
89  // Apply color map with histogram equalization
90  depth_texture = colorizer.colorize(depth);
91 
92  // Tell pointcloud object to map to this color frame
93  pc.map_to(depth_texture);
94 
95  // Generate the pointcloud and texture mappings
96  points = pc.calculate(depth);
97  }
98 
99  // Populate projection and view matrices based on user input
100  prepare_matrices(app_state,
101  app.width(), app.height(),
102  proj_matrix, view_matrix);
103 
104  // We need to get OpenGL texture ID for pointcloud texture
105  uint32_t texture_id = 0;
106  // First, check if the frame is already a GPU-frame
107  if (auto gpu_frame = depth_texture.as<rs2::gl::gpu_frame>())
108  {
109  // If it is (and you have passed window for sharing to init_processing
110  // you can just get the texture ID of the GPU frame
111  texture_id = gpu_frame.get_texture_id(0);
112  }
113  else
114  {
115  // Otherwise, we need to upload texture like in all other examples
116  tex.upload(depth_texture);
117  texture_id = tex.get_gl_handle();
118  }
119 
120  // Clear screen
121  glClearColor(0.2f, 0.2f, 0.2f, 1.f);
123 
124  // We need Depth-Test unless you want pointcloud to intersect with itself
126 
127  // Set texture to our selected texture ID
129  glBindTexture(GL_TEXTURE_2D, texture_id);
130 
131  // Inform pointcloud-renderer of the projection and view matrices:
132  pc_renderer.set_matrix(RS2_GL_MATRIX_PROJECTION, proj_matrix);
133  pc_renderer.set_matrix(RS2_GL_MATRIX_TRANSFORMATION, view_matrix);
134 
135  // If we have something to render, use pointcloud-renderer to do it
136  if (points) pc_renderer.process(points);
137 
138  // Disable texturing
140 
141  // Print textual information
142  printer.print_instructions(app, use_gpu_processing);
143 
144  // Handle user input and check if reset is required
145  if (handle_input(app, use_gpu_processing))
146  {
147  // First, shutdown processing and rendering
150 
151  // Next, reinitialize processing and rendering with new settings
152  rs2::gl::init_processing(app, use_gpu_processing);
154  }
155  }
156 
157  return EXIT_SUCCESS;
158 }
159 catch (const rs2::error & e)
160 {
161  std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
162  return EXIT_FAILURE;
163 }
164 catch (const std::exception & e)
165 {
166  std::cerr << e.what() << std::endl;
167  return EXIT_FAILURE;
168 }
169 
171 {
172  // Initialize running clock to keep track of time (for FPS calculation)
174  int rendered_frames = 0; // Counts number of frames since last update
175  int last_fps = 0; // Stores last calculated FPS
176  glfwSwapInterval(0); // This is functionally disabling V-Sync,
177  // allowing application FPS to go beyond monitor refresh rate
178 }
179 
180 void instructions_printer::print_instructions(window& app, bool use_gpu_processing)
181 {
182  glLoadIdentity();
184  glOrtho(0, app.width(), app.height(), 0, -1, +1);
185 
186  glColor3f(1.f, 1.f, 1.f);
187  std::stringstream ss;
188  ss << "Performing Point-Cloud and Histogram-Equalization (Colorize) on the " << (use_gpu_processing ? "GPU" : "CPU");
189  draw_text(20, 20, ss.str().c_str());
190 
191  ss.str("");
192  ss << "( Press " << (use_gpu_processing ? "[C] - Switch to processing on the CPU )" : "[G] - Switch to processing on the GPU )");
193  draw_text(20, 36, ss.str().c_str());
194 
195  ss.str("");
196  ss << "This demo is being rendered at " << last_fps << " frames per second, ~" << (1000 / (last_fps + 1)) << "ms for single rendered frame";
197  draw_text(20, 52, ss.str().c_str());
198 
199  rendered_frames++;
200 
201  auto since_last_clock = std::chrono::high_resolution_clock::now() - last_clock;
202  auto sec_elapsed = std::chrono::duration_cast<std::chrono::seconds>(since_last_clock).count();
203  if (sec_elapsed > 0)
204  {
207  rendered_frames = 0;
208  }
209 }
210 
211 bool handle_input(window& app, bool& use_gpu_processing)
212 {
213  bool reset = false;
214 
215  if (glfwGetKey(app, GLFW_KEY_C) == GLFW_PRESS)
216  {
217  reset = use_gpu_processing;
218  use_gpu_processing = false;
219  }
220  if (glfwGetKey(app, GLFW_KEY_G) == GLFW_PRESS)
221  {
222  reset = !use_gpu_processing;
223  use_gpu_processing = true;
224  }
225 
226  return reset;
227 }
228 
229 void prepare_matrices(glfw_state& app_state, float width, float height, float* projection, float* view)
230 {
231  glLoadIdentity();
232 
234  glPushMatrix();
235  gluPerspective(60, width / height, 0.01f, 10.0f);
236  glGetFloatv(GL_PROJECTION_MATRIX, projection);
237 
239  glPushMatrix();
240  gluLookAt(0, 0, 0, 0, 0, 1, 0, -1, 0);
241  glTranslatef(0, 0, 0.5f + app_state.offset_y * 0.05f);
242  glRotated(app_state.pitch, 1, 0, 0);
243  glRotated(app_state.yaw, 0, 1, 0);
244  glTranslatef(0, 0, -0.5f);
246 
247  glPopMatrix();
249  glPopMatrix();
250 }
void init_processing(bool use_glsl=true)
void prepare_matrices(glfw_state &app_state, float width, float height, float *projection, float *view)
#define GL_TEXTURE_2D
#define glOrtho
GLboolean reset
double yaw
Definition: example.hpp:875
#define glPopMatrix
#define GL_PROJECTION
video_frame colorize(frame depth) const
double pitch
Definition: example.hpp:876
GLint GLint GLsizei GLsizei GLsizei depth
void map_to(frame mapped)
#define glLoadIdentity
e
Definition: rmse.py:177
void shutdown_processing()
#define glEnable
The texture class.
Definition: example.hpp:402
#define glGetFloatv
GLuint get_gl_handle()
Definition: example.hpp:469
depth_frame get_depth_frame() const
Definition: rs_frame.hpp:1006
const std::string & get_failed_args() const
Definition: rs_types.hpp:117
GLdouble f
rs2::frame process(rs2::frame frame) const override
bool poll_for_frames(frameset *f) const
void set_matrix(rs2_gl_matrix_type type, float *m4x4)
void print_instructions(window &app, bool use_gpu_processing)
float width() const
Definition: example.hpp:627
void shutdown_rendering()
GLFWAPI void glfwSwapInterval(int interval)
Sets the swap interval for the current context.
Definition: context.c:658
void upload(const rs2::video_frame &frame)
Definition: example.hpp:406
unsigned int uint32_t
Definition: stdint.h:80
#define glPushMatrix
#define GL_PROJECTION_MATRIX
#define glClear
points calculate(frame depth) const
static const textual_icon upload
Definition: model-views.h:235
GLint GLsizei GLsizei height
float offset_y
Definition: example.hpp:881
#define glTranslatef
std::chrono::high_resolution_clock::time_point last_clock
#define GLFW_KEY_G
Definition: glfw3.h:384
void init_rendering(bool use_glsl=true)
void enable_stream(rs2_stream stream_type, int stream_index, int width, int height, rs2_format format=RS2_FORMAT_ANY, int framerate=0)
#define GL_DEPTH_BUFFER_BIT
#define GL_MODELVIEW
float height() const
Definition: example.hpp:628
int main(int argc, char *argv[])
#define glColor3f
bool handle_input(window &app, bool &use_gpu_processing)
#define glBindTexture
void draw_text(int x, int y, const char *text)
Definition: example.hpp:109
GLint GLsizei count
#define GL_MODELVIEW_MATRIX
#define glClearColor
std::ostream & cerr()
#define glRotated
void register_glfw_callbacks(window &app, glfw_state &app_state)
Definition: example.hpp:1037
pipeline_profile start()
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
GLFWAPI int glfwGetKey(GLFWwindow *window, int key)
Returns the last reported state of a keyboard key for the specified window.
Definition: input.c:591
#define glMatrixMode
const std::string & get_failed_function() const
Definition: rs_types.hpp:112
GLint GLsizei width
GLdouble GLdouble GLint GLint const GLdouble * points
#define GL_DEPTH_TEST
#define GLFW_KEY_C
Definition: glfw3.h:380
#define glDisable
T as() const
Definition: rs_frame.hpp:580


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:40