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