NCBI C++ ToolKit
glutils.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: glutils.cpp 47292 2022-12-21 00:32:34Z evgeniev $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Mike DiCuccio
27  *
28  * File Description:
29  * OpenGL utility functions
30  */
31 
32 
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbifile.hpp>
35 #include <corelib/ncbi_system.hpp>
36 #include <gui/opengl.h>
37 #include <gui/opengl/glutils.hpp>
39 #ifdef NCBI_OS_DARWIN
40 #include <GLKit/GLKVector3.h>
41 #include <GLKit/GLKMatrix4.h>
42 #include <GLKit/GLKMathUtils.h>
43 #endif
44 
45 #ifdef GLEW_MX
46 GLEWContext* glewGetContext()
47 {
48  return NCBI_NS_NCBI::CGLGlewContext::GetInstance().GetGlewContext();
49 }
50 #endif
51 
53 
54 // static accelerated state - default to 'not determined'
56 
57 
58 
59 #ifdef GLEW_MX
60 CGLGlewContext& CGLGlewContext::GetInstance()
61 {
62  static CGLGlewContext instance;
63  return instance;
64 }
65 #endif
66 
67 
68 //
69 // access the accelerated flag
70 // this defaults to autodetect, and is user-overridable
71 //
73 {
74  if ( m_Accel != eNotDetermined ) {
75  return m_Accel;
76  }
77 
78  const char* str = reinterpret_cast<const char*> (glGetString(GL_RENDERER));
79  if ( !str ) {
80  return eNotDetermined;
81  }
82 
83  _TRACE("GL_VERSION = " << glGetString(GL_VERSION));
84  _TRACE("GL_RENDERER = " << glGetString(GL_RENDERER));
85  _TRACE("GL_EXTENSIONS = " << glGetString(GL_EXTENSIONS));
86 
87  // Solaris software renderer returns:
88  // GL_RENDERER = Sun dpa software renderer, VIS
89  string s(str);
90  if (s.find("software renderer") != string::npos) {
92  << "CGlUtils::GetAccelerated(): "
93  "auto-detected non-hardware-accelerated platform");
95  } else {
97  << "CGlUtils::GetAccelerated(): "
98  "auto-detected hardware-accelerated platform");
100  }
101 
102  return m_Accel;
103 }
104 
105 
106 //
107 // check for and report OpenGL errors
108 //
110 {
111  static EGlDiagMode mode = eUndefined;
112  if ( mode == eUndefined ) {
113  const char* value = getenv("NCBI_GBENCH_GLERROR");
114  if ( !value ) {
115  mode = eIgnore;
116  } else if (strcmp(value, "ABORT") == 0) {
117  mode = eAbort;
118  } else if (strcmp(value, "LOGPOST") == 0) {
119  mode = eLogPost;
120  } else if (strcmp(value, "THROW") == 0) {
121  mode = eThrow;
122  } else {
123  mode = eIgnore;
124  }
125  }
126 
127  return mode;
128 }
129 
131 {
132  string msg;
133  switch ( error ) {
134  default:
135  msg = "CGlUtils::CheckGlError(): unknown error";
136  break;
137 
138  case GL_INVALID_OPERATION:
139  msg = "CGlUtils::CheckGlError(): invalid operation";
140  break;
141 
142  case GL_INVALID_ENUM:
143  msg = "CGlUtils::CheckGlError(): invalid enum";
144  break;
145 
146  case GL_INVALID_VALUE:
147  msg = "CGlUtils::CheckGlError(): invalid value";
148  break;
149 
150  case GL_STACK_OVERFLOW:
151  msg = "CGlUtils::CheckGlError(): stack overflow";
152  break;
153 
154  case GL_STACK_UNDERFLOW:
155  msg = "CGlUtils::CheckGlError(): stack underflow";
156  break;
157 
158  case GL_OUT_OF_MEMORY:
159  msg = "CGlUtils::CheckGlError(): out of memory";
160  break;
161  }
162 
163  return msg;
164 }
165 
167 {
168  GLint error = glGetError();
169  if (error == GL_NO_ERROR) {
170  return false;
171  }
172 
174  string msg = GetErrMsg(error);
175 
176  switch (mode) {
177  case eUndefined:
178  case eIgnore:
179  default:
180  break;
181 
182  case eLogPost:
183  LOG_POST(Error << msg);
184  break;
185 
186  case eAbort:
187  // abort
188  LOG_POST(Error << msg);
189  Abort();
190  break;
191 
192  case eThrow:
193  // throw
194  NCBI_THROW(COpenGLException, eGlError, msg);
195  break;
196  }
197 
198  return true;
199 }
200 
201 
202 #ifdef _DEBUG
203 
204 //
205 // dumpState()
206 // this is a debugging function designed to show a bunch of OpenGL enables
207 //
209 {
210  LOG_POST(Info << "OpenGL Vendor: " << glGetString(GL_VENDOR));
211  LOG_POST(Info << "OpenGL Renderer: " << glGetString(GL_RENDERER));
212  LOG_POST(Info << "OpenGL Version: " << glGetString(GL_VERSION));
213  LOG_POST(Info << "OpenGL Extensions: " << glGetString(GL_EXTENSIONS));
214  LOG_POST(Info << "\n");
215 
216  GLint viewport[4];
217  float modelview[16];
218  float projection[16];
219  float color[4];
220 
221  glGetIntegerv(GL_VIEWPORT, viewport);
222  glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
223  glGetFloatv(GL_PROJECTION_MATRIX, projection);
224  glGetFloatv(GL_CURRENT_COLOR, color);
225 
226  GLint red_bits = 0;
227  GLint green_bits = 0;
228  GLint blue_bits = 0;
229  GLint alpha_bits = 0;
230  GLint depth_bits = 0;
231  GLint stencil_bits = 0;
232  glGetIntegerv(GL_RED_BITS, &red_bits);
233  glGetIntegerv(GL_GREEN_BITS, &green_bits);
234  glGetIntegerv(GL_BLUE_BITS, &blue_bits);
235  glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
236  glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
237  glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
238 
239  LOG_POST(Info << "Buffers:");
240  LOG_POST(Info << " Color:"
241  << " Red=" << red_bits << " bits"
242  << " Green=" << green_bits << " bits"
243  << " Blue=" << blue_bits << " bits"
244  << " Alpha=" << alpha_bits << " bits");
245  LOG_POST(Info << " Depth: " << depth_bits << " bits");
246  LOG_POST(Info << " Stencil: " << alpha_bits << " bits");
247 
248  LOG_POST(Info << "Viewport: "
249  << viewport[0] << ", " << viewport[1] << ", "
250  << viewport[2] << ", " << viewport[3]);
251 
252  int i;
253  int j;
254  LOG_POST(Info << "Projection matrix:");
255  for (i = 0; i < 4; ++i) {
256  string msg;
257  for (j = 0; j < 4; ++j) {
258  // remember, OpenGL matrices are transposed!
259  msg += NStr::DoubleToString(projection[j * 4+i]) + " ";
260  }
261  LOG_POST(Info << msg);
262  }
263 
264  LOG_POST(Info << "Modelview matrix:");
265  for (i = 0; i < 4; ++i) {
266  string msg;
267  for (j = 0; j < 4; ++j) {
268  // remember, OpenGL matrices are transposed!
269  msg += NStr::DoubleToString(modelview[j * 4+i]) + " ";
270  }
271  LOG_POST(Info << msg);
272  }
273 
274  LOG_POST(Info << "Current draw color: "
275  << color[0] << ", " << color[1] << ", "
276  << color[2] << ", " << color[3]);
277 
278  LOG_POST(Info << "Lighting: "
279  << (glIsEnabled(GL_LIGHTING) ? "enabled" : "disabled"));
280  LOG_POST(Info << "Depth Testing: "
281  << (glIsEnabled(GL_DEPTH_TEST) ? "enabled" : "disabled"));
282  LOG_POST(Info << "Face Culling: "
283  << (glIsEnabled(GL_CULL_FACE) ? "enabled" : "disabled"));
284  LOG_POST(Info << "Blending: "
285  << (glIsEnabled(GL_BLEND) ? "enabled" : "disabled"));
286  LOG_POST(Info << "Alpha Testing: "
287  << (glIsEnabled(GL_ALPHA_TEST) ? "enabled" : "disabled"));
288  LOG_POST(Info << "2D Texture: "
289  << (glIsEnabled(GL_TEXTURE_2D) ? "enabled" : "disabled"));
290 }
291 
292 #endif
293 
294 #ifdef NCBI_OS_DARWIN
295 
296 int gluProjectX(
297  GLdouble objx,
298  GLdouble objy,
299  GLdouble objz,
300  const GLdouble modelMatrix[16],
301  const GLdouble projMatrix[16],
302  const GLint viewport[4],
303  GLdouble* winx,
304  GLdouble* winy,
305  GLdouble* winz)
306 {
307  GLKVector3 object { (float)objx, (float)objy, (float)objz };
308  GLKMatrix4 model = GLKMatrix4Make(
309  modelMatrix[0], modelMatrix[1], modelMatrix[2], modelMatrix[3],
310  modelMatrix[4], modelMatrix[5], modelMatrix[6], modelMatrix[7],
311  modelMatrix[8], modelMatrix[9], modelMatrix[10], modelMatrix[11],
312  modelMatrix[12], modelMatrix[13], modelMatrix[14], modelMatrix[15]);
313  GLKMatrix4 projection = GLKMatrix4Make(
314  projMatrix[0], projMatrix[1], projMatrix[2], projMatrix[3],
315  projMatrix[4], projMatrix[5], projMatrix[6], projMatrix[7],
316  projMatrix[8], projMatrix[9], projMatrix[10], projMatrix[11],
317  projMatrix[12], projMatrix[13], projMatrix[14], projMatrix[15]);
318  GLKVector3 result = GLKMathProject(object, model, projection, const_cast<int*>(viewport));
319  *winx = result.x;
320  *winy = result.y;
321  *winz = result.z;
322  return GL_TRUE;
323 }
324 
325 int gluUnProjectX(
326  GLdouble winx,
327  GLdouble winy,
328  GLdouble winz,
329  const GLdouble modelMatrix[16],
330  const GLdouble projMatrix[16],
331  const GLint viewport[4],
332  GLdouble* objx,
333  GLdouble* objy,
334  GLdouble* objz)
335 {
336  GLKVector3 window{ (float)winx, (float)winy, (float)winz };
337  GLKMatrix4 model = GLKMatrix4Make(
338  modelMatrix[0], modelMatrix[1], modelMatrix[2], modelMatrix[3],
339  modelMatrix[4], modelMatrix[5], modelMatrix[6], modelMatrix[7],
340  modelMatrix[8], modelMatrix[9], modelMatrix[10], modelMatrix[11],
341  modelMatrix[12], modelMatrix[13], modelMatrix[14], modelMatrix[15]);
342  GLKMatrix4 projection = GLKMatrix4Make(
343  projMatrix[0], projMatrix[1], projMatrix[2], projMatrix[3],
344  projMatrix[4], projMatrix[5], projMatrix[6], projMatrix[7],
345  projMatrix[8], projMatrix[9], projMatrix[10], projMatrix[11],
346  projMatrix[12], projMatrix[13], projMatrix[14], projMatrix[15]);
347  bool success = false;
348  GLKVector3 result = GLKMathUnproject(window, model, projection, const_cast<int*>(viewport), &success);
349  *objx = result.x;
350  *objy = result.y;
351  *objz = result.z;
352  return (success ? GL_TRUE : GL_FALSE);
353 }
354 
355 #endif
356 
static const char * str(char *buf, int n)
Definition: stats.c:84
#define _TRACE(message)
Definition: ncbidbg.hpp:122
NCBI_XNCBI_EXPORT void Abort(void)
Smart abort function.
Definition: ncbidiag.cpp:8150
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
int gluProjectX(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz)
Definition: glutils.hpp:223
EAccelState
status of hardware acceleration.
Definition: glutils.hpp:58
static EAccelState m_Accel
Definition: glutils.hpp:96
static EGlDiagMode GetDiagnosticMode()
Get current diagnostic (error handling) mode.
Definition: glutils.cpp:109
static void DumpState()
Dump many of the most common OpenGL states.
Definition: glutils.cpp:208
static bool CheckGlError()
Check if there are any OpenGL errors.
Definition: glutils.cpp:166
static string GetErrMsg(GLint error)
Get message for specified OpenGL error.
Definition: glutils.cpp:130
int gluUnProjectX(GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz)
Definition: glutils.hpp:237
static EAccelState GetAccelerated(void)
Get the status of hardware acceleration.
Definition: glutils.cpp:72
@ eAccelerated
Definition: glutils.hpp:60
@ eNotAccelerated
Definition: glutils.hpp:61
@ eNotDetermined
Definition: glutils.hpp:59
@ eLogPost
Definition: glutils.hpp:68
@ eThrow
Definition: glutils.hpp:69
@ eUndefined
Definition: glutils.hpp:66
@ eAbort
Definition: glutils.hpp:70
@ eIgnore
Definition: glutils.hpp:67
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static string DoubleToString(double value, int precision=-1, TNumToStringFlags flags=0)
Convert double to string.
Definition: ncbistr.hpp:5181
n background color
int i
mdb_mode_t mode
Definition: lmdb++.h:38
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Standard mechanism to include OpenGL headers for all platforms.
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
else result
Definition: token2.c:20
Modified on Fri Sep 20 14:56:58 2024 by modify_doxy.py rev. 669887