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