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