0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[occt.git] / src / OpenGl / OpenGl_Texture.hxx
1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2013-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _OpenGl_Texture_H__
16 #define _OpenGl_Texture_H__
17
18 #include <OpenGl_GlCore13.hxx>
19 #include <OpenGl_NamedResource.hxx>
20 #include <OpenGl_Sampler.hxx>
21 #include <Graphic3d_TypeOfTexture.hxx>
22 #include <Graphic3d_TextureUnit.hxx>
23
24 class Graphic3d_TextureParams;
25 class Image_PixMap;
26
27 //! Selects preferable texture format for specified parameters.
28 template<class T>
29 struct OpenGl_TextureFormatSelector
30 {
31   // Not implemented
32 };
33
34 template<>
35 struct OpenGl_TextureFormatSelector<GLubyte>
36 {
37   static GLint Internal (GLuint theChannels)
38   {
39     switch (theChannels)
40     {
41       case 1:
42         return GL_R8;
43       case 2:
44         return GL_RG8;
45       case 3:
46         return GL_RGB8;
47       case 4:
48         return GL_RGBA8;
49       default:
50         return GL_NONE;
51     }
52   }
53
54   static GLint DataType()
55   {
56     return GL_UNSIGNED_BYTE;
57   }
58 };
59
60 template<>
61 struct OpenGl_TextureFormatSelector<GLushort>
62 {
63   static GLint Internal (GLuint theChannels)
64   {
65     switch (theChannels)
66     {
67       case 1:
68         return GL_R16;
69       case 2:
70         return GL_RG16;
71       case 3:
72         return GL_RGB16;
73       case 4:
74         return GL_RGBA16;
75       default:
76         return GL_NONE;
77     }
78   }
79
80   static GLint DataType()
81   {
82     return GL_UNSIGNED_SHORT;
83   }
84 };
85
86 template<>
87 struct OpenGl_TextureFormatSelector<GLfloat>
88 {
89   static GLint Internal (GLuint theChannels)
90   {
91     switch (theChannels)
92     {
93       case 1:
94         return GL_R32F;
95       case 2:
96         return GL_RG32F;
97       case 3:
98         return GL_RGB32F;
99       case 4:
100         return GL_RGBA32F;
101       default:
102         return GL_NONE;
103     }
104   }
105
106   static GLint DataType()
107   {
108     return GL_FLOAT;
109   }
110 };
111
112 template<>
113 struct OpenGl_TextureFormatSelector<GLuint>
114 {
115   static GLint Internal (GLuint theChannels)
116   {
117     switch (theChannels)
118     {
119       case 1:
120         return GL_RED;
121       case 2:
122         return GL_RG;
123       case 3:
124         return GL_RGB;
125       case 4:
126         return GL_RGBA;
127       default:
128         return GL_NONE;
129     }
130   }
131
132   static GLint DataType()
133   {
134     return GL_UNSIGNED_INT;
135   }
136 };
137
138 //! Only unsigned formats are available in OpenGL ES 2.0
139 #if !defined(GL_ES_VERSION_2_0)
140 template<>
141 struct OpenGl_TextureFormatSelector<GLbyte>
142 {
143   static GLint Internal (GLuint theChannels)
144   {
145     switch (theChannels)
146     {
147       case 1:
148         return GL_R8_SNORM;
149       case 2:
150         return GL_RG8_SNORM;
151       case 3:
152         return GL_RGB8_SNORM;
153       case 4:
154         return GL_RGBA8_SNORM;
155       default:
156         return GL_NONE;
157     }
158   }
159
160   static GLint DataType()
161   {
162     return GL_BYTE;
163   }
164 };
165
166 template<>
167 struct OpenGl_TextureFormatSelector<GLshort>
168 {
169   static GLint Internal (GLuint theChannels)
170   {
171     switch (theChannels)
172     {
173       case 1:
174         return GL_R16_SNORM;
175       case 2:
176         return GL_RG16_SNORM;
177       case 3:
178         return GL_RGB16_SNORM;
179       case 4:
180         return GL_RGBA16_SNORM;
181       default:
182         return GL_NONE;
183     }
184   }
185
186   static GLint DataType()
187   {
188     return GL_SHORT;
189   }
190 };
191
192 template<>
193 struct OpenGl_TextureFormatSelector<GLint>
194 {
195   static GLint Internal (GLuint theChannels)
196   {
197     switch (theChannels)
198     {
199       case 1:
200         return GL_RED_SNORM;
201       case 2:
202         return GL_RG_SNORM;
203       case 3:
204         return GL_RGB_SNORM;
205       case 4:
206         return GL_RGBA_SNORM;
207       default:
208         return GL_NONE;
209     }
210   }
211
212   static GLint DataType()
213   {
214     return GL_INT;
215   }
216 };
217 #endif
218
219 //! Stores parameters of OpenGL texture format.
220 class OpenGl_TextureFormat
221 {
222   friend class OpenGl_Texture;
223
224 public:
225
226   //! Returns OpenGL format of the pixel data.
227   inline GLenum Format() const
228   {
229     switch (myChannels)
230     {
231       case 1:
232         return GL_RED;
233       case 2:
234         return GL_RG;
235       case 3:
236         return GL_RGB;
237       case 4:
238         return GL_RGBA;
239       default:
240         return GL_NONE;
241     }
242   }
243
244   //! Returns OpenGL internal format of the pixel data.
245   inline GLint Internal() const
246   {
247     return myInternal;
248   }
249
250   //! Returns OpenGL data type of the pixel data.
251   inline GLint DataType() const
252   {
253     return myDataType;
254   }
255
256   //! Returns texture format for specified type and number of channels.
257   template<class T, int N>
258   static OpenGl_TextureFormat Create()
259   {
260     return OpenGl_TextureFormat (N,
261                                  OpenGl_TextureFormatSelector<T>::Internal(N),
262                                  OpenGl_TextureFormatSelector<T>::DataType());
263   }
264
265 private:
266
267   //! Creates new texture format.
268   OpenGl_TextureFormat (const GLint theChannels,
269                         const GLint theInternal,
270                         const GLint theDataType)
271   : myInternal (theInternal),
272     myChannels (theChannels),
273     myDataType (theDataType) {}
274
275 private:
276
277   GLint myInternal; //!< OpenGL internal format of the pixel data
278   GLint myChannels; //!< Number of channels for each pixel (from 1 to 4)
279   GLint myDataType; //!< OpenGL data type of input pixel data
280
281 };
282
283 //! Texture resource.
284 class OpenGl_Texture : public OpenGl_NamedResource
285 {
286   DEFINE_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource)
287 public:
288
289   //! Helpful constants
290   static const GLuint NO_TEXTURE = 0;
291
292   //! Return pixel size of pixel format in bytes.
293   //! Note that this method considers that OpenGL natively supports this pixel format,
294   //! which might be not the case - in the latter case, actual pixel size might differ!
295   Standard_EXPORT static Standard_Size PixelSizeOfPixelFormat (Standard_Integer theInternalFormat);
296
297 public:
298
299   //! Create uninitialized texture.
300   Standard_EXPORT OpenGl_Texture (const TCollection_AsciiString& theResourceId = TCollection_AsciiString(),
301                                   const Handle(Graphic3d_TextureParams)& theParams = Handle(Graphic3d_TextureParams)());
302
303   //! Destroy object.
304   Standard_EXPORT virtual ~OpenGl_Texture();
305
306   //! @return true if current object was initialized
307   inline bool IsValid() const
308   {
309     return myTextureId != NO_TEXTURE;
310   }
311
312   //! @return target to which the texture is bound (GL_TEXTURE_1D, GL_TEXTURE_2D)
313   inline GLenum GetTarget() const
314   {
315     return myTarget;
316   }
317
318   //! @return texture width (0 LOD)
319   inline GLsizei SizeX() const
320   {
321     return mySizeX;
322   }
323
324   //! @return texture height (0 LOD)
325   inline GLsizei SizeY() const
326   {
327     return mySizeY;
328   }
329
330   //! @return texture ID
331   inline GLuint TextureId() const
332   {
333     return myTextureId;
334   }
335
336   //! @return texture format (not sized)
337   inline GLenum GetFormat() const
338   {
339     return myTextFormat;
340   }
341   
342   //! @return texture format (sized)
343   GLint SizedFormat() const
344   {
345     return mySizedFormat;
346   }
347
348   //! Return true for GL_RED and GL_ALPHA formats.
349   bool IsAlpha() const
350   {
351     return myIsAlpha;
352   }
353
354   //! Setup to interprete the format as Alpha by Shader Manager
355   //! (should be GL_ALPHA within compatible context or GL_RED otherwise).
356   void SetAlpha (const bool theValue)
357   {
358     myIsAlpha = theValue;
359   }
360
361   //! Creates Texture id if not yet generated.
362   //! Data should be initialized by another method.
363   Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theCtx);
364
365   //! Destroy object - will release GPU memory if any.
366   Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
367
368   //! Return texture sampler.
369   const Handle(OpenGl_Sampler)& Sampler() const { return mySampler; }
370
371   //! Set texture sampler.
372   void SetSampler (const Handle(OpenGl_Sampler)& theSampler) { mySampler = theSampler; }
373
374   //! Initialize the Sampler Object (as OpenGL object).
375   //! @param theCtx currently bound OpenGL context
376   Standard_EXPORT bool InitSamplerObject (const Handle(OpenGl_Context)& theCtx);
377
378   //! Bind this Texture to the unit specified in sampler parameters.
379   //! Also binds Sampler Object if it is allocated.
380   void Bind (const Handle(OpenGl_Context)& theCtx) const
381   {
382     Bind (theCtx, mySampler->Parameters()->TextureUnit());
383   }
384
385   //! Unbind texture from the unit specified in sampler parameters.
386   //! Also unbinds Sampler Object if it is allocated.
387   void Unbind (const Handle(OpenGl_Context)& theCtx) const
388   {
389     Unbind (theCtx, mySampler->Parameters()->TextureUnit());
390   }
391
392   //! Bind this Texture to specified unit.
393   //! Also binds Sampler Object if it is allocated.
394   Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx,
395                              const Graphic3d_TextureUnit   theTextureUnit) const;
396
397   //! Unbind texture from specified unit.
398   //! Also unbinds Sampler Object if it is allocated.
399   Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx,
400                                const Graphic3d_TextureUnit   theTextureUnit) const;
401
402   //! Revision of associated data source.
403   Standard_Size Revision() const { return myRevision; }
404
405   //! Set revision of associated data source.
406   void SetRevision (const Standard_Size theRevision) { myRevision = theRevision; }
407
408   //! Notice that texture will be unbound after this call.
409   Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
410                              const Image_PixMap&           theImage,
411                              const Graphic3d_TypeOfTexture theType);
412
413   //! Initialize the texture with specified format, size and texture type.
414   //! If theImage is empty the texture data will contain trash.
415   //! Notice that texture will be unbound after this call.
416   Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
417                              const GLint                   theTextFormat,
418                              const GLenum                  thePixelFormat,
419                              const GLenum                  theDataType,
420                              const GLsizei                 theSizeX,
421                              const GLsizei                 theSizeY,
422                              const Graphic3d_TypeOfTexture theType,
423                              const Image_PixMap*           theImage = NULL);
424
425   //! Initialize the 2D multisampling texture using glTexImage2DMultisample().
426   Standard_EXPORT bool Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
427                                           const GLsizei                 theNbSamples,
428                                           const GLint                   theTextFormat,
429                                           const GLsizei                 theSizeX,
430                                           const GLsizei                 theSizeY);
431
432   //! Allocates texture rectangle with specified format and size.
433   //! \note Texture data is not initialized (will contain trash).
434   Standard_EXPORT bool InitRectangle (const Handle(OpenGl_Context)& theCtx,
435                                       const Standard_Integer        theSizeX,
436                                       const Standard_Integer        theSizeY,
437                                       const OpenGl_TextureFormat&   theFormat);
438
439   //! Initializes 3D texture rectangle with specified format and size.
440   Standard_EXPORT bool Init3D (const Handle(OpenGl_Context)& theCtx,
441                                const GLint                   theTextFormat,
442                                const GLenum                  thePixelFormat,
443                                const GLenum                  theDataType,
444                                const Standard_Integer        theSizeX,
445                                const Standard_Integer        theSizeY,
446                                const Standard_Integer        theSizeZ,
447                                const void*                   thePixels);
448
449   //! @return true if texture was generated within mipmaps
450   Standard_Boolean HasMipmaps() const { return myHasMipmaps; }
451
452   //! Return texture type and format by Image_PixMap data format.
453   Standard_EXPORT static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
454                                              const Image_PixMap&           theData,
455                                              GLint&                        theTextFormat,
456                                              GLenum&                       thePixelFormat,
457                                              GLenum&                       theDataType);
458
459   //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
460   Standard_EXPORT virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE;
461
462   //! Returns TRUE for point sprite texture.
463   virtual bool IsPointSprite() const { return false; }
464
465 protected:
466
467   //! Apply default sampler parameters after texture creation.
468   Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
469
470 protected:
471
472   Handle(OpenGl_Sampler) mySampler; //!< texture sampler
473   Standard_Size    myRevision;   //!< revision of associated data source
474   GLuint           myTextureId;  //!< GL resource ID
475   GLenum           myTarget;     //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D
476   GLsizei          mySizeX;      //!< texture width
477   GLsizei          mySizeY;      //!< texture height
478   GLsizei          mySizeZ;      //!< texture depth
479   GLenum           myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
480   GLint            mySizedFormat;//!< internal (sized) texture format
481   Standard_Integer myNbSamples;  //!< number of MSAA samples
482   Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
483   bool             myIsAlpha;    //!< indicates alpha format
484
485 };
486
487 DEFINE_STANDARD_HANDLE(OpenGl_Texture, OpenGl_NamedResource)
488
489 #endif // _OpenGl_Texture_H__