| 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 | |
| 20 | #ifndef _OpenGl_Context_H__ |
| 21 | #define _OpenGl_Context_H__ |
| 22 | |
| 23 | #include <Aspect_Handle.hxx> |
| 24 | #include <Aspect_Drawable.hxx> |
| 25 | #include <Aspect_Display.hxx> |
| 26 | #include <Aspect_RenderingContext.hxx> |
| 27 | #include <Handle_OpenGl_Context.hxx> |
| 28 | #include <NCollection_DataMap.hxx> |
| 29 | #include <NCollection_Handle.hxx> |
| 30 | #include <NCollection_Queue.hxx> |
| 31 | #include <OpenGl_Resource.hxx> |
| 32 | #include <Standard_Transient.hxx> |
| 33 | #include <TCollection_AsciiString.hxx> |
| 34 | #include <Handle_OpenGl_Context.hxx> |
| 35 | |
| 36 | //! Forward declarations |
| 37 | struct OpenGl_GlCore12; |
| 38 | struct OpenGl_GlCore13; |
| 39 | struct OpenGl_GlCore14; |
| 40 | struct OpenGl_GlCore15; |
| 41 | struct OpenGl_GlCore20; |
| 42 | struct OpenGl_ArbVBO; |
| 43 | struct OpenGl_ArbTBO; |
| 44 | struct OpenGl_ArbIns; |
| 45 | struct OpenGl_ExtFBO; |
| 46 | struct OpenGl_ExtGS; |
| 47 | |
| 48 | //! This class generalize access to the GL context and available extensions. |
| 49 | //! |
| 50 | //! Functions are grouped into structures and accessed as fields. |
| 51 | //! You should check the group for NULL before usage (if group is not NULL |
| 52 | //! then all functions are available): |
| 53 | //! @code |
| 54 | //! if (myContext->core20 != NULL) |
| 55 | //! { |
| 56 | //! myGlProgram = myContext->core20->glCreateProgram(); |
| 57 | //! .. do more stuff .. |
| 58 | //! } |
| 59 | //! else |
| 60 | //! { |
| 61 | //! .. compatibility with outdated configurations .. |
| 62 | //! } |
| 63 | //! @endcode |
| 64 | //! |
| 65 | //! Current implementation provide access to OpenGL core functionality up to 2.0 version |
| 66 | //! (core12, core13, core14, core15, fields core20). |
| 67 | //! within several extensions (arbVBO, extFBO, etc.). |
| 68 | //! |
| 69 | //! Simplified extensions classification: |
| 70 | //! - prefixed with NV, AMD, ATI are vendor-specific (however may be provided by other vendors in some cases); |
| 71 | //! - prefixed with EXT are accepted by 2+ vendors; |
| 72 | //! - prefixed with ARB are accepted by Architecture Review Board and are candidates |
| 73 | //! for inclusion into GL core functionality. |
| 74 | //! Some functionality can be represented in several extensions simultaneously. |
| 75 | //! In this case developer should be careful because different specification may differ |
| 76 | //! in aspects (like enumeration values and error-handling). |
| 77 | //! |
| 78 | //! Notice that some systems provide mechanisms to simultaneously incorporate with GL contexts |
| 79 | //! with different capabilities. Thats why OpenGl_Context should be initialized and used |
| 80 | //! for each GL context individually. |
| 81 | class OpenGl_Context : public Standard_Transient |
| 82 | { |
| 83 | public: |
| 84 | |
| 85 | //! Empty constructor. You should call Init() to perform initialization with bound GL context. |
| 86 | Standard_EXPORT OpenGl_Context(); |
| 87 | |
| 88 | //! Destructor. |
| 89 | Standard_EXPORT virtual ~OpenGl_Context(); |
| 90 | |
| 91 | //! Share GL context resources. |
| 92 | //! theShareCtx - handle to context to retrieve handles to shared resources. |
| 93 | Standard_EXPORT void Share (const Handle(OpenGl_Context)& theShareCtx); |
| 94 | |
| 95 | //! Initialize available extensions. |
| 96 | //! GL context should be active! |
| 97 | Standard_EXPORT Standard_Boolean Init(); |
| 98 | |
| 99 | #if (defined(_WIN32) || defined(__WIN32__)) |
| 100 | Standard_EXPORT Standard_Boolean Init (const Aspect_Handle theWindow, |
| 101 | const Aspect_Handle theWindowDC, |
| 102 | const Aspect_RenderingContext theGContext); |
| 103 | #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) |
| 104 | Standard_EXPORT Standard_Boolean Init (const void* theGContext); |
| 105 | #else |
| 106 | Standard_EXPORT Standard_Boolean Init (const Aspect_Drawable theWindow, |
| 107 | const Aspect_Display theDisplay, |
| 108 | const Aspect_RenderingContext theGContext); |
| 109 | #endif |
| 110 | |
| 111 | //! Check if theExtName extension is supported by active GL context. |
| 112 | Standard_EXPORT Standard_Boolean CheckExtension (const char* theExtName) const; |
| 113 | |
| 114 | //! Auxiliary template to retrieve GL function pointer. |
| 115 | //! Pointer to function retrieved from library is statically casted |
| 116 | //! to requested type - there no way to check real signature of exported function. |
| 117 | //! The context should be bound before call. |
| 118 | template <typename FuncType_t> |
| 119 | Standard_Boolean FindProc (const char* theFuncName, |
| 120 | FuncType_t& theFuncPtr) |
| 121 | { |
| 122 | theFuncPtr = (FuncType_t )findProc (theFuncName); |
| 123 | return (theFuncPtr != NULL); |
| 124 | } |
| 125 | |
| 126 | //! @return true if detected GL version is greater or equal to requested one. |
| 127 | inline Standard_Boolean IsGlGreaterEqual (const Standard_Integer theVerMajor, |
| 128 | const Standard_Integer theVerMinor) |
| 129 | { |
| 130 | return (myGlVerMajor > theVerMajor) |
| 131 | || (myGlVerMajor == theVerMajor && myGlVerMinor >= theVerMinor); |
| 132 | } |
| 133 | |
| 134 | //! Clean up errors stack for this GL context (glGetError() in loop). |
| 135 | Standard_EXPORT void ResetErrors(); |
| 136 | |
| 137 | //! This method uses system-dependent API to retrieve information |
| 138 | //! about GL context bound to the current thread. |
| 139 | //! @return true if current thread is bound to this GL context |
| 140 | Standard_EXPORT Standard_Boolean IsCurrent() const; |
| 141 | |
| 142 | //! Activates current context. |
| 143 | //! Class should be initialized with appropriate info. |
| 144 | Standard_EXPORT Standard_Boolean MakeCurrent(); |
| 145 | |
| 146 | //! Swap front/back buffers for this GL context (should be activated before!). |
| 147 | Standard_EXPORT void SwapBuffers(); |
| 148 | |
| 149 | //! Return true if active mode is GL_FEEDBACK (cached state) |
| 150 | Standard_EXPORT Standard_Boolean IsFeedback() const; |
| 151 | |
| 152 | //! Setup feedback mode cached state |
| 153 | Standard_EXPORT void SetFeedback (const Standard_Boolean theFeedbackOn); |
| 154 | |
| 155 | //! This function retrieves information from GL about free GPU memory that is: |
| 156 | //! - OS-dependent. On some OS it is per-process and on others - for entire system. |
| 157 | //! - Vendor-dependent. Currently available only on NVIDIA and AMD/ATi drivers only. |
| 158 | //! - Numbers meaning may vary. |
| 159 | //! You should use this info only for diagnostics purposes. |
| 160 | //! @return free GPU dedicated memory in bytes. |
| 161 | Standard_EXPORT Standard_Size AvailableMemory() const; |
| 162 | |
| 163 | //! This function retrieves information from GL about GPU memory |
| 164 | //! and contains more vendor-specific values than AvailableMemory(). |
| 165 | Standard_EXPORT TCollection_AsciiString MemoryInfo() const; |
| 166 | |
| 167 | //! Access shared resource by its name. |
| 168 | //! @param theKey - unique identifier; |
| 169 | //! @return handle to shared resource or NULL. |
| 170 | Standard_EXPORT const Handle(OpenGl_Resource)& GetResource (const TCollection_AsciiString& theKey) const; |
| 171 | |
| 172 | //! Access shared resource by its name. |
| 173 | //! @param theKey - unique identifier; |
| 174 | //! @param theValue - handle to fill; |
| 175 | //! @return true if resource was shared. |
| 176 | template<typename TheHandleType> |
| 177 | Standard_Boolean GetResource (const TCollection_AsciiString& theKey, |
| 178 | TheHandleType& theValue) const |
| 179 | { |
| 180 | const Handle(OpenGl_Resource)& aResource = GetResource (theKey); |
| 181 | if (aResource.IsNull()) |
| 182 | { |
| 183 | return Standard_False; |
| 184 | } |
| 185 | |
| 186 | theValue = TheHandleType::DownCast (aResource); |
| 187 | return !theValue.IsNull(); |
| 188 | } |
| 189 | |
| 190 | //! Register shared resource. |
| 191 | //! Notice that after registration caller shouldn't release it by himself - |
| 192 | //! it will be automatically released on context destruction. |
| 193 | //! @param theKey - unique identifier, shouldn't be empty; |
| 194 | //! @param theResource - new resource to register, shouldn't be NULL. |
| 195 | Standard_EXPORT Standard_Boolean ShareResource (const TCollection_AsciiString& theKey, |
| 196 | const Handle(OpenGl_Resource)& theResource); |
| 197 | |
| 198 | //! Release shared resource. |
| 199 | //! If there are more than one reference to this resource |
| 200 | //! (also used by some other existing object) then call will be ignored. |
| 201 | //! This means that current object itself should nullify handle before this call. |
| 202 | //! Notice that this is unrecommended operation at all and should be used |
| 203 | //! only in case of fat resources to release memory for other needs. |
| 204 | //! @param theKey - unique identifier. |
| 205 | Standard_EXPORT void ReleaseResource (const TCollection_AsciiString& theKey); |
| 206 | |
| 207 | //! Append resource to queue for delayed clean up. |
| 208 | //! Resources in this queue will be released at next redraw call. |
| 209 | Standard_EXPORT void DelayedRelease (Handle(OpenGl_Resource)& theResource); |
| 210 | |
| 211 | //! Clean up the delayed release queue. |
| 212 | Standard_EXPORT void ReleaseDelayed(); |
| 213 | |
| 214 | //! @return maximum degree of anisotropy texture filter |
| 215 | Standard_EXPORT Standard_Integer MaxDegreeOfAnisotropy() const; |
| 216 | |
| 217 | //! @return value for GL_MAX_TEXTURE_SIZE |
| 218 | Standard_EXPORT Standard_Integer MaxTextureSize() const; |
| 219 | |
| 220 | private: |
| 221 | |
| 222 | //! Wrapper to system function to retrieve GL function pointer by name. |
| 223 | Standard_EXPORT void* findProc (const char* theFuncName); |
| 224 | |
| 225 | //! Read OpenGL version information from active context. |
| 226 | Standard_EXPORT void readGlVersion(); |
| 227 | |
| 228 | //! Private initialization function that should be called only once. |
| 229 | Standard_EXPORT void init(); |
| 230 | |
| 231 | public: // core profiles |
| 232 | |
| 233 | OpenGl_GlCore12* core12; |
| 234 | OpenGl_GlCore13* core13; |
| 235 | OpenGl_GlCore14* core14; |
| 236 | OpenGl_GlCore15* core15; |
| 237 | OpenGl_GlCore20* core20; |
| 238 | |
| 239 | public: // extensions |
| 240 | |
| 241 | Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two |
| 242 | OpenGl_ArbVBO* arbVBO; //!< GL_ARB_vertex_buffer_object |
| 243 | OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object |
| 244 | OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced |
| 245 | OpenGl_ExtFBO* extFBO; //!< GL_EXT_framebuffer_object |
| 246 | OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4 |
| 247 | Standard_Boolean extBgra; //!< GL_EXT_bgra |
| 248 | Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic |
| 249 | Standard_Boolean atiMem; //!< GL_ATI_meminfo |
| 250 | Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info |
| 251 | |
| 252 | private: // system-dependent fields |
| 253 | |
| 254 | #if (defined(_WIN32) || defined(__WIN32__)) |
| 255 | Aspect_Handle myWindow; //!< window handle (owner of GL context) : HWND |
| 256 | Aspect_Handle myWindowDC; //!< Device Descriptor handle : HDC |
| 257 | Aspect_RenderingContext myGContext; //!< Rendering Context handle : HGLRC |
| 258 | #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) |
| 259 | void* myGContext; //!< Rendering Context handle : NSOpenGLContext |
| 260 | #else |
| 261 | Aspect_Drawable myWindow; //!< window handle (owner of GL context) : GLXDrawable |
| 262 | Aspect_Display myDisplay; //!< connection to the X-server : Display* |
| 263 | Aspect_RenderingContext myGContext; //!< X-GLX rendering context : GLXContext |
| 264 | #endif |
| 265 | |
| 266 | private: // context info |
| 267 | |
| 268 | typedef NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)> OpenGl_ResourcesMap; |
| 269 | typedef NCollection_Handle<OpenGl_ResourcesMap> Handle(OpenGl_ResourcesMap); |
| 270 | typedef NCollection_Queue<Handle(OpenGl_Resource)> OpenGl_ResourcesQueue; |
| 271 | typedef NCollection_Handle<OpenGl_ResourcesQueue> Handle(OpenGl_ResourcesQueue); |
| 272 | |
| 273 | Handle(OpenGl_ResourcesMap) mySharedResources; //!< shared resourced with unique identification key |
| 274 | Handle(OpenGl_ResourcesQueue) myReleaseQueue; //!< queue of resources for delayed clean up |
| 275 | |
| 276 | void* myGlLibHandle; //!< optional handle to GL library |
| 277 | OpenGl_GlCore20* myGlCore20; //!< common structure for GL core functions upto 2.0 |
| 278 | Standard_Integer myAnisoMax; //!< maximum level of anisotropy texture filter |
| 279 | Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE |
| 280 | Standard_Integer myGlVerMajor; //!< cached GL version major number |
| 281 | Standard_Integer myGlVerMinor; //!< cached GL version minor number |
| 282 | Standard_Boolean myIsFeedback; //!< flag indicates GL_FEEDBACK mode |
| 283 | Standard_Boolean myIsInitialized; //!< flag indicates initialization state |
| 284 | |
| 285 | private: |
| 286 | |
| 287 | //! Copying allowed only within Handles |
| 288 | OpenGl_Context (const OpenGl_Context& ); |
| 289 | OpenGl_Context& operator= (const OpenGl_Context& ); |
| 290 | |
| 291 | public: |
| 292 | |
| 293 | DEFINE_STANDARD_RTTI(OpenGl_Context) // Type definition |
| 294 | |
| 295 | friend class OpenGl_Window; |
| 296 | |
| 297 | }; |
| 298 | |
| 299 | #endif // _OpenGl_Context_H__ |