Corrected integration.
[occt.git] / src / OpenGl / OpenGl_Context.cxx
CommitLineData
b311480e 1// Created on: 2012-01-26
2// Created by: Kirill GAVRILOV
3// Copyright (c) 2012-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
2166f0fa 20
5f8b738e 21#if (defined(_WIN32) || defined(__WIN32__))
22 #include <windows.h>
23#endif
24
2166f0fa
SK
25#include <OpenGl_Context.hxx>
26
5f8b738e 27#include <OpenGl_ArbVBO.hxx>
5e27df78 28#include <OpenGl_ArbTBO.hxx>
29#include <OpenGl_ArbIns.hxx>
5f8b738e 30#include <OpenGl_ExtFBO.hxx>
31#include <OpenGl_GlCore20.hxx>
32
2bd4c032 33#include <Standard_ProgramError.hxx>
34
5f8b738e 35#if (defined(_WIN32) || defined(__WIN32__))
36 //
37#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
38 #include <dlfcn.h>
39#else
40 #include <GL/glx.h> // glXGetProcAddress()
41#endif
42
f0430952 43// GL_NVX_gpu_memory_info
44#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
45 enum
46 {
47 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047,
48 GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048,
49 GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
50 GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A,
51 GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B
52 };
53#endif
54
2166f0fa
SK
55IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
56IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
57
5f8b738e 58//! Make record shorter to retrieve function pointer using variable with same name
59#define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
2166f0fa 60
5e27df78 61namespace
62{
63 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
64};
65
2166f0fa
SK
66// =======================================================================
67// function : OpenGl_Context
68// purpose :
69// =======================================================================
70OpenGl_Context::OpenGl_Context()
5f8b738e 71: core12 (NULL),
72 core13 (NULL),
73 core14 (NULL),
74 core15 (NULL),
75 core20 (NULL),
76 arbVBO (NULL),
5e27df78 77 arbTBO (NULL),
78 arbIns (NULL),
5f8b738e 79 extFBO (NULL),
f0430952 80 atiMem (Standard_False),
81 nvxMem (Standard_False),
5e27df78 82 mySharedResources (new OpenGl_ResourcesMap()),
83 myReleaseQueue (new OpenGl_ResourcesQueue()),
5f8b738e 84 myGlLibHandle (NULL),
85 myGlCore20 (NULL),
86 myGlVerMajor (0),
87 myGlVerMinor (0),
664cae74 88 myIsFeedback (Standard_False),
5f8b738e 89 myIsInitialized (Standard_False)
2166f0fa 90{
5f8b738e 91#if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
92 // Vendors can not extend functionality on this system
93 // and developers are limited to OpenGL support provided by Mac OS X SDK.
94 // We retrieve function pointers from system library
95 // to generalize extensions support on all platforms.
96 // In this way we also reach binary compatibility benefit between OS releases
97 // if some newest functionality is optionally used.
98 // Notice that GL version / extension availability checks are required
99 // because function pointers may be available but not functionality itself
100 // (depends on renderer).
101 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
102#endif
2166f0fa
SK
103}
104
105// =======================================================================
106// function : ~OpenGl_Context
107// purpose :
108// =======================================================================
109OpenGl_Context::~OpenGl_Context()
110{
5e27df78 111 // release clean up queue
112 ReleaseDelayed();
113
114 // release shared resources if any
115 if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
116 {
117 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
118 anIter.More(); anIter.Next())
119 {
120 anIter.Value()->Release (this);
121 }
122 }
123 mySharedResources.Nullify();
124
5f8b738e 125 delete myGlCore20;
126 delete arbVBO;
127 delete extFBO;
128}
129
5e27df78 130// =======================================================================
131// function : Share
132// purpose :
133// =======================================================================
134void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
135{
136 if (!theShareCtx.IsNull())
137 {
138 mySharedResources = theShareCtx->mySharedResources;
139 myReleaseQueue = theShareCtx->myReleaseQueue;
140 }
141}
142
86fa64d9 143// =======================================================================
144// function : IsCurrent
145// purpose :
146// =======================================================================
147Standard_Boolean OpenGl_Context::IsCurrent() const
148{
149#if (defined(_WIN32) || defined(__WIN32__))
150 if (myWindowDC == NULL || myGContext == NULL)
151 {
152 return Standard_False;
153 }
154 return (( (HDC )myWindowDC == wglGetCurrentDC())
155 && ((HGLRC )myGContext == wglGetCurrentContext()));
156#else
157 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
158 {
159 return Standard_False;
160 }
161
162 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
163 && ((GLXContext )myGContext == glXGetCurrentContext())
164 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
165#endif
166}
167
2bd4c032 168// =======================================================================
169// function : MakeCurrent
170// purpose :
171// =======================================================================
172Standard_Boolean OpenGl_Context::MakeCurrent()
173{
174#if (defined(_WIN32) || defined(__WIN32__))
86fa64d9 175 if (myWindowDC == NULL || myGContext == NULL)
2bd4c032 176 {
86fa64d9 177 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
178 return Standard_False;
179 }
180
181 // technically it should be safe to activate already bound GL context
182 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
183 if (IsCurrent())
184 {
185 return Standard_True;
186 }
187 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
188 {
189 // notice that glGetError() couldn't be used here!
190 wchar_t* aMsgBuff = NULL;
191 DWORD anErrorCode = GetLastError();
192 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
193 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
194 if (aMsgBuff != NULL)
195 {
196 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed. " << aMsgBuff << L" (" << int(anErrorCode) << L")\n";
197 LocalFree (aMsgBuff);
198 }
199 else
200 {
201 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed with #" << int(anErrorCode) << L" error code\n";
202 }
2bd4c032 203 return Standard_False;
204 }
205#else
86fa64d9 206 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
207 {
208 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
209 return Standard_False;
210 }
211
212 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
2bd4c032 213 {
214 // if there is no current context it might be impossible to use glGetError() correctly
215 //std::cerr << "glXMakeCurrent() failed!\n";
216 return Standard_False;
217 }
218#endif
219 return Standard_True;
220}
221
5e27df78 222// =======================================================================
223// function : SwapBuffers
224// purpose :
225// =======================================================================
226void OpenGl_Context::SwapBuffers()
227{
228#if (defined(_WIN32) || defined(__WIN32__))
229 if ((HDC )myWindowDC != NULL)
230 {
231 ::SwapBuffers ((HDC )myWindowDC);
232 glFlush();
233 }
234#else
235 if ((Display* )myDisplay != NULL)
236 {
237 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
238 }
239#endif
240}
241
5f8b738e 242// =======================================================================
243// function : findProc
244// purpose :
245// =======================================================================
246void* OpenGl_Context::findProc (const char* theFuncName)
247{
248#if (defined(_WIN32) || defined(__WIN32__))
249 return wglGetProcAddress (theFuncName);
250#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
251 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
252#else
253 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
254#endif
2166f0fa
SK
255}
256
257// =======================================================================
258// function : CheckExtension
259// purpose :
260// =======================================================================
2bd4c032 261Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
2166f0fa 262{
5f8b738e 263 if (theExtName == NULL)
264 {
265 std::cerr << "CheckExtension called with NULL string!\n";
266 return Standard_False;
267 }
268 int anExtNameLen = strlen (theExtName);
269
270 // available since OpenGL 3.0
271 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
2bd4c032 272 /**if (IsGlGreaterEqual (3, 0))
5f8b738e 273 {
274 GLint anExtNb = 0;
275 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
276 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
277 {
278 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
279 if (anExtension[anExtNameLen] == '\0' &&
280 strncmp (anExtension, theExtName, anExtNameLen) == 0)
281 {
282 return Standard_True;
283 }
284 }
285 return Standard_False;
286 }*/
287
288 // use old way with huge string for all extensions
289 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
290 if (anExtString == NULL)
291 {
292 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
2166f0fa
SK
293 return Standard_False;
294 }
295
296 // Search for theExtName in the extensions string.
297 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
5f8b738e 298 char* aPtrIter = (char* )anExtString;
299 const char* aPtrEnd = aPtrIter + strlen (anExtString);
2166f0fa
SK
300 while (aPtrIter < aPtrEnd)
301 {
302 int n = strcspn (aPtrIter, " ");
5f8b738e 303 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
304 {
2166f0fa 305 return Standard_True;
5f8b738e 306 }
2166f0fa
SK
307 aPtrIter += (n + 1);
308 }
309 return Standard_False;
310}
311
312// =======================================================================
313// function : Init
314// purpose :
315// =======================================================================
f0430952 316Standard_Boolean OpenGl_Context::Init()
2166f0fa 317{
2bd4c032 318 if (myIsInitialized)
5f8b738e 319 {
f0430952 320 return Standard_True;
5f8b738e 321 }
2bd4c032 322
323#if (defined(_WIN32) || defined(__WIN32__))
324 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
325 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
326#else
327 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
328 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
329 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
330#endif
f0430952 331 if (myGContext == NULL)
332 {
333 return Standard_False;
334 }
2bd4c032 335
336 init();
337 myIsInitialized = Standard_True;
f0430952 338 return Standard_True;
2bd4c032 339}
340
341// =======================================================================
342// function : Init
343// purpose :
344// =======================================================================
345#if (defined(_WIN32) || defined(__WIN32__))
f0430952 346Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
347 const Aspect_Handle theWindowDC,
348 const Aspect_RenderingContext theGContext)
2bd4c032 349#else
f0430952 350Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
351 const Aspect_Display theDisplay,
352 const Aspect_RenderingContext theGContext)
2bd4c032 353#endif
354{
355 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
356
357 myWindow = theWindow;
358 myGContext = theGContext;
359#if (defined(_WIN32) || defined(__WIN32__))
360 myWindowDC = theWindowDC;
361#else
362 myDisplay = theDisplay;
363#endif
86fa64d9 364 if (myGContext == NULL || !MakeCurrent())
f0430952 365 {
366 return Standard_False;
367 }
2bd4c032 368
369 init();
370 myIsInitialized = Standard_True;
f0430952 371 return Standard_True;
5f8b738e 372}
373
374// =======================================================================
375// function : ResetErrors
376// purpose :
377// =======================================================================
378void OpenGl_Context::ResetErrors()
379{
380 while (glGetError() != GL_NO_ERROR)
381 {
382 //
383 }
384}
385
386// =======================================================================
387// function : readGlVersion
388// purpose :
389// =======================================================================
390void OpenGl_Context::readGlVersion()
391{
392 // reset values
393 myGlVerMajor = 0;
394 myGlVerMinor = 0;
395
396 // available since OpenGL 3.0
397 GLint aMajor, aMinor;
398 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
399 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
400 if (glGetError() == GL_NO_ERROR)
401 {
402 myGlVerMajor = aMajor;
403 myGlVerMinor = aMinor;
404 return;
405 }
406 ResetErrors();
407
408 // Read version string.
409 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
410 // Following trash (after space) is vendor-specific.
411 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
412 // and should be considered as vendor-specific too.
413 const char* aVerStr = (const char* )glGetString (GL_VERSION);
414 if (aVerStr == NULL || *aVerStr == '\0')
415 {
416 // invalid GL context
417 return;
418 }
419
420 // parse string for major number
421 char aMajorStr[32];
422 char aMinorStr[32];
423 size_t aMajIter = 0;
424 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
425 {
426 ++aMajIter;
427 }
428 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
429 {
430 return;
431 }
432 memcpy (aMajorStr, aVerStr, aMajIter);
433 aMajorStr[aMajIter] = '\0';
434
435 // parse string for minor number
436 size_t aMinIter = aMajIter + 1;
437 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
438 {
439 ++aMinIter;
440 }
441 size_t aMinLen = aMinIter - aMajIter - 1;
442 if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
443 {
444 return;
445 }
446 memcpy (aMinorStr, aVerStr, aMinLen);
447 aMinorStr[aMinLen] = '\0';
448
449 // read numbers
450 myGlVerMajor = atoi (aMajorStr);
451 myGlVerMinor = atoi (aMinorStr);
452
453 if (myGlVerMajor <= 0)
454 {
455 myGlVerMajor = 0;
456 myGlVerMinor = 0;
457 }
458}
459
460// =======================================================================
461// function : init
462// purpose :
463// =======================================================================
464void OpenGl_Context::init()
465{
466 // read version
467 readGlVersion();
468
f0430952 469 atiMem = CheckExtension ("GL_ATI_meminfo");
470 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
471
5f8b738e 472 // initialize VBO extension (ARB)
473 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
2166f0fa
SK
474 {
475 arbVBO = new OpenGl_ArbVBO();
5f8b738e 476 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
477 if (!FindProcShort (arbVBO, glGenBuffersARB)
478 || !FindProcShort (arbVBO, glBindBufferARB)
479 || !FindProcShort (arbVBO, glBufferDataARB)
480 || !FindProcShort (arbVBO, glDeleteBuffersARB))
2166f0fa
SK
481 {
482 delete arbVBO;
483 arbVBO = NULL;
484 }
485 }
486
5e27df78 487 // initialize TBO extension (ARB)
488 if (CheckExtension ("GL_ARB_texture_buffer_object"))
489 {
490 arbTBO = new OpenGl_ArbTBO();
491 memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
492 if (!FindProcShort (arbTBO, glTexBufferARB))
493 {
494 delete arbTBO;
495 arbTBO = NULL;
496 }
497 }
498
499 // initialize hardware instancing extension (ARB)
500 if (CheckExtension ("GL_ARB_draw_instanced"))
501 {
502 arbIns = new OpenGl_ArbIns();
503 memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
504 if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
505 || !FindProcShort (arbIns, glDrawElementsInstancedARB))
506 {
507 delete arbIns;
508 arbIns = NULL;
509 }
510 }
511
5f8b738e 512 // initialize FBO extension (EXT)
513 if (CheckExtension ("GL_EXT_framebuffer_object"))
2166f0fa
SK
514 {
515 extFBO = new OpenGl_ExtFBO();
5f8b738e 516 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
517 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
518 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
519 || !FindProcShort (extFBO, glBindFramebufferEXT)
520 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
521 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
522 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
523 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
524 || !FindProcShort (extFBO, glBindRenderbufferEXT)
525 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
526 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
2166f0fa
SK
527 {
528 delete extFBO;
529 extFBO = NULL;
530 }
531 }
5f8b738e 532
533 myGlCore20 = new OpenGl_GlCore20();
534 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
535
536 // initialize OpenGL 1.2 core functionality
2bd4c032 537 if (IsGlGreaterEqual (1, 2))
5f8b738e 538 {
539 if (!FindProcShort (myGlCore20, glBlendColor)
540 || !FindProcShort (myGlCore20, glBlendEquation)
541 || !FindProcShort (myGlCore20, glDrawRangeElements)
542 || !FindProcShort (myGlCore20, glTexImage3D)
543 || !FindProcShort (myGlCore20, glTexSubImage3D)
544 || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
545 {
546 myGlVerMajor = 1;
547 myGlVerMinor = 1;
548 }
549 }
550
551 // initialize OpenGL 1.3 core functionality
2bd4c032 552 if (IsGlGreaterEqual (1, 3))
5f8b738e 553 {
554 if (!FindProcShort (myGlCore20, glActiveTexture)
555 || !FindProcShort (myGlCore20, glSampleCoverage)
556 || !FindProcShort (myGlCore20, glCompressedTexImage3D)
557 || !FindProcShort (myGlCore20, glCompressedTexImage2D)
558 || !FindProcShort (myGlCore20, glCompressedTexImage1D)
559 || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
560 || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
561 || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
562 || !FindProcShort (myGlCore20, glGetCompressedTexImage)
563 // deprecated
564 || !FindProcShort (myGlCore20, glClientActiveTexture)
565 || !FindProcShort (myGlCore20, glMultiTexCoord1d)
566 || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
567 || !FindProcShort (myGlCore20, glMultiTexCoord1f)
568 || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
569 || !FindProcShort (myGlCore20, glMultiTexCoord1i)
570 || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
571 || !FindProcShort (myGlCore20, glMultiTexCoord1s)
572 || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
573 || !FindProcShort (myGlCore20, glMultiTexCoord2d)
574 || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
575 || !FindProcShort (myGlCore20, glMultiTexCoord2f)
576 || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
577 || !FindProcShort (myGlCore20, glMultiTexCoord2i)
578 || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
579 || !FindProcShort (myGlCore20, glMultiTexCoord2s)
580 || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
581 || !FindProcShort (myGlCore20, glMultiTexCoord3d)
582 || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
583 || !FindProcShort (myGlCore20, glMultiTexCoord3f)
584 || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
585 || !FindProcShort (myGlCore20, glMultiTexCoord3i)
586 || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
587 || !FindProcShort (myGlCore20, glMultiTexCoord3s)
588 || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
589 || !FindProcShort (myGlCore20, glMultiTexCoord4d)
590 || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
591 || !FindProcShort (myGlCore20, glMultiTexCoord4f)
592 || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
593 || !FindProcShort (myGlCore20, glMultiTexCoord4i)
594 || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
595 || !FindProcShort (myGlCore20, glMultiTexCoord4s)
596 || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
597 || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
598 || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
599 || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
600 || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
601 {
602 myGlVerMajor = 1;
603 myGlVerMinor = 2;
604 core12 = myGlCore20;
605 }
606 }
607
608 // initialize OpenGL 1.4 core functionality
2bd4c032 609 if (IsGlGreaterEqual (1, 4))
5f8b738e 610 {
611 if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
612 || !FindProcShort (myGlCore20, glMultiDrawArrays)
613 || !FindProcShort (myGlCore20, glMultiDrawElements)
614 || !FindProcShort (myGlCore20, glPointParameterf)
615 || !FindProcShort (myGlCore20, glPointParameterfv)
616 || !FindProcShort (myGlCore20, glPointParameteri)
617 || !FindProcShort (myGlCore20, glPointParameteriv))
618 {
619 myGlVerMajor = 1;
620 myGlVerMinor = 3;
621 core12 = myGlCore20;
622 core13 = myGlCore20;
623 }
624 }
625
626 // initialize OpenGL 1.5 core functionality
2bd4c032 627 if (IsGlGreaterEqual (1, 5))
5f8b738e 628 {
629 if (!FindProcShort (myGlCore20, glGenQueries)
630 || !FindProcShort (myGlCore20, glDeleteQueries)
631 || !FindProcShort (myGlCore20, glIsQuery)
632 || !FindProcShort (myGlCore20, glBeginQuery)
633 || !FindProcShort (myGlCore20, glEndQuery)
634 || !FindProcShort (myGlCore20, glGetQueryiv)
635 || !FindProcShort (myGlCore20, glGetQueryObjectiv)
636 || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
637 || !FindProcShort (myGlCore20, glBindBuffer)
638 || !FindProcShort (myGlCore20, glDeleteBuffers)
639 || !FindProcShort (myGlCore20, glGenBuffers)
640 || !FindProcShort (myGlCore20, glIsBuffer)
641 || !FindProcShort (myGlCore20, glBufferData)
642 || !FindProcShort (myGlCore20, glBufferSubData)
643 || !FindProcShort (myGlCore20, glGetBufferSubData)
644 || !FindProcShort (myGlCore20, glMapBuffer)
645 || !FindProcShort (myGlCore20, glUnmapBuffer)
646 || !FindProcShort (myGlCore20, glGetBufferParameteriv)
647 || !FindProcShort (myGlCore20, glGetBufferPointerv))
648 {
649 myGlVerMajor = 1;
650 myGlVerMinor = 4;
651 core12 = myGlCore20;
652 core13 = myGlCore20;
653 core14 = myGlCore20;
654 }
655 }
656
657 // initialize OpenGL 2.0 core functionality
2bd4c032 658 if (IsGlGreaterEqual (2, 0))
5f8b738e 659 {
660 if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
661 || !FindProcShort (myGlCore20, glDrawBuffers)
662 || !FindProcShort (myGlCore20, glStencilOpSeparate)
663 || !FindProcShort (myGlCore20, glStencilFuncSeparate)
664 || !FindProcShort (myGlCore20, glStencilMaskSeparate)
665 || !FindProcShort (myGlCore20, glAttachShader)
666 || !FindProcShort (myGlCore20, glBindAttribLocation)
667 || !FindProcShort (myGlCore20, glCompileShader)
668 || !FindProcShort (myGlCore20, glCreateProgram)
669 || !FindProcShort (myGlCore20, glCreateShader)
670 || !FindProcShort (myGlCore20, glDeleteProgram)
671 || !FindProcShort (myGlCore20, glDeleteShader)
672 || !FindProcShort (myGlCore20, glDetachShader)
673 || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
674 || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
675 || !FindProcShort (myGlCore20, glGetActiveAttrib)
676 || !FindProcShort (myGlCore20, glGetActiveUniform)
677 || !FindProcShort (myGlCore20, glGetAttachedShaders)
678 || !FindProcShort (myGlCore20, glGetAttribLocation)
679 || !FindProcShort (myGlCore20, glGetProgramiv)
680 || !FindProcShort (myGlCore20, glGetProgramInfoLog)
681 || !FindProcShort (myGlCore20, glGetShaderiv)
682 || !FindProcShort (myGlCore20, glGetShaderInfoLog)
683 || !FindProcShort (myGlCore20, glGetShaderSource)
684 || !FindProcShort (myGlCore20, glGetUniformLocation)
685 || !FindProcShort (myGlCore20, glGetUniformfv)
686 || !FindProcShort (myGlCore20, glGetUniformiv)
687 || !FindProcShort (myGlCore20, glGetVertexAttribdv)
688 || !FindProcShort (myGlCore20, glGetVertexAttribfv)
689 || !FindProcShort (myGlCore20, glGetVertexAttribiv)
690 || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
691 || !FindProcShort (myGlCore20, glIsProgram)
692 || !FindProcShort (myGlCore20, glIsShader)
693 || !FindProcShort (myGlCore20, glLinkProgram)
694 || !FindProcShort (myGlCore20, glShaderSource)
695 || !FindProcShort (myGlCore20, glUseProgram)
696 || !FindProcShort (myGlCore20, glUniform1f)
697 || !FindProcShort (myGlCore20, glUniform2f)
698 || !FindProcShort (myGlCore20, glUniform3f)
699 || !FindProcShort (myGlCore20, glUniform4f)
700 || !FindProcShort (myGlCore20, glUniform1i)
701 || !FindProcShort (myGlCore20, glUniform2i)
702 || !FindProcShort (myGlCore20, glUniform3i)
703 || !FindProcShort (myGlCore20, glUniform4i)
704 || !FindProcShort (myGlCore20, glUniform1fv)
705 || !FindProcShort (myGlCore20, glUniform2fv)
706 || !FindProcShort (myGlCore20, glUniform3fv)
707 || !FindProcShort (myGlCore20, glUniform4fv)
708 || !FindProcShort (myGlCore20, glUniform1iv)
709 || !FindProcShort (myGlCore20, glUniform2iv)
710 || !FindProcShort (myGlCore20, glUniform3iv)
711 || !FindProcShort (myGlCore20, glUniform4iv)
712 || !FindProcShort (myGlCore20, glUniformMatrix2fv)
713 || !FindProcShort (myGlCore20, glUniformMatrix3fv)
714 || !FindProcShort (myGlCore20, glUniformMatrix4fv)
715 || !FindProcShort (myGlCore20, glValidateProgram)
716 || !FindProcShort (myGlCore20, glVertexAttrib1d)
717 || !FindProcShort (myGlCore20, glVertexAttrib1dv)
718 || !FindProcShort (myGlCore20, glVertexAttrib1f)
719 || !FindProcShort (myGlCore20, glVertexAttrib1fv)
720 || !FindProcShort (myGlCore20, glVertexAttrib1s)
721 || !FindProcShort (myGlCore20, glVertexAttrib1sv)
722 || !FindProcShort (myGlCore20, glVertexAttrib2d)
723 || !FindProcShort (myGlCore20, glVertexAttrib2dv)
724 || !FindProcShort (myGlCore20, glVertexAttrib2f)
725 || !FindProcShort (myGlCore20, glVertexAttrib2fv)
726 || !FindProcShort (myGlCore20, glVertexAttrib2s)
727 || !FindProcShort (myGlCore20, glVertexAttrib2sv)
728 || !FindProcShort (myGlCore20, glVertexAttrib3d)
729 || !FindProcShort (myGlCore20, glVertexAttrib3dv)
730 || !FindProcShort (myGlCore20, glVertexAttrib3f)
731 || !FindProcShort (myGlCore20, glVertexAttrib3fv)
732 || !FindProcShort (myGlCore20, glVertexAttrib3s)
733 || !FindProcShort (myGlCore20, glVertexAttrib3sv)
734 || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
735 || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
736 || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
737 || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
738 || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
739 || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
740 || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
741 || !FindProcShort (myGlCore20, glVertexAttrib4bv)
742 || !FindProcShort (myGlCore20, glVertexAttrib4d)
743 || !FindProcShort (myGlCore20, glVertexAttrib4dv)
744 || !FindProcShort (myGlCore20, glVertexAttrib4f)
745 || !FindProcShort (myGlCore20, glVertexAttrib4fv)
746 || !FindProcShort (myGlCore20, glVertexAttrib4iv)
747 || !FindProcShort (myGlCore20, glVertexAttrib4s)
748 || !FindProcShort (myGlCore20, glVertexAttrib4sv)
749 || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
750 || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
751 || !FindProcShort (myGlCore20, glVertexAttrib4usv)
752 || !FindProcShort (myGlCore20, glVertexAttribPointer))
753 {
754 myGlVerMajor = 1;
755 myGlVerMinor = 5;
756 core12 = myGlCore20;
757 core13 = myGlCore20;
758 core14 = myGlCore20;
759 core15 = myGlCore20;
760 }
761 }
762
2bd4c032 763 if (IsGlGreaterEqual (2, 0))
5f8b738e 764 {
765 core12 = myGlCore20;
766 core13 = myGlCore20;
767 core14 = myGlCore20;
768 core15 = myGlCore20;
769 core20 = myGlCore20;
770 }
2166f0fa 771}
664cae74 772// =======================================================================
773// function : IsFeedback
774// purpose :
775// =======================================================================
776Standard_Boolean OpenGl_Context::IsFeedback() const
777{
778 return myIsFeedback;
779}
780
781// =======================================================================
782// function : SetFeedback
783// purpose :
784// =======================================================================
785void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
786{
787 myIsFeedback = theFeedbackOn;
788}
f0430952 789
790// =======================================================================
791// function : MemoryInfo
792// purpose :
793// =======================================================================
794Standard_Size OpenGl_Context::AvailableMemory() const
795{
796 if (atiMem)
797 {
798 // this is actually information for VBO pool
799 // however because pools are mostly shared
800 // it can be used for total GPU memory estimations
801 GLint aMemInfo[4];
802 aMemInfo[0] = 0;
803 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
804 // returned value is in KiB, however this maybe changed in future
805 return Standard_Size(aMemInfo[0]) * 1024;
806 }
807 else if (nvxMem)
808 {
809 // current available dedicated video memory (in KiB), currently unused GPU memory
810 GLint aMemInfo = 0;
811 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
812 return Standard_Size(aMemInfo) * 1024;
813 }
814 return 0;
815}
816
817// =======================================================================
818// function : MemoryInfo
819// purpose :
820// =======================================================================
821TCollection_AsciiString OpenGl_Context::MemoryInfo() const
822{
823 TCollection_AsciiString anInfo;
824 if (atiMem)
825 {
826 GLint aValues[4];
827 memset (aValues, 0, sizeof(aValues));
828 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
829
830 // total memory free in the pool
831 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
832
833 // largest available free block in the pool
834 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
835 if (aValues[2] != aValues[0])
836 {
837 // total auxiliary memory free
838 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
839 }
840 }
841 else if (nvxMem)
842 {
843 //current available dedicated video memory (in KiB), currently unused GPU memory
844 GLint aValue = 0;
845 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
846 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
847
848 // dedicated video memory, total size (in KiB) of the GPU memory
849 GLint aDedicated = 0;
850 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
851 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
852
853 // total available memory, total size (in KiB) of the memory available for allocations
854 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
855 if (aValue != aDedicated)
856 {
857 // different only for special configurations
858 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
859 }
860 }
861 return anInfo;
862}
5e27df78 863
864
865// =======================================================================
866// function : GetResource
867// purpose :
868// =======================================================================
869const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
870{
871 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
872}
873
874// =======================================================================
875// function : ShareResource
876// purpose :
877// =======================================================================
878Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
879 const Handle(OpenGl_Resource)& theResource)
880{
881 if (theKey.IsEmpty() || theResource.IsNull())
882 {
883 return Standard_False;
884 }
885 return mySharedResources->Bind (theKey, theResource);
886}
887
888// =======================================================================
889// function : ReleaseResource
890// purpose :
891// =======================================================================
892void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
893{
894 if (!mySharedResources->IsBound (theKey))
895 {
896 return;
897 }
898 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
899 if (aRes->GetRefCount() > 1)
900 {
901 return;
902 }
903
904 aRes->Release (this);
905 mySharedResources->UnBind (theKey);
906}
907
908// =======================================================================
909// function : DelayedRelease
910// purpose :
911// =======================================================================
912void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
913{
914 myReleaseQueue->Push (theResource);
915 theResource.Nullify();
916}
917
918// =======================================================================
919// function : ReleaseDelayed
920// purpose :
921// =======================================================================
922void OpenGl_Context::ReleaseDelayed()
923{
924 while (!myReleaseQueue->IsEmpty())
925 {
926 myReleaseQueue->Front()->Release (this);
927 myReleaseQueue->Pop();
928 }
929}