da9ec7bb786803bf399877ef1841350978166dcc
[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 true for GL_RED and GL_ALPHA formats.
343   bool IsAlpha() const
344   {
345     return myIsAlpha;
346   }
347
348   //! Setup to interprete the format as Alpha by Shader Manager
349   //! (should be GL_ALPHA within compatible context or GL_RED otherwise).
350   void SetAlpha (const bool theValue)
351   {
352     myIsAlpha = theValue;
353   }
354
355   //! Creates Texture id if not yet generated.
356   //! Data should be initialized by another method.
357   Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theCtx);
358
359   //! Destroy object - will release GPU memory if any.
360   Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
361
362   //! Return texture sampler.
363   const Handle(OpenGl_Sampler)& Sampler() const { return mySampler; }
364
365   //! Set texture sampler.
366   void SetSampler (const Handle(OpenGl_Sampler)& theSampler) { mySampler = theSampler; }
367
368   //! Initialize the Sampler Object (as OpenGL object).
369   //! @param theCtx currently bound OpenGL context
370   Standard_EXPORT bool InitSamplerObject (const Handle(OpenGl_Context)& theCtx);
371
372   //! Bind this Texture to the unit specified in sampler parameters.
373   //! Also binds Sampler Object if it is allocated.
374   void Bind (const Handle(OpenGl_Context)& theCtx) const
375   {
376     Bind (theCtx, mySampler->Parameters()->TextureUnit());
377   }
378
379   //! Unbind texture from the unit specified in sampler parameters.
380   //! Also unbinds Sampler Object if it is allocated.
381   void Unbind (const Handle(OpenGl_Context)& theCtx) const
382   {
383     Unbind (theCtx, mySampler->Parameters()->TextureUnit());
384   }
385
386   //! Bind this Texture to specified unit.
387   //! Also binds Sampler Object if it is allocated.
388   Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx,
389                              const Graphic3d_TextureUnit   theTextureUnit) const;
390
391   //! Unbind texture from specified unit.
392   //! Also unbinds Sampler Object if it is allocated.
393   Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx,
394                                const Graphic3d_TextureUnit   theTextureUnit) const;
395
396   //! Revision of associated data source.
397   Standard_Size Revision() const { return myRevision; }
398
399   //! Set revision of associated data source.
400   void SetRevision (const Standard_Size theRevision) { myRevision = theRevision; }
401
402   //! Notice that texture will be unbound after this call.
403   Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
404                              const Image_PixMap&           theImage,
405                              const Graphic3d_TypeOfTexture theType);
406
407   //! Initialize the texture with specified format, size and texture type.
408   //! If theImage is empty the texture data will contain trash.
409   //! Notice that texture will be unbound after this call.
410   Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
411                              const GLint                   theTextFormat,
412                              const GLenum                  thePixelFormat,
413                              const GLenum                  theDataType,
414                              const GLsizei                 theSizeX,
415                              const GLsizei                 theSizeY,
416                              const Graphic3d_TypeOfTexture theType,
417                              const Image_PixMap*           theImage = NULL);
418
419   //! Initialize the 2D multisampling texture using glTexImage2DMultisample().
420   Standard_EXPORT bool Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
421                                           const GLsizei                 theNbSamples,
422                                           const GLint                   theTextFormat,
423                                           const GLsizei                 theSizeX,
424                                           const GLsizei                 theSizeY);
425
426   //! Allocates texture rectangle with specified format and size.
427   //! \note Texture data is not initialized (will contain trash).
428   Standard_EXPORT bool InitRectangle (const Handle(OpenGl_Context)& theCtx,
429                                       const Standard_Integer        theSizeX,
430                                       const Standard_Integer        theSizeY,
431                                       const OpenGl_TextureFormat&   theFormat);
432
433   //! Initializes 3D texture rectangle with specified format and size.
434   Standard_EXPORT bool Init3D (const Handle(OpenGl_Context)& theCtx,
435                                const GLint                   theTextFormat,
436                                const GLenum                  thePixelFormat,
437                                const GLenum                  theDataType,
438                                const Standard_Integer        theSizeX,
439                                const Standard_Integer        theSizeY,
440                                const Standard_Integer        theSizeZ,
441                                const void*                   thePixels);
442
443   //! @return true if texture was generated within mipmaps
444   Standard_Boolean HasMipmaps() const { return myHasMipmaps; }
445
446   //! Return texture type and format by Image_PixMap data format.
447   Standard_EXPORT static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
448                                              const Image_PixMap&           theData,
449                                              GLint&                        theTextFormat,
450                                              GLenum&                       thePixelFormat,
451                                              GLenum&                       theDataType);
452
453   //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
454   Standard_EXPORT virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE;
455
456 protected:
457
458   //! Apply default sampler parameters after texture creation.
459   Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
460
461 protected:
462
463   Handle(OpenGl_Sampler) mySampler; //!< texture sampler
464   Standard_Size    myRevision;   //!< revision of associated data source
465   GLuint           myTextureId;  //!< GL resource ID
466   GLenum           myTarget;     //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D
467   GLsizei          mySizeX;      //!< texture width
468   GLsizei          mySizeY;      //!< texture height
469   GLsizei          mySizeZ;      //!< texture depth
470   GLenum           myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
471   GLint            mySizedFormat;//!< internal (sized) texture format
472   Standard_Integer myNbSamples;  //!< number of MSAA samples
473   Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
474   bool             myIsAlpha;    //!< indicates alpha format
475
476 };
477
478 DEFINE_STANDARD_HANDLE(OpenGl_Texture, OpenGl_NamedResource)
479
480 #endif // _OpenGl_Texture_H__