0028811: Visualization - merge texturing support into AIS_Shape class and get rid...
[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_Resource.hxx>
20 #include <Graphic3d_TypeOfTexture.hxx>
21
22 class OpenGl_Context;
23 class Graphic3d_TextureParams;
24 class Image_PixMap;
25
26 //! Selects preferable texture format for specified parameters.
27 template<class T>
28 struct OpenGl_TextureFormatSelector
29 {
30   // Not implemented
31 };
32
33 template<>
34 struct OpenGl_TextureFormatSelector<GLubyte>
35 {
36   static GLint Internal (GLuint theChannels)
37   {
38     switch (theChannels)
39     {
40       case 1:
41         return GL_R8;
42       case 2:
43         return GL_RG8;
44       case 3:
45         return GL_RGB8;
46       case 4:
47         return GL_RGBA8;
48       default:
49         return GL_NONE;
50     }
51   }
52
53   static GLint DataType()
54   {
55     return GL_UNSIGNED_BYTE;
56   }
57 };
58
59 template<>
60 struct OpenGl_TextureFormatSelector<GLushort>
61 {
62   static GLint Internal (GLuint theChannels)
63   {
64     switch (theChannels)
65     {
66       case 1:
67         return GL_R16;
68       case 2:
69         return GL_RG16;
70       case 3:
71         return GL_RGB16;
72       case 4:
73         return GL_RGBA16;
74       default:
75         return GL_NONE;
76     }
77   }
78
79   static GLint DataType()
80   {
81     return GL_UNSIGNED_SHORT;
82   }
83 };
84
85 template<>
86 struct OpenGl_TextureFormatSelector<GLfloat>
87 {
88   static GLint Internal (GLuint theChannels)
89   {
90     switch (theChannels)
91     {
92       case 1:
93         return GL_R32F;
94       case 2:
95         return GL_RG32F;
96       case 3:
97         return GL_RGB32F;
98       case 4:
99         return GL_RGBA32F;
100       default:
101         return GL_NONE;
102     }
103   }
104
105   static GLint DataType()
106   {
107     return GL_FLOAT;
108   }
109 };
110
111 template<>
112 struct OpenGl_TextureFormatSelector<GLuint>
113 {
114   static GLint Internal (GLuint theChannels)
115   {
116     switch (theChannels)
117     {
118       case 1:
119         return GL_RED;
120       case 2:
121         return GL_RG;
122       case 3:
123         return GL_RGB;
124       case 4:
125         return GL_RGBA;
126       default:
127         return GL_NONE;
128     }
129   }
130
131   static GLint DataType()
132   {
133     return GL_UNSIGNED_INT;
134   }
135 };
136
137 //! Only unsigned formats are available in OpenGL ES 2.0
138 #if !defined(GL_ES_VERSION_2_0)
139 template<>
140 struct OpenGl_TextureFormatSelector<GLbyte>
141 {
142   static GLint Internal (GLuint theChannels)
143   {
144     switch (theChannels)
145     {
146       case 1:
147         return GL_R8_SNORM;
148       case 2:
149         return GL_RG8_SNORM;
150       case 3:
151         return GL_RGB8_SNORM;
152       case 4:
153         return GL_RGBA8_SNORM;
154       default:
155         return GL_NONE;
156     }
157   }
158
159   static GLint DataType()
160   {
161     return GL_BYTE;
162   }
163 };
164
165 template<>
166 struct OpenGl_TextureFormatSelector<GLshort>
167 {
168   static GLint Internal (GLuint theChannels)
169   {
170     switch (theChannels)
171     {
172       case 1:
173         return GL_R16_SNORM;
174       case 2:
175         return GL_RG16_SNORM;
176       case 3:
177         return GL_RGB16_SNORM;
178       case 4:
179         return GL_RGBA16_SNORM;
180       default:
181         return GL_NONE;
182     }
183   }
184
185   static GLint DataType()
186   {
187     return GL_SHORT;
188   }
189 };
190
191 template<>
192 struct OpenGl_TextureFormatSelector<GLint>
193 {
194   static GLint Internal (GLuint theChannels)
195   {
196     switch (theChannels)
197     {
198       case 1:
199         return GL_RED_SNORM;
200       case 2:
201         return GL_RG_SNORM;
202       case 3:
203         return GL_RGB_SNORM;
204       case 4:
205         return GL_RGBA_SNORM;
206       default:
207         return GL_NONE;
208     }
209   }
210
211   static GLint DataType()
212   {
213     return GL_INT;
214   }
215 };
216 #endif
217
218 //! Stores parameters of OpenGL texture format.
219 class OpenGl_TextureFormat
220 {
221   friend class OpenGl_Texture;
222
223 public:
224
225   //! Returns OpenGL format of the pixel data.
226   inline GLenum Format() const
227   {
228     switch (myChannels)
229     {
230       case 1:
231         return GL_RED;
232       case 2:
233         return GL_RG;
234       case 3:
235         return GL_RGB;
236       case 4:
237         return GL_RGBA;
238       default:
239         return GL_NONE;
240     }
241   }
242
243   //! Returns OpenGL internal format of the pixel data.
244   inline GLint Internal() const
245   {
246     return myInternal;
247   }
248
249   //! Returns OpenGL data type of the pixel data.
250   inline GLint DataType() const
251   {
252     return myDataType;
253   }
254
255   //! Returns texture format for specified type and number of channels.
256   template<class T, int N>
257   static OpenGl_TextureFormat Create()
258   {
259     return OpenGl_TextureFormat (N,
260                                  OpenGl_TextureFormatSelector<T>::Internal(N),
261                                  OpenGl_TextureFormatSelector<T>::DataType());
262   }
263
264 private:
265
266   //! Creates new texture format.
267   OpenGl_TextureFormat (const GLint theChannels,
268                         const GLint theInternal,
269                         const GLint theDataType)
270   : myInternal (theInternal),
271     myChannels (theChannels),
272     myDataType (theDataType) {}
273
274 private:
275
276   GLint myInternal; //!< OpenGL internal format of the pixel data
277   GLint myChannels; //!< Number of channels for each pixel (from 1 to 4)
278   GLint myDataType; //!< OpenGL data type of input pixel data
279
280 };
281
282 class OpenGl_Texture;
283 DEFINE_STANDARD_HANDLE(OpenGl_Texture, OpenGl_Resource)
284
285 //! Texture resource.
286 class OpenGl_Texture : public OpenGl_Resource
287 {
288
289 public:
290
291   //! Helpful constants
292   static const GLuint NO_TEXTURE = 0;
293
294 public:
295
296   //! Create uninitialized VBO.
297   Standard_EXPORT OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams = NULL);
298
299   //! Destroy object.
300   Standard_EXPORT virtual ~OpenGl_Texture();
301
302   //! @return true if current object was initialized
303   inline bool IsValid() const
304   {
305     return myTextureId != NO_TEXTURE;
306   }
307
308   //! @return target to which the texture is bound (GL_TEXTURE_1D, GL_TEXTURE_2D)
309   inline GLenum GetTarget() const
310   {
311     return myTarget;
312   }
313
314   //! @return texture width (0 LOD)
315   inline GLsizei SizeX() const
316   {
317     return mySizeX;
318   }
319
320   //! @return texture height (0 LOD)
321   inline GLsizei SizeY() const
322   {
323     return mySizeY;
324   }
325
326   //! @return texture ID
327   inline GLuint TextureId() const
328   {
329     return myTextureId;
330   }
331
332   //! @return texture format (not sized)
333   inline GLenum GetFormat() const
334   {
335     return myTextFormat;
336   }
337
338   //! Return true for GL_RED and GL_ALPHA formats.
339   bool IsAlpha() const
340   {
341     return myIsAlpha;
342   }
343
344   //! Setup to interprete the format as Alpha by Shader Manager
345   //! (should be GL_ALPHA within compatible context or GL_RED otherwise).
346   void SetAlpha (const bool theValue)
347   {
348     myIsAlpha = theValue;
349   }
350
351   //! Creates Texture id if not yet generated.
352   //! Data should be initialized by another method.
353   Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theCtx);
354
355   //! Destroy object - will release GPU memory if any.
356   Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
357
358   //! Bind this Texture to specified unit.
359   Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx,
360                              const GLenum                  theTextureUnit = GL_TEXTURE0) const;
361
362   //! Unbind texture from specified unit.
363   Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx,
364                                const GLenum                  theTextureUnit = GL_TEXTURE0) const;
365
366   //! Revision of associated data source.
367   Standard_Size Revision() const { return myRevision; }
368
369   //! Set revision of associated data source.
370   void SetRevision (const Standard_Size theRevision) { myRevision = theRevision; }
371
372   //! Notice that texture will be unbound after this call.
373   Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
374                              const Image_PixMap&           theImage,
375                              const Graphic3d_TypeOfTexture theType);
376
377   //! Initialize the texture with specified format, size and texture type.
378   //! If theImage is empty the texture data will contain trash.
379   //! Notice that texture will be unbound after this call.
380   Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
381                              const GLint                   theTextFormat,
382                              const GLenum                  thePixelFormat,
383                              const GLenum                  theDataType,
384                              const GLsizei                 theSizeX,
385                              const GLsizei                 theSizeY,
386                              const Graphic3d_TypeOfTexture theType,
387                              const Image_PixMap*           theImage = NULL);
388
389   //! Initialize the 2D multisampling texture using glTexImage2DMultisample().
390   Standard_EXPORT bool Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
391                                           const GLsizei                 theNbSamples,
392                                           const GLint                   theTextFormat,
393                                           const GLsizei                 theSizeX,
394                                           const GLsizei                 theSizeY);
395
396   //! Allocates texture rectangle with specified format and size.
397   //! \note Texture data is not initialized (will contain trash).
398   Standard_EXPORT bool InitRectangle (const Handle(OpenGl_Context)& theCtx,
399                                       const Standard_Integer        theSizeX,
400                                       const Standard_Integer        theSizeY,
401                                       const OpenGl_TextureFormat&   theFormat);
402
403   //! Initializes 3D texture rectangle with specified format and size.
404   Standard_EXPORT bool Init3D (const Handle(OpenGl_Context)& theCtx,
405                                const GLint                   theTextFormat,
406                                const GLenum                  thePixelFormat,
407                                const GLenum                  theDataType,
408                                const Standard_Integer        theSizeX,
409                                const Standard_Integer        theSizeY,
410                                const Standard_Integer        theSizeZ,
411                                const void*                   thePixels);
412
413   //! @return true if texture was generated within mipmaps
414   Standard_EXPORT Standard_Boolean HasMipmaps() const;
415
416   //! @return assigned texture parameters (not necessary applied)
417   Standard_EXPORT const Handle(Graphic3d_TextureParams)& GetParams() const;
418
419   //! @param texture parameters
420   Standard_EXPORT void SetParams (const Handle(Graphic3d_TextureParams)& theParams);
421
422   //! Return texture type and format by Image_PixMap data format.
423   Standard_EXPORT static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
424                                              const Image_PixMap&           theData,
425                                              GLint&                        theTextFormat,
426                                              GLenum&                       thePixelFormat,
427                                              GLenum&                       theDataType);
428
429 protected:
430
431   Standard_Size    myRevision;   //!< revision of associated data source
432   GLuint           myTextureId;  //!< GL resource ID
433   GLenum           myTarget;     //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D
434   GLsizei          mySizeX;      //!< texture width
435   GLsizei          mySizeY;      //!< texture height
436   GLsizei          mySizeZ;      //!< texture depth
437   GLenum           myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
438   Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
439   bool             myIsAlpha;    //!< indicates alpha format
440
441   Handle(Graphic3d_TextureParams) myParams; //!< texture parameters
442
443 public:
444
445   DEFINE_STANDARD_RTTIEXT(OpenGl_Texture,OpenGl_Resource) // Type definition
446
447 };
448
449 #endif // _OpenGl_Texture_H__