0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / OpenGl / OpenGl_TextureFormat.hxx
1 // Copyright (c) 2017-2019 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _OpenGl_TextureFormat_HeaderFile
15 #define _OpenGl_TextureFormat_HeaderFile
16
17 #include <Image_CompressedFormat.hxx>
18 #include <Image_Format.hxx>
19 #include <OpenGl_GlCore13.hxx>
20 #include <Standard_Handle.hxx>
21
22 class OpenGl_Context;
23
24 //! Stores parameters of OpenGL texture format.
25 class OpenGl_TextureFormat
26 {
27 public:
28
29   //! Returns texture format for specified type and number of channels.
30   //! @tparam theCompType component type
31   //! @tparam theNbComps  number of components
32   template<class theCompType, int theNbComps>
33   static OpenGl_TextureFormat Create();
34
35   //! Find texture format suitable to specified image format.
36   //! @param theCtx [in] OpenGL context defining supported texture formats
37   //! @param theFormat [in] image format
38   //! @param theIsColorMap [in] flag indicating color nature of image (to select sRGB texture)
39   //! @return found format or invalid format
40   Standard_EXPORT static OpenGl_TextureFormat FindFormat (const Handle(OpenGl_Context)& theCtx,
41                                                           Image_Format theFormat,
42                                                           bool theIsColorMap);
43
44   //! Find texture format suitable to specified internal (sized) texture format.
45   //! @param theCtx [in] OpenGL context defining supported texture formats
46   //! @param theSizedFormat [in] sized (internal) texture format (example: GL_RGBA8)
47   //! @return found format or invalid format
48   Standard_EXPORT static OpenGl_TextureFormat FindSizedFormat (const Handle(OpenGl_Context)& theCtx,
49                                                                GLint theSizedFormat);
50
51   //! Find texture format suitable to specified compressed texture format.
52   //! @param theCtx [in] OpenGL context defining supported texture formats
53   //! @param theFormat [in] compressed texture format
54   //! @return found format or invalid format
55   Standard_EXPORT static OpenGl_TextureFormat FindCompressedFormat (const Handle(OpenGl_Context)& theCtx,
56                                                                     Image_CompressedFormat theFormat,
57                                                                     bool theIsColorMap);
58
59 public:
60
61   //! Empty constructor (invalid texture format).
62   OpenGl_TextureFormat() : myInternalFormat (0), myPixelFormat (0), myDataType (0), myNbComponents (0) {}
63
64   //! Return TRUE if format is defined.
65   bool IsValid() const
66   {
67     return myInternalFormat != 0
68         && myPixelFormat != 0
69         && myDataType != 0;
70   }
71
72   //! Returns OpenGL internal format of the pixel data (example: GL_R32F).
73   GLint InternalFormat() const { return myInternalFormat; }
74
75   //! Sets texture internal format.
76   void SetInternalFormat (GLint theInternal) { myInternalFormat = theInternal; }
77
78   //! Returns OpenGL format of the pixel data (example: GL_RED).
79   GLenum PixelFormat() const { return myPixelFormat; }
80
81   //! Sets OpenGL format of the pixel data.
82   void SetPixelFormat (GLenum theFormat) { myPixelFormat = theFormat; }
83
84   //! Returns OpenGL data type of the pixel data (example: GL_FLOAT).
85   GLint DataType() const { return myDataType; }
86
87   //! Sets OpenGL data type of the pixel data.
88   void SetDataType (GLint theType) { myDataType = theType; }
89
90   //! Returns number of components (channels). Here for debugging purposes.
91   GLint NbComponents() const { return myNbComponents; }
92
93   //! Sets number of components (channels).
94   void SetNbComponents (GLint theNbComponents) { myNbComponents = theNbComponents; }
95
96   //! Return TRUE if internal texture format is sRGB(A).
97   bool IsSRGB() const
98   {
99     return myInternalFormat == GL_SRGB8
100         || myInternalFormat == GL_SRGB8_ALPHA8;
101   }
102
103 public:
104
105   //! Returns OpenGL internal format of the pixel data (example: GL_R32F).
106   GLint Internal() const { return myInternalFormat; }
107
108   //! Returns OpenGL format of the pixel data (example: GL_RED).
109   GLenum Format() const { return myPixelFormat; }
110
111 private:
112
113   GLint  myInternalFormat; //!< OpenGL internal format of the pixel data
114   GLenum myPixelFormat;    //!< OpenGL pixel format
115   GLint  myDataType;       //!< OpenGL data type of input pixel data
116   GLint  myNbComponents;   //!< number of channels for each pixel (from 1 to 4)
117
118 };
119
120 //! Selects preferable texture format for specified parameters.
121 template<class T> struct OpenGl_TextureFormatSelector
122 {
123   // Not implemented
124 };
125
126 //! Specialization for unsigned byte.
127 template<> struct OpenGl_TextureFormatSelector<GLubyte>
128 {
129   static GLint DataType() { return GL_UNSIGNED_BYTE; }
130   static GLint Internal (GLuint theChannels)
131   {
132     switch (theChannels)
133     {
134       case 1:  return GL_R8;
135       case 2:  return GL_RG8;
136       case 3:  return GL_RGB8;
137       case 4:  return GL_RGBA8;
138       default: return GL_NONE;
139     }
140   }
141 };
142
143 //! Specialization for unsigned short.
144 template<> struct OpenGl_TextureFormatSelector<GLushort>
145 {
146   static GLint DataType() { return GL_UNSIGNED_SHORT; }
147   static GLint Internal (GLuint theChannels)
148   {
149     switch (theChannels)
150     {
151       case 1:  return GL_R16;
152       case 2:  return GL_RG16;
153       case 3:  return GL_RGB16;
154       case 4:  return GL_RGBA16;
155       default: return GL_NONE;
156     }
157   }
158 };
159
160 //! Specialization for float.
161 template<> struct OpenGl_TextureFormatSelector<GLfloat>
162 {
163   static GLint DataType() { return GL_FLOAT; }
164   static GLint Internal (GLuint theChannels)
165   {
166     switch (theChannels)
167     {
168       case 1:  return GL_R32F;
169       case 2:  return GL_RG32F;
170       case 3:  return GL_RGB32F;
171       case 4:  return GL_RGBA32F;
172       default: return GL_NONE;
173     }
174   }
175 };
176
177 //! Specialization for unsigned int.
178 template<> struct OpenGl_TextureFormatSelector<GLuint>
179 {
180   static GLint DataType() { return GL_UNSIGNED_INT; }
181   static GLint Internal (GLuint theChannels)
182   {
183     switch (theChannels)
184     {
185       case 1:  return GL_RED;
186       case 2:  return GL_RG;
187       case 3:  return GL_RGB;
188       case 4:  return GL_RGBA;
189       default: return GL_NONE;
190     }
191   }
192 };
193
194 //! Specialization for signed byte.
195 template<> struct OpenGl_TextureFormatSelector<GLbyte>
196 {
197   static GLint DataType() { return GL_BYTE; }
198   static GLint Internal (GLuint theChannels)
199   {
200     switch (theChannels)
201     {
202       case 1:  return GL_R8_SNORM;
203       case 2:  return GL_RG8_SNORM;
204       case 3:  return GL_RGB8_SNORM;
205       case 4:  return GL_RGBA8_SNORM;
206       default: return GL_NONE;
207     }
208   }
209 };
210
211 //! Specialization for signed short.
212 template<> struct OpenGl_TextureFormatSelector<GLshort>
213 {
214   static GLint DataType() { return GL_SHORT; }
215   static GLint Internal (GLuint theChannels)
216   {
217     switch (theChannels)
218     {
219       case 1:  return GL_R16_SNORM;
220       case 2:  return GL_RG16_SNORM;
221       case 3:  return GL_RGB16_SNORM;
222       case 4:  return GL_RGBA16_SNORM;
223       default: return GL_NONE;
224     }
225   }
226 };
227
228 //! Specialization for signed int.
229 template<> struct OpenGl_TextureFormatSelector<GLint>
230 {
231   static GLint DataType() { return GL_INT; }
232   static GLint Internal (GLuint theChannels)
233   {
234     switch (theChannels)
235     {
236       case 1:  return GL_RED_SNORM;
237       case 2:  return GL_RG_SNORM;
238       case 3:  return GL_RGB_SNORM;
239       case 4:  return GL_RGBA_SNORM;
240       default: return GL_NONE;
241     }
242   }
243 };
244
245 // =======================================================================
246 // function : Create
247 // purpose  :
248 // =======================================================================
249 template<class theCompType, int theNbComps>
250 inline OpenGl_TextureFormat OpenGl_TextureFormat::Create()
251 {
252   OpenGl_TextureFormat aFormat;
253   aFormat.SetNbComponents (theNbComps);
254   aFormat.SetInternalFormat (OpenGl_TextureFormatSelector<theCompType>::Internal (theNbComps));
255   aFormat.SetDataType (OpenGl_TextureFormatSelector<theCompType>::DataType());
256   GLenum aPixelFormat = GL_NONE;
257   switch (theNbComps)
258   {
259     case 1: aPixelFormat = GL_RED;  break;
260     case 2: aPixelFormat = GL_RG;   break;
261     case 3: aPixelFormat = GL_RGB;  break;
262     case 4: aPixelFormat = GL_RGBA; break;
263   }
264   aFormat.SetPixelFormat (aPixelFormat);
265   return aFormat;
266 }
267
268 #endif // _OpenGl_TextureFormat_HeaderFile