inputlag.c
Go to the documentation of this file.
1 //========================================================================
2 // Input lag test
3 // Copyright (c) Camilla Löwy <elmindreda@glfw.org>
4 //
5 // This software is provided 'as-is', without any express or implied
6 // warranty. In no event will the authors be held liable for any damages
7 // arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it
11 // freely, subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented; you must not
14 // claim that you wrote the original software. If you use this software
15 // in a product, an acknowledgment in the product documentation would
16 // be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such, and must not
19 // be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source
22 // distribution.
23 //
24 //========================================================================
25 //
26 // This test renders a marker at the cursor position reported by GLFW to
27 // check how much it lags behind the hardware mouse cursor
28 //
29 //========================================================================
30 
31 #include <glad/glad.h>
32 #include <GLFW/glfw3.h>
33 
34 #define NK_IMPLEMENTATION
35 #define NK_INCLUDE_FIXED_TYPES
36 #define NK_INCLUDE_FONT_BAKING
37 #define NK_INCLUDE_DEFAULT_FONT
38 #define NK_INCLUDE_DEFAULT_ALLOCATOR
39 #define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
40 #define NK_INCLUDE_STANDARD_VARARGS
41 #include <nuklear.h>
42 
43 #define NK_GLFW_GL2_IMPLEMENTATION
44 #include <nuklear_glfw_gl2.h>
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #include "getopt.h"
51 
52 void usage(void)
53 {
54  printf("Usage: inputlag [-h] [-f]\n");
55  printf("Options:\n");
56  printf(" -f create full screen window\n");
57  printf(" -h show this help\n");
58 }
59 
60 struct nk_vec2 cursor_new, cursor_pos, cursor_vel;
62 
64 {
65  float a = .25; // exponential smoothing factor
66 
68  double x, y;
69  glfwGetCursorPos(window, &x, &y);
70  cursor_new.x = (float) x;
71  cursor_new.y = (float) y;
72  }
73 
74  cursor_vel.x = (cursor_new.x - cursor_pos.x) * a + cursor_vel.x * (1 - a);
75  cursor_vel.y = (cursor_new.y - cursor_pos.y) * a + cursor_vel.y * (1 - a);
76  cursor_pos = cursor_new;
77 }
78 
80 {
81  cursor_new.x = (float) xpos;
82  cursor_new.y = (float) ypos;
83 }
84 
86 
88 {
90 }
91 
97 
99 {
100  glfwSwapBuffers(window);
101 
102  if (swap_clear)
104 
105  if (swap_finish)
106  glFinish();
107 
108  if (swap_occlusion_query) {
109  GLint occlusion_result;
110  if (!occlusion_query)
114  glVertex2f(0, 0);
115  glEnd();
118  }
119 
120  if (swap_read_pixels) {
121  unsigned char rgba[4];
122  glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
123  }
124 }
125 
126 void error_callback(int error, const char* description)
127 {
128  fprintf(stderr, "Error: %s\n", description);
129 }
130 
131 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
132 {
133  if (action != GLFW_PRESS)
134  return;
135 
136  switch (key)
137  {
138  case GLFW_KEY_ESCAPE:
139  glfwSetWindowShouldClose(window, 1);
140  break;
141  }
142 }
143 
144 void draw_marker(struct nk_command_buffer* canvas, int lead, struct nk_vec2 pos)
145 {
146  struct nk_color colors[4] = { nk_rgb(255,0,0), nk_rgb(255,255,0), nk_rgb(0,255,0), nk_rgb(0,96,255) };
147  struct nk_rect rect = { -5 + pos.x, -5 + pos.y, 10, 10 };
148  nk_fill_circle(canvas, rect, colors[lead]);
149 }
150 
151 int main(int argc, char** argv)
152 {
153  int ch, width, height;
154  unsigned long frame_count = 0;
155  double last_time, current_time;
156  double frame_rate = 0;
157  int fullscreen = GLFW_FALSE;
158  GLFWmonitor* monitor = NULL;
160  struct nk_context* nk;
161  struct nk_font_atlas* atlas;
162 
163  int show_forecasts = nk_true;
164 
165  while ((ch = getopt(argc, argv, "fh")) != -1)
166  {
167  switch (ch)
168  {
169  case 'h':
170  usage();
171  exit(EXIT_SUCCESS);
172 
173  case 'f':
174  fullscreen = GLFW_TRUE;
175  break;
176  }
177  }
178 
180 
181  if (!glfwInit())
182  exit(EXIT_FAILURE);
183 
184  if (fullscreen)
185  {
186  const GLFWvidmode* mode;
187 
188  monitor = glfwGetPrimaryMonitor();
189  mode = glfwGetVideoMode(monitor);
190 
191  width = mode->width;
192  height = mode->height;
193  }
194  else
195  {
196  width = 640;
197  height = 480;
198  }
199 
202 
204 
205  window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL);
206  if (!window)
207  {
208  glfwTerminate();
209  exit(EXIT_FAILURE);
210  }
211 
212  glfwMakeContextCurrent(window);
214  update_vsync();
215 
216  last_time = glfwGetTime();
217 
221 
224 
225  while (!glfwWindowShouldClose(window))
226  {
227  int width, height;
228  struct nk_rect area;
229 
230  glfwPollEvents();
231  sample_input(window);
232 
233  glfwGetWindowSize(window, &width, &height);
234  area = nk_rect(0.f, 0.f, (float) width, (float) height);
235 
238  if (nk_begin(nk, "", area, 0))
239  {
241  struct nk_command_buffer *canvas = nk_window_get_canvas(nk);
242  int lead;
243 
244  for (lead = show_forecasts ? 3 : 0; lead >= 0; lead--)
245  draw_marker(canvas, lead, nk_vec2(cursor_pos.x + cursor_vel.x * lead,
246  cursor_pos.y + cursor_vel.y * lead));
247 
248  // print instructions
249  nk_layout_row_dynamic(nk, 20, 1);
250  nk_label(nk, "Move mouse uniformly and check marker under cursor:", align_left);
251  for (lead = 0; lead <= 3; lead++) {
252  nk_layout_row_begin(nk, NK_STATIC, 12, 2);
253  nk_layout_row_push(nk, 25);
254  draw_marker(canvas, lead, nk_layout_space_to_screen(nk, nk_vec2(20, 5)));
255  nk_label(nk, "", 0);
256  nk_layout_row_push(nk, 500);
257  if (lead == 0)
258  nk_label(nk, "- current cursor position (no input lag)", align_left);
259  else
260  nk_labelf(nk, align_left, "- %d-frame forecast (input lag is %d frame)", lead, lead);
261  nk_layout_row_end(nk);
262  }
263 
264  nk_layout_row_dynamic(nk, 20, 1);
265 
266  nk_checkbox_label(nk, "Show forecasts", &show_forecasts);
267  nk_label(nk, "Input method:", align_left);
268  if (nk_option_label(nk, "glfwGetCursorPos (sync query)", cursor_method == cursor_sync_query))
270  if (nk_option_label(nk, "glfwSetCursorPosCallback (latest input message)", cursor_method == cursor_input_message))
272 
273  nk_label(nk, "", 0); // separator
274 
275  nk_value_float(nk, "FPS", (float) frame_rate);
276  if (nk_checkbox_label(nk, "Enable vsync", &enable_vsync))
277  update_vsync();
278 
279  nk_label(nk, "", 0); // separator
280 
281  nk_label(nk, "After swap:", align_left);
282  nk_checkbox_label(nk, "glClear", &swap_clear);
283  nk_checkbox_label(nk, "glFinish", &swap_finish);
284  nk_checkbox_label(nk, "draw with occlusion query", &swap_occlusion_query);
285  nk_checkbox_label(nk, "glReadPixels", &swap_read_pixels);
286  }
287 
288  nk_end(nk);
290 
291  swap_buffers(window);
292 
293  frame_count++;
294 
295  current_time = glfwGetTime();
296  if (current_time - last_time > 1.0)
297  {
298  frame_rate = frame_count / (current_time - last_time);
299  frame_count = 0;
300  last_time = current_time;
301  }
302  }
303 
304  glfwTerminate();
305  exit(EXIT_SUCCESS);
306 }
307 
void error_callback(int error, const char *description)
Definition: inputlag.c:126
NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags)
int height
Definition: glfw3.h:1532
GLint y
GLFWAPI void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the client area of the specified window.
Definition: window.c:544
NK_API void nk_layout_row_end(struct nk_context *)
NK_API void nk_fill_circle(struct nk_command_buffer *, struct nk_rect, struct nk_color)
static double frame_rate
Definition: tearing.c:69
The header of the GLFW 3 API.
GLFWAPI GLFWglproc glfwGetProcAddress(const char *procname)
Returns the address of the specified function for the current context.
Definition: context.c:741
long long current_time()
#define GL_RGBA
#define glBegin
void *(* GLADloadproc)(const char *name)
static GLFWwindow * window
Definition: joysticks.c:55
#define GL_UNSIGNED_BYTE
int width
Definition: glfw3.h:1529
struct nk_vec2 cursor_new cursor_pos cursor_vel
Definition: inputlag.c:60
GLFWAPI const GLFWvidmode * glfwGetVideoMode(GLFWmonitor *monitor)
Returns the current mode of the specified monitor.
Definition: monitor.c:417
#define GLFW_CONTEXT_VERSION_MAJOR
Context client API major version hint and attribute.
Definition: glfw3.h:921
void sample_input(GLFWwindow *window)
Definition: inputlag.c:63
struct GLFWmonitor GLFWmonitor
nk_uint nk_flags
Definition: nuklear.h:407
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
Sets the error callback.
Definition: init.c:309
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
NK_API void nk_label(struct nk_context *, const char *, nk_flags align)
NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context *, struct nk_vec2)
int getopt(int argc, char *const argv[], const char *optstring)
Definition: getopt.c:52
NK_API void nk_glfw3_render(enum nk_anti_aliasing)
NK_API struct nk_color nk_rgb(int r, int g, int b)
void update_vsync()
Definition: inputlag.c:87
#define GLFW_SCALE_TO_MONITOR
Window content area scaling window window hint.
Definition: glfw3.h:979
GLboolean GLboolean GLboolean GLboolean a
GLuint64 key
Definition: glext.h:8966
NK_API struct nk_vec2 nk_vec2(float x, float y)
GLFWAPI int glfwInit(void)
Initializes the GLFW library.
Definition: init.c:198
GLdouble f
NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
GLenum mode
#define glGenQueries
#define GL_COLOR_BUFFER_BIT
NK_API void nk_glfw3_new_frame(void)
void usage(void)
Definition: inputlag.c:52
int swap_clear
Definition: inputlag.c:92
int GLint
NK_API struct nk_rect nk_rect(float x, float y, float w, float h)
GLdouble x
NK_API struct nk_context * nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state)
GLFWAPI void glfwSwapInterval(int interval)
Sets the swap interval for the current context.
Definition: context.c:658
GLuint occlusion_query
Definition: inputlag.c:96
void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos)
Definition: inputlag.c:79
#define GLFW_KEY_ESCAPE
Definition: glfw3.h:412
#define glClear
GLint GLsizei GLsizei height
GLFWAPI void glfwSwapBuffers(GLFWwindow *window)
Swaps the front and back buffers of the specified window.
Definition: context.c:641
GLFWAPI void glfwMakeContextCurrent(GLFWwindow *window)
Makes the context of the specified window current for the calling thread.
Definition: context.c:611
NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols)
#define glGetQueryObjectiv
GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *window, GLFWcursorposfun cbfun)
Sets the cursor position callback.
Definition: input.c:832
#define glEnd
float y
Definition: nuklear.h:457
#define glBeginQuery
float x
Definition: nuklear.h:457
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: inputlag.c:131
action
Definition: enums.py:62
GLAPI int gladLoadGLLoader(GLADloadproc)
Definition: glad/glad.c:1697
#define glEndQuery
static const textual_icon exit
Definition: model-views.h:254
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow *window, int value)
Sets the close flag of the specified window.
Definition: window.c:486
#define GL_QUERY_RESULT
GLFWAPI GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
Creates a window and its associated context.
Definition: window.c:151
#define GLFW_TRUE
One.
Definition: glfw3.h:279
GLFWAPI void glfwGetCursorPos(GLFWwindow *window, double *xpos, double *ypos)
Retrieves the position of the cursor relative to the client area of the window.
Definition: input.c:637
GLFWAPI double glfwGetTime(void)
Returns the value of the GLFW timer.
Definition: input.c:1275
#define glFinish
Video mode type.
Definition: glfw3.h:1525
unsigned int GLuint
NK_API int nk_option_label(struct nk_context *, const char *, int active)
NK_API struct nk_command_buffer * nk_window_get_canvas(struct nk_context *)
static double xpos
Definition: splitview.c:33
NK_API int nk_checkbox_label(struct nk_context *, const char *, int *active)
GLFWAPI GLFWmonitor * glfwGetPrimaryMonitor(void)
Returns the primary monitor.
Definition: monitor.c:308
GLFWAPI void glfwTerminate(void)
Terminates the GLFW library.
Definition: init.c:243
void draw_marker(struct nk_command_buffer *canvas, int lead, struct nk_vec2 pos)
Definition: inputlag.c:144
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun cbfun)
Sets the key callback.
Definition: input.c:791
float rs2_vector::* pos
GLFWAPI void glfwPollEvents(void)
Processes all pending events.
Definition: window.c:1072
NK_API void nk_glfw3_font_stash_end(void)
#define NULL
Definition: tinycthread.c:47
#define GL_SAMPLES_PASSED
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
void swap_buffers(GLFWwindow *window)
Definition: inputlag.c:98
#define glVertex2f
int swap_occlusion_query
Definition: inputlag.c:94
NK_API void nk_end(struct nk_context *ctx)
#define glReadPixels
#define GLFW_CONTEXT_VERSION_MINOR
Context client API minor version hint and attribute.
Definition: glfw3.h:927
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
enum @54 cursor_method
int swap_read_pixels
Definition: inputlag.c:95
int swap_finish
Definition: inputlag.c:93
#define GL_POINTS
struct GLFWwindow GLFWwindow
GLFWAPI void glfwWindowHint(int hint, int value)
Sets the specified window hint to the desired value.
Definition: window.c:291
int enable_vsync
Definition: inputlag.c:85
GLint GLsizei width
static double ypos
Definition: splitview.c:33
int main(int argc, char **argv)
Definition: inputlag.c:151
GLFWAPI int glfwWindowShouldClose(GLFWwindow *window)
Checks the close flag of the specified window.
Definition: window.c:477
NK_API void nk_layout_row_push(struct nk_context *, float value)


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