splitview.c
Go to the documentation of this file.
1 //========================================================================
2 // This is an example program for the GLFW library
3 //
4 // The program uses a "split window" view, rendering four views of the
5 // same scene in one window (e.g. uesful for 3D modelling software). This
6 // demo uses scissors to separete the four different rendering areas from
7 // each other.
8 //
9 // (If the code seems a little bit strange here and there, it may be
10 // because I am not a friend of orthogonal projections)
11 //========================================================================
12 
13 #include <glad/glad.h>
14 #include <GLFW/glfw3.h>
15 
16 #if defined(_MSC_VER)
17  // Make MS math.h define M_PI
18  #define _USE_MATH_DEFINES
19 #endif
20 
21 #include <math.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include <linmath.h>
26 
27 
28 //========================================================================
29 // Global variables
30 //========================================================================
31 
32 // Mouse position
33 static double xpos = 0, ypos = 0;
34 
35 // Window size
36 static int width, height;
37 
38 // Active view: 0 = none, 1 = upper left, 2 = upper right, 3 = lower left,
39 // 4 = lower right
40 static int active_view = 0;
41 
42 // Rotation around each axis
43 static int rot_x = 0, rot_y = 0, rot_z = 0;
44 
45 // Do redraw?
46 static int do_redraw = 1;
47 
48 
49 //========================================================================
50 // Draw a solid torus (use a display list for the model)
51 //========================================================================
52 
53 #define TORUS_MAJOR 1.5
54 #define TORUS_MINOR 0.5
55 #define TORUS_MAJOR_RES 32
56 #define TORUS_MINOR_RES 32
57 
58 static void drawTorus(void)
59 {
60  static GLuint torus_list = 0;
61  int i, j, k;
62  double s, t, x, y, z, nx, ny, nz, scale, twopi;
63 
64  if (!torus_list)
65  {
66  // Start recording displaylist
67  torus_list = glGenLists(1);
68  glNewList(torus_list, GL_COMPILE_AND_EXECUTE);
69 
70  // Draw torus
71  twopi = 2.0 * M_PI;
72  for (i = 0; i < TORUS_MINOR_RES; i++)
73  {
75  for (j = 0; j <= TORUS_MAJOR_RES; j++)
76  {
77  for (k = 1; k >= 0; k--)
78  {
79  s = (i + k) % TORUS_MINOR_RES + 0.5;
80  t = j % TORUS_MAJOR_RES;
81 
82  // Calculate point on surface
83  x = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * cos(t * twopi / TORUS_MAJOR_RES);
84  y = TORUS_MINOR * sin(s * twopi / TORUS_MINOR_RES);
85  z = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * sin(t * twopi / TORUS_MAJOR_RES);
86 
87  // Calculate surface normal
88  nx = x - TORUS_MAJOR * cos(t * twopi / TORUS_MAJOR_RES);
89  ny = y;
90  nz = z - TORUS_MAJOR * sin(t * twopi / TORUS_MAJOR_RES);
91  scale = 1.0 / sqrt(nx*nx + ny*ny + nz*nz);
92  nx *= scale;
93  ny *= scale;
94  nz *= scale;
95 
96  glNormal3f((float) nx, (float) ny, (float) nz);
97  glVertex3f((float) x, (float) y, (float) z);
98  }
99  }
100 
101  glEnd();
102  }
103 
104  // Stop recording displaylist
105  glEndList();
106  }
107  else
108  {
109  // Playback displaylist
110  glCallList(torus_list);
111  }
112 }
113 
114 
115 //========================================================================
116 // Draw the scene (a rotating torus)
117 //========================================================================
118 
119 static void drawScene(void)
120 {
121  const GLfloat model_diffuse[4] = {1.0f, 0.8f, 0.8f, 1.0f};
122  const GLfloat model_specular[4] = {0.6f, 0.6f, 0.6f, 1.0f};
123  const GLfloat model_shininess = 20.0f;
124 
125  glPushMatrix();
126 
127  // Rotate the object
128  glRotatef((GLfloat) rot_x * 0.5f, 1.0f, 0.0f, 0.0f);
129  glRotatef((GLfloat) rot_y * 0.5f, 0.0f, 1.0f, 0.0f);
130  glRotatef((GLfloat) rot_z * 0.5f, 0.0f, 0.0f, 1.0f);
131 
132  // Set model color (used for orthogonal views, lighting disabled)
133  glColor4fv(model_diffuse);
134 
135  // Set model material (used for perspective view, lighting enabled)
136  glMaterialfv(GL_FRONT, GL_DIFFUSE, model_diffuse);
137  glMaterialfv(GL_FRONT, GL_SPECULAR, model_specular);
138  glMaterialf(GL_FRONT, GL_SHININESS, model_shininess);
139 
140  // Draw torus
141  drawTorus();
142 
143  glPopMatrix();
144 }
145 
146 
147 //========================================================================
148 // Draw a 2D grid (used for orthogonal views)
149 //========================================================================
150 
151 static void drawGrid(float scale, int steps)
152 {
153  int i;
154  float x, y;
155  mat4x4 view;
156 
157  glPushMatrix();
158 
159  // Set background to some dark bluish grey
160  glClearColor(0.05f, 0.05f, 0.2f, 0.0f);
162 
163  // Setup modelview matrix (flat XY view)
164  {
165  vec3 eye = { 0.f, 0.f, 1.f };
166  vec3 center = { 0.f, 0.f, 0.f };
167  vec3 up = { 0.f, 1.f, 0.f };
168  mat4x4_look_at(view, eye, center, up);
169  }
170  glLoadMatrixf((const GLfloat*) view);
171 
172  // We don't want to update the Z-buffer
174 
175  // Set grid color
176  glColor3f(0.0f, 0.5f, 0.5f);
177 
178  glBegin(GL_LINES);
179 
180  // Horizontal lines
181  x = scale * 0.5f * (float) (steps - 1);
182  y = -scale * 0.5f * (float) (steps - 1);
183  for (i = 0; i < steps; i++)
184  {
185  glVertex3f(-x, y, 0.0f);
186  glVertex3f(x, y, 0.0f);
187  y += scale;
188  }
189 
190  // Vertical lines
191  x = -scale * 0.5f * (float) (steps - 1);
192  y = scale * 0.5f * (float) (steps - 1);
193  for (i = 0; i < steps; i++)
194  {
195  glVertex3f(x, -y, 0.0f);
196  glVertex3f(x, y, 0.0f);
197  x += scale;
198  }
199 
200  glEnd();
201 
202  // Enable Z-buffer writing again
204 
205  glPopMatrix();
206 }
207 
208 
209 //========================================================================
210 // Draw all views
211 //========================================================================
212 
213 static void drawAllViews(void)
214 {
215  const GLfloat light_position[4] = {0.0f, 8.0f, 8.0f, 1.0f};
216  const GLfloat light_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
217  const GLfloat light_specular[4] = {1.0f, 1.0f, 1.0f, 1.0f};
218  const GLfloat light_ambient[4] = {0.2f, 0.2f, 0.3f, 1.0f};
219  float aspect;
220  mat4x4 view, projection;
221 
222  // Calculate aspect of window
223  if (height > 0)
224  aspect = (float) width / (float) height;
225  else
226  aspect = 1.f;
227 
228  // Clear screen
229  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
231 
232  // Enable scissor test
234 
235  // Enable depth test
238 
239  // ** ORTHOGONAL VIEWS **
240 
241  // For orthogonal views, use wireframe rendering
243 
244  // Enable line anti-aliasing
248 
249  // Setup orthogonal projection matrix
251  glLoadIdentity();
252  glOrtho(-3.0 * aspect, 3.0 * aspect, -3.0, 3.0, 1.0, 50.0);
253 
254  // Upper left view (TOP VIEW)
255  glViewport(0, height / 2, width / 2, height / 2);
256  glScissor(0, height / 2, width / 2, height / 2);
258  {
259  vec3 eye = { 0.f, 10.f, 1e-3f };
260  vec3 center = { 0.f, 0.f, 0.f };
261  vec3 up = { 0.f, 1.f, 0.f };
262  mat4x4_look_at( view, eye, center, up );
263  }
264  glLoadMatrixf((const GLfloat*) view);
265  drawGrid(0.5, 12);
266  drawScene();
267 
268  // Lower left view (FRONT VIEW)
269  glViewport(0, 0, width / 2, height / 2);
270  glScissor(0, 0, width / 2, height / 2);
272  {
273  vec3 eye = { 0.f, 0.f, 10.f };
274  vec3 center = { 0.f, 0.f, 0.f };
275  vec3 up = { 0.f, 1.f, 0.f };
276  mat4x4_look_at( view, eye, center, up );
277  }
278  glLoadMatrixf((const GLfloat*) view);
279  drawGrid(0.5, 12);
280  drawScene();
281 
282  // Lower right view (SIDE VIEW)
283  glViewport(width / 2, 0, width / 2, height / 2);
284  glScissor(width / 2, 0, width / 2, height / 2);
286  {
287  vec3 eye = { 10.f, 0.f, 0.f };
288  vec3 center = { 0.f, 0.f, 0.f };
289  vec3 up = { 0.f, 1.f, 0.f };
290  mat4x4_look_at( view, eye, center, up );
291  }
292  glLoadMatrixf((const GLfloat*) view);
293  drawGrid(0.5, 12);
294  drawScene();
295 
296  // Disable line anti-aliasing
299 
300  // ** PERSPECTIVE VIEW **
301 
302  // For perspective view, use solid rendering
304 
305  // Enable face culling (faster rendering)
309 
310  // Setup perspective projection matrix
312  mat4x4_perspective(projection,
313  65.f * (float) M_PI / 180.f,
314  aspect,
315  1.f, 50.f);
316  glLoadMatrixf((const GLfloat*) projection);
317 
318  // Upper right view (PERSPECTIVE VIEW)
319  glViewport(width / 2, height / 2, width / 2, height / 2);
320  glScissor(width / 2, height / 2, width / 2, height / 2);
322  {
323  vec3 eye = { 3.f, 1.5f, 3.f };
324  vec3 center = { 0.f, 0.f, 0.f };
325  vec3 up = { 0.f, 1.f, 0.f };
326  mat4x4_look_at( view, eye, center, up );
327  }
328  glLoadMatrixf((const GLfloat*) view);
329 
330  // Configure and enable light source 1
331  glLightfv(GL_LIGHT1, GL_POSITION, light_position);
332  glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
333  glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
334  glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
337 
338  // Draw scene
339  drawScene();
340 
341  // Disable lighting
343 
344  // Disable face culling
346 
347  // Disable depth test
349 
350  // Disable scissor test
352 
353  // Draw a border around the active view
354  if (active_view > 0 && active_view != 2)
355  {
356  glViewport(0, 0, width, height);
357 
359  glLoadIdentity();
360  glOrtho(0.0, 2.0, 0.0, 2.0, 0.0, 1.0);
361 
363  glLoadIdentity();
364  glTranslatef((GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f);
365 
366  glColor3f(1.0f, 1.0f, 0.6f);
367 
369  glVertex2i(0, 0);
370  glVertex2i(1, 0);
371  glVertex2i(1, 1);
372  glVertex2i(0, 1);
373  glVertex2i(0, 0);
374  glEnd();
375  }
376 }
377 
378 
379 //========================================================================
380 // Framebuffer size callback function
381 //========================================================================
382 
383 static void framebufferSizeFun(GLFWwindow* window, int w, int h)
384 {
385  width = w;
386  height = h > 0 ? h : 1;
387  do_redraw = 1;
388 }
389 
390 
391 //========================================================================
392 // Window refresh callback function
393 //========================================================================
394 
396 {
397  drawAllViews();
398  glfwSwapBuffers(window);
399  do_redraw = 0;
400 }
401 
402 
403 //========================================================================
404 // Mouse position callback function
405 //========================================================================
406 
407 static void cursorPosFun(GLFWwindow* window, double x, double y)
408 {
409  int wnd_width, wnd_height, fb_width, fb_height;
410  double scale;
411 
412  glfwGetWindowSize(window, &wnd_width, &wnd_height);
413  glfwGetFramebufferSize(window, &fb_width, &fb_height);
414 
415  scale = (double) fb_width / (double) wnd_width;
416 
417  x *= scale;
418  y *= scale;
419 
420  // Depending on which view was selected, rotate around different axes
421  switch (active_view)
422  {
423  case 1:
424  rot_x += (int) (y - ypos);
425  rot_z += (int) (x - xpos);
426  do_redraw = 1;
427  break;
428  case 3:
429  rot_x += (int) (y - ypos);
430  rot_y += (int) (x - xpos);
431  do_redraw = 1;
432  break;
433  case 4:
434  rot_y += (int) (x - xpos);
435  rot_z += (int) (y - ypos);
436  do_redraw = 1;
437  break;
438  default:
439  // Do nothing for perspective view, or if no view is selected
440  break;
441  }
442 
443  // Remember cursor position
444  xpos = x;
445  ypos = y;
446 }
447 
448 
449 //========================================================================
450 // Mouse button callback function
451 //========================================================================
452 
453 static void mouseButtonFun(GLFWwindow* window, int button, int action, int mods)
454 {
455  if ((button == GLFW_MOUSE_BUTTON_LEFT) && action == GLFW_PRESS)
456  {
457  // Detect which of the four views was clicked
458  active_view = 1;
459  if (xpos >= width / 2)
460  active_view += 1;
461  if (ypos >= height / 2)
462  active_view += 2;
463  }
464  else if (button == GLFW_MOUSE_BUTTON_LEFT)
465  {
466  // Deselect any previously selected view
467  active_view = 0;
468  }
469 
470  do_redraw = 1;
471 }
472 
473 static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
474 {
475  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
477 }
478 
479 
480 //========================================================================
481 // main
482 //========================================================================
483 
484 int main(void)
485 {
487 
488  // Initialise GLFW
489  if (!glfwInit())
490  {
491  fprintf(stderr, "Failed to initialize GLFW\n");
492  exit(EXIT_FAILURE);
493  }
494 
496 
497  // Open OpenGL window
498  window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL);
499  if (!window)
500  {
501  fprintf(stderr, "Failed to open GLFW window\n");
502 
503  glfwTerminate();
504  exit(EXIT_FAILURE);
505  }
506 
507  // Set callback functions
513 
514  // Enable vsync
515  glfwMakeContextCurrent(window);
517  glfwSwapInterval(1);
518 
521 
522  glfwGetFramebufferSize(window, &width, &height);
523  framebufferSizeFun(window, width, height);
524 
525  // Main loop
526  for (;;)
527  {
528  // Only redraw if we need to
529  if (do_redraw)
530  windowRefreshFun(window);
531 
532  // Wait for new events
533  glfwWaitEvents();
534 
535  // Check if the window should be closed
536  if (glfwWindowShouldClose(window))
537  break;
538  }
539 
540  // Close OpenGL window and terminate GLFW
541  glfwTerminate();
542 
543  exit(EXIT_SUCCESS);
544 }
545 
#define glLightfv
#define GL_LEQUAL
#define TORUS_MINOR_RES
Definition: splitview.c:56
GLint y
#define GL_SHININESS
GLFWAPI void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the client area of the specified window.
Definition: window.c:544
vec4 mat4x4[4]
Definition: linmath.h:83
khronos_float_t GLfloat
#define glRotatef
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
#define GL_QUAD_STRIP
GLdouble s
#define glDepthFunc
#define GL_SCISSOR_TEST
#define glOrtho
#define glBegin
void *(* GLADloadproc)(const char *name)
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:10806
static GLFWwindow * window
Definition: joysticks.c:55
GLAPI int GLAD_GL_VERSION_1_3
static void drawGrid(float scale, int steps)
Definition: splitview.c:151
#define glDepthMask
#define GL_CW
#define glPopMatrix
#define glMaterialfv
#define GL_LINE
#define GL_PROJECTION
#define glFrontFace
#define GL_BACK
#define glCullFace
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow *window, GLFWmousebuttonfun cbfun)
Sets the mouse button callback.
Definition: input.c:821
GLAPI int GLAD_GL_ARB_multisample
#define GLFW_MOUSE_BUTTON_LEFT
Definition: glfw3.h:546
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: splitview.c:473
GLdouble GLdouble GLdouble w
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow *window, GLFWframebuffersizefun cbfun)
Sets the framebuffer resize callback for the specified window.
Definition: window.c:1050
#define GL_BLEND
#define glPolygonMode
#define glLoadIdentity
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
GLdouble GLdouble z
#define glVertex3f
#define GL_SRC_ALPHA
e
Definition: rmse.py:177
#define glEnable
static void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
Definition: linmath.h:357
static int rot_x
Definition: splitview.c:43
static int height
Definition: splitview.c:36
GLdouble t
GLuint64 key
Definition: glext.h:8966
#define GL_LIGHTING
static void drawTorus(void)
Definition: splitview.c:58
GLFWAPI int glfwInit(void)
Initializes the GLFW library.
Definition: init.c:198
GLdouble f
static int do_redraw
Definition: splitview.c:46
#define GL_SPECULAR
static void mouseButtonFun(GLFWwindow *window, int button, int action, int mods)
Definition: splitview.c:453
#define glEndList
#define GL_COLOR_BUFFER_BIT
#define TORUS_MAJOR
Definition: splitview.c:53
GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow *window, GLFWwindowrefreshfun cbfun)
Sets the refresh callback for the specified window.
Definition: window.c:1006
#define GL_DIFFUSE
#define GL_FRONT_AND_BACK
#define GL_LINES
#define glScissor
GLdouble x
#define GL_LIGHT1
GLFWAPI void glfwSwapInterval(int interval)
Sets the swap interval for the current context.
Definition: context.c:658
#define glPushMatrix
#define glLoadMatrixf
GLbyte ny
#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
#define glTranslatef
static void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
Definition: linmath.h:383
#define glNormal3f
static int rot_z
Definition: splitview.c:43
GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *window, GLFWcursorposfun cbfun)
Sets the cursor position callback.
Definition: input.c:832
#define glEnd
GLint j
#define glColor4fv
#define glGenLists
GLbyte nx
Definition: glext.h:6424
static void drawAllViews(void)
Definition: splitview.c:213
#define GL_FILL
#define GL_TRUE
#define TORUS_MINOR
Definition: splitview.c:54
#define GL_MULTISAMPLE_ARB
#define GL_FRONT
action
Definition: enums.py:62
GLAPI int gladLoadGLLoader(GLADloadproc)
Definition: glad/glad.c:1697
#define glViewport
#define GL_POSITION
#define GL_DEPTH_BUFFER_BIT
#define GL_MODELVIEW
static const textual_icon exit
Definition: model-views.h:254
#define GL_ONE_MINUS_SRC_ALPHA
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow *window, int value)
Sets the close flag of the specified window.
Definition: window.c:486
#define GL_LINE_SMOOTH
GLFWAPI void glfwWaitEvents(void)
Waits until events are queued and processes them.
Definition: window.c:1078
#define glVertex2i
#define TORUS_MAJOR_RES
Definition: splitview.c:55
static void cursorPosFun(GLFWwindow *window, double x, double y)
Definition: splitview.c:407
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
#define GL_FALSE
#define GL_CULL_FACE
static int active_view
Definition: splitview.c:40
#define glColor3f
#define GL_COMPILE_AND_EXECUTE
unsigned int GLuint
static void windowRefreshFun(GLFWwindow *window)
Definition: splitview.c:395
#define GL_AMBIENT
static double xpos
Definition: splitview.c:33
GLFWAPI void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the framebuffer of the specified window.
Definition: window.c:647
static int width
Definition: splitview.c:36
GLFWAPI void glfwTerminate(void)
Terminates the GLFW library.
Definition: init.c:243
#define glClearColor
#define GLFW_SAMPLES
Framebuffer MSAA samples hint.
Definition: glfw3.h:893
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun cbfun)
Sets the key callback.
Definition: input.c:791
#define GL_LINE_STRIP
#define glCallList
#define NULL
Definition: tinycthread.c:47
#define glNewList
#define glMaterialf
static int rot_y
Definition: splitview.c:43
int i
static void framebufferSizeFun(GLFWwindow *window, int w, int h)
Definition: splitview.c:383
GLbyte GLbyte nz
#define glBlendFunc
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
int main(void)
Definition: splitview.c:484
static void drawScene(void)
Definition: splitview.c:119
#define glMatrixMode
struct GLFWwindow GLFWwindow
GLFWAPI void glfwWindowHint(int hint, int value)
Sets the specified window hint to the desired value.
Definition: window.c:291
GLint GLsizei width
#define GL_DEPTH_TEST
static double ypos
Definition: splitview.c:33
#define glDisable
GLFWAPI int glfwWindowShouldClose(GLFWwindow *window)
Checks the close flag of the specified window.
Definition: window.c:477


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