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