gVirtualXRay  2.0.10
VirtualX-RayImagingLibraryonGPU
OpenGLUtilities.inl
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2014-2023, Dr Franck P. Vidal, Bangor University, All rights reserved.
4 Copyright (c) 2023-present, Prof Franck P. Vidal (franck.vidal@stfc.ac.uk),
5 UK Research and Innovation, All rights reserved.
6 
7 
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
10 
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13 
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation and/or
16 other materials provided with the distribution.
17 
18 3. Neither the name of Bangor University, UK Research and Innovation nor the
19 names of its contributors may be used to endorse or promote products derived
20 from this software without specific prior written permission.
21 
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 */
34 
35 
64 //******************************************************************************
65 // Include
66 //******************************************************************************
67 #include <cmath>
68 
69 #ifndef GVXR_OPENGL_EXCEPTION_H
71 #endif
72 
73 #ifndef GVXR_OUT_OF_BOUNDS_EXCEPTION_H
75 #endif
76 
77 #ifndef GVXR_FBO_EXCEPTION_H
79 #endif
80 
81 #ifndef GVXR_TYPES_H
82 #include "gVirtualXRay/Types.h"
83 #endif
84 
85 #ifndef GVXR_CONSTANT_VALUES_H
87 #endif
88 
89 
90 //******************************************************************************
91 // namespace
92 //******************************************************************************
93 namespace gVirtualXRay {
94 
95 
96 //--------------------------------
97 inline void pushProjectionMatrix()
98 //--------------------------------
99 {
101 }
102 
103 
104 //-------------------------------
105 inline void pushModelViewMatrix()
106 //-------------------------------
107 {
109 }
110 
111 
112 //-------------------------------
113 inline void popProjectionMatrix()
114 //-------------------------------
115 {
116  // Make sure the stack is not empty
117  if (g_p_projection_matrix_stack.size() == 0)
118  {
119  throw OutOfBoundsException(__FILE__, __FUNCTION__, __LINE__);
120  }
121 
122  // Restore the matrix
124 
125  // Remove the last matrix
126  g_p_projection_matrix_stack.pop_back();
127 }
128 
129 
130 //------------------------------
131 inline void popModelViewMatrix()
132 //------------------------------
133 {
134  // Make sure the stack is not empty
135  if (g_p_modelview_matrix_stack.size() == 0)
136  {
137  throw OutOfBoundsException(__FILE__, __FUNCTION__, __LINE__);
138  }
139 
140  // Restore the matrix
143 
144  // Remove the last matrix
145  g_p_modelview_matrix_stack.pop_back();
146 }
147 
148 
149 //----------------------------------------
151 //----------------------------------------
152 {
154 }
155 
156 
157 //---------------------------------------
159 //---------------------------------------
160 {
162 }
163 
164 
165 //---------------------------------------------------------
167  double right,
168  double bottom,
169  double top,
170  double nearPlane,
171  double farPlane)
172 //---------------------------------------------------------
173 {
174  double t_x(-(right + left) / (right - left));
175  double t_y(-(top + bottom) / (top - bottom));
176  double t_z(-(farPlane + nearPlane) / (farPlane - nearPlane));
177 
178  return (MATRIX4(
179  2.0 / (right - left),
180  0.0,
181  0.0,
182  0.0,
183 
184  0.0,
185  2.0 / (top - bottom),
186  0.0,
187  0.0,
188 
189  0.0,
190  0.0,
191  -2.0 / (farPlane - nearPlane),
192  0.0,
193 
194  t_x,
195  t_y,
196  t_z,
197  1.0)
198  );
199 }
200 
201 //-----------------------------------------------------
202 inline void loadOrthoProjectionMatrix(double left,
203  double right,
204  double bottom,
205  double top,
206  double nearPlane,
207  double farPlane)
208 //-----------------------------------------------------
209 {
210  g_current_projection_matrix = buildOrthoProjectionMatrix(left, right, bottom, top, nearPlane, farPlane);
211 }
212 
213 
214 //-------------------------------------------------------
215 inline void loadFrustumProjectionMatrix(double left,
216  double right,
217  double bottom,
218  double top,
219  double nearPlane,
220  double farPlane)
221 //-------------------------------------------------------
222 {
223  g_current_projection_matrix = buildFrustumProjectionMatrix(left, right, bottom, top, nearPlane, farPlane);
224 }
225 
226 
227 //-----------------------------------------------------------
229  double right,
230  double bottom,
231  double top,
232  double nearPlane,
233  double farPlane)
234 //-----------------------------------------------------------
235 {
236  double a( (right + left) / (right - left));
237  double b( (top + bottom) / (top - bottom));
238  double c(-(farPlane + nearPlane) / (farPlane - nearPlane));
239  double d(-(2.0 * farPlane * nearPlane) / (farPlane - nearPlane));
240 
241  return (MATRIX4(
242  2.0 * nearPlane / (right - left),
243  0.0,
244  0.0,
245  0.0,
246 
247  0.0,
248  2.0 * nearPlane / (top - bottom),
249  0.0,
250  0.0,
251 
252  a,
253  b,
254  c,
255  -1.0,
256 
257  0.0,
258  0.0,
259  d,
260  0.0)
261  );
262 }
263 
264 
265 //---------------------------------------------------------
266 inline void multiplyOrthoProjectionMatrix(double left,
267  double right,
268  double bottom,
269  double top,
270  double nearPlane,
271  double farPlane)
272 //---------------------------------------------------------
273 {
274  g_current_projection_matrix *= buildOrthoProjectionMatrix(left, right, bottom, top, nearPlane, farPlane);
275 }
276 
277 
278 //------------------------------------------------------------
280  double aspect,
281  double zNear,
282  double zFar)
283 //------------------------------------------------------------
284 {
285  double f(tan(Pi_2 - (((fovy * Pi) / 180.0) / 2.0)));
286 
287  return (MATRIX4(
288  f / aspect,
289  0.0,
290  0.0,
291  0.0,
292 
293  0.0,
294  f,
295  0.0,
296  0.0,
297 
298  0.0,
299  0.0,
300  (zFar + zNear) / (zNear - zFar),
301  -1.0,
302 
303  0.0,
304  0.0,
305  (2.0 * zFar * zNear) / (zNear - zFar),
306  0.0)
307  );
308 }
309 
310 
311 //--------------------------------------------------------
312 inline void loadPerspectiveProjectionMatrix(double fovy,
313  double aspect,
314  double zNear,
315  double zFar)
316 //--------------------------------------------------------
317 {
319 }
320 
321 
322 //------------------------------------------------------------
323 inline void multiplyPerspectiveProjectionMatrix(double fovy,
324  double aspect,
325  double zNear,
326  double zFar)
327 //------------------------------------------------------------
328 {
330 }
331 
332 
333 //-----------------------------------------------------------
335  const VEC3& center,
336  const VEC3& up)
337 //-----------------------------------------------------------
338 {
339  // Forward vector: centre - eye
340  VEC3 forward(center - eye);
341  forward.normalize();
342 
343  // Up vector
344  VEC3 up1(up.normal());
345 
346  // Side vector: forward x up
347  VEC3 side(forward ^ up1);
348 
349  // New up vector: side x forward
350  VEC3 u(side.normal() ^ forward);
351 
352 
353  MATRIX4 matrix(
354  side.getX(),
355  u.getX(),
356  -forward.getX(),
357  0.0,
358 
359  side.getY(),
360  u.getY(),
361  -forward.getY(),
362  0.0,
363 
364  side.getZ(),
365  u.getZ(),
366  -forward.getZ(),
367  0.0,
368 
369  0.0,
370  0.0,
371  0.0,
372  1.0);
373 
374  matrix.translate(-eye.getX(), -eye.getY(), -eye.getZ());
375 
376  return (matrix);
377 }
378 
379 
380 //-------------------------------------------------------
382  double eyeY,
383  double eyeZ,
384  double centerX,
385  double centerY,
386  double centerZ,
387  double upX,
388  double upY,
389  double upZ)
390 //-------------------------------------------------------
391 {
392  return (buildLookAtModelViewMatrix(VEC3(eyeX, eyeY, eyeZ), VEC3(centerX, centerY, centerZ), VEC3(upX, upY, upZ)));
393 }
394 
395 
396 //-------------------------------------------------------
397 inline void loadLookAtModelViewMatrix(const VEC3& eye,
398  const VEC3& center,
399  const VEC3& up)
400 //-------------------------------------------------------
401 {
403 }
404 
405 
406 //---------------------------------------------------
407 inline void loadLookAtModelViewMatrix(double eyeX,
408  double eyeY,
409  double eyeZ,
410  double centerX,
411  double centerY,
412  double centerZ,
413  double upX,
414  double upY,
415  double upZ)
416 //---------------------------------------------------
417 {
419  eyeX, eyeY, eyeZ,
420  centerX, centerY, centerZ,
421  upX, upY, upZ);
422 }
423 
424 
425 //---------------------------------------------------------------
426 inline std::string getShaderTypeID(const std::type_info& aTypeID)
427 //---------------------------------------------------------------
428 {
429  if (aTypeID == typeid(unsigned int))
430  {
431  return std::string("r32ui");
432  }
433  else if (aTypeID == typeid(int))
434  {
435  return std::string("r32i");
436  }
437  else if (aTypeID == typeid(unsigned short))
438  {
439  return std::string("r16ui");
440  }
441  else if (aTypeID == typeid(short))
442  {
443  return std::string("r16i");
444  }
445  else if (aTypeID == typeid(unsigned char))
446  {
447  return std::string("r8ui");
448  }
449  else if (aTypeID == typeid(char))
450  {
451  return std::string("r8i");
452  }
453  else if (aTypeID == typeid(float))
454  {
455  return std::string("r32f");
456  }
457  else
458  {
459  throw Exception(__FILE__, __FUNCTION__, __LINE__,
460  "The data type of this image is not supported on GPU.");
461  }
462 }
463 
464 
465 //------------------------------------------------------------------
466 inline std::string getShaderImageType(const std::type_info& aTypeID)
467 //------------------------------------------------------------------
468 {
469  if (aTypeID == typeid(unsigned int))
470  {
471  return std::string("uimage3D");
472  }
473  else if (aTypeID == typeid(int))
474  {
475  return std::string("image3D");
476  }
477  else if (aTypeID == typeid(unsigned short))
478  {
479  return std::string("uimage3D");
480  }
481  else if (aTypeID == typeid(short))
482  {
483  return std::string("image3D");
484  }
485  else if (aTypeID == typeid(unsigned char))
486  {
487  return std::string("uimage3D");
488  }
489  else if (aTypeID == typeid(char))
490  {
491  return std::string("image3D");
492  }
493  else if (aTypeID == typeid(float))
494  {
495  return std::string("image3D");
496  }
497  else
498  {
499  throw Exception(__FILE__, __FUNCTION__, __LINE__,
500  "The data type of this image is not supported on GPU.");
501  }
502 }
503 
504 
505 //------------------------------------------------------------------
506 inline std::string getShaderPixelType(const std::type_info& aTypeID)
507 //------------------------------------------------------------------
508 {
509  if (aTypeID == typeid(unsigned int))
510  {
511  return std::string("uint");
512  }
513  else if (aTypeID == typeid(int))
514  {
515  return std::string("int");
516  }
517  else if (aTypeID == typeid(unsigned short))
518  {
519  return std::string("uint");
520  }
521  else if (aTypeID == typeid(short))
522  {
523  return std::string("int");
524  }
525  else if (aTypeID == typeid(unsigned char))
526  {
527  return std::string("uint");
528  }
529  else if (aTypeID == typeid(char))
530  {
531  return std::string("int");
532  }
533  else if (aTypeID == typeid(float))
534  {
535  return std::string("float");
536  }
537  else
538  {
539  throw Exception(__FILE__, __FUNCTION__, __LINE__,
540  "The data type of this image is not supported on GPU.");
541  }
542 }
543 
544 
545 //----------------------------------------------------------------------
546 inline std::string getShaderRGBAPixelType(const std::type_info& aTypeID)
547 //----------------------------------------------------------------------
548 {
549  if (aTypeID == typeid(unsigned int))
550  {
551  return std::string("uvec4");
552  }
553  else if (aTypeID == typeid(int))
554  {
555  return std::string("vec4");
556  }
557  else if (aTypeID == typeid(unsigned short))
558  {
559  return std::string("uvec4");
560  }
561  else if (aTypeID == typeid(short))
562  {
563  return std::string("vec4");
564  }
565  else if (aTypeID == typeid(unsigned char))
566  {
567  return std::string("uvec4");
568  }
569  else if (aTypeID == typeid(char))
570  {
571  return std::string("vec4");
572  }
573  else if (aTypeID == typeid(float))
574  {
575  return std::string("vec4");
576  }
577  else
578  {
579  throw Exception(__FILE__, __FUNCTION__, __LINE__,
580  "The data type of this image is not supported on GPU.");
581  }
582 }
583 
584 
585 //--------------------------------------------------------------
586 inline int getShaderOpenGLType(const std::type_info& aTypeID)
587 //--------------------------------------------------------------
588 {
589  if (aTypeID == typeid(unsigned int))
590  {
591  return GL_R32UI;
592  }
593  else if (aTypeID == typeid(int))
594  {
595  return GL_R32I;
596  }
597  else if (aTypeID == typeid(unsigned short))
598  {
599  return GL_R16UI;
600  }
601  else if (aTypeID == typeid(short))
602  {
603  return GL_R16I;
604  }
605  else if (aTypeID == typeid(unsigned char))
606  {
607  return GL_R8UI;
608  }
609  else if (aTypeID == typeid(char))
610  {
611  return GL_R8I;
612  }
613  else if (aTypeID == typeid(float))
614  {
615  return GL_R32F;
616  }
617  else
618  {
619  throw Exception(__FILE__, __FUNCTION__, __LINE__,
620  "The data type of this image is not supported on GPU.");
621  }
622 }
623 
624 
625 } // namespace gVirtualXRay
void pushProjectionMatrix()
Add the current matrix to the projection matrix stack.
void loadIdentity()
Load identity matrix.
Definition: Matrix4x4.inl:151
Type declarations.
void pushModelViewMatrix()
Add the current matrix to the model/view matrix stack.
void applyModelViewMatrix()
Class to handle exceptions related to OpenGL.
void multiplyPerspectiveProjectionMatrix(double fovy, double aspect, double zNear, double zFar)
MATRIX4 buildOrthoProjectionMatrix(double left, double right, double bottom, double top, double near, double far)
Create a orthographic projection matrix.
void loadPerspectiveProjectionMatrix(double fovy, double aspect, double zNear, double zFar)
Replace the projection matrix by a perspective projection matrix.
Vec3 is a template class to handle a 3D vector.
Definition: Vec3.h:88
T getX() const
Accessor on the position along the x-axis.
Definition: Vec3.inl:115
T getZ() const
Accessor on the position along the z-axis.
Definition: Vec3.inl:131
Exception is a class to handle exceptions.
Definition: Exception.h:109
Vec3 normal() const
Get the unit vector corresponding to the normed current vector.
Definition: Vec3.inl:147
std::string getShaderPixelType(const std::type_info &aTypeID)
Matrix4x4< RATIONAL_NUMBER > MATRIX4
Type of data used to store 4x4 matrices.
Definition: Types.h:119
const double Pi_2
Pi divided by 2.0.
std::string getShaderRGBAPixelType(const std::type_info &aTypeID)
T getY() const
Accessor on the position along the y-axis.
Definition: Vec3.inl:123
std::string getShaderImageType(const std::type_info &aTypeID)
void loadIdentityModelViewMatrix()
Replace the model/view matrix by the identity matrix.
Vec3< RATIONAL_NUMBER > VEC3
Type of data used to store 3D vectors.
Definition: Types.h:115
MATRIX4 g_current_projection_matrix
The projection matrix.
MATRIX4 buildFrustumProjectionMatrix(double left, double right, double bottom, double top, double near, double far)
Create a perspective projection matrix.
void loadOrthoProjectionMatrix(double left, double right, double bottom, double top, double near, double far)
Replace the projection matrix by a orthographic projection matrix.
void normalize()
Normalize the current vector so that its length is 1.
Definition: Vec3.inl:155
void multiplyOrthoProjectionMatrix(double left, double right, double bottom, double top, double nearPlane, double farPlane)
void popProjectionMatrix()
std::vector< MATRIX4 > g_p_projection_matrix_stack
The stack of projection matrix.
void loadIdentityProjectionMatrix()
Replace the projection matrix by the identity matrix.
std::vector< MATRIX4 > g_p_modelview_matrix_stack
The stack of model/view matrices.
std::string getShaderTypeID(const std::type_info &aTypeID)
MATRIX4 buildLookAtModelViewMatrix(const VEC3 &eye, const VEC3 &centre, const VEC3 &up)
Create a modelling-viewing matrix.
void loadFrustumProjectionMatrix(double left, double right, double bottom, double top, double near, double far)
Replace the projection matrix by a perspective projection matrix.
Class to handle exceptions when accessing an array cell that is not accessible, i.e. out of bounds memory access.
MATRIX4 g_current_modelview_matrix
The model/view matrices.
MATRIX4 buildPerspectiveProjectionMatrix(double fovy, double aspect, double zNear, double zFar)
Create a perspective projection matrix.
const double Pi
Pi.
int getShaderOpenGLType(const std::type_info &aTypeID)
Constant values, such as the Z number of different atoms, etc.
Matrix4x4 is a template class to handle a 4 by 4 matrix.
Definition: Matrix4x4.h:89
void popModelViewMatrix()
void loadLookAtModelViewMatrix(const VEC3 &eye, const VEC3 &centre, const VEC3 &up)
Replace the modelling-viewing matrix by a viewing transformation matrix.
Class to handle exceptions related to frame buffer objects (FBOs).