0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
[occt.git] / src / OpenGl / OpenGl_TextureFormat.cxx
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 #include <OpenGl_TextureFormat.hxx>
15
16 #include <OpenGl_Context.hxx>
17
18 // =======================================================================
19 // function : FindFormat
20 // purpose  :
21 // =======================================================================
22 OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Context)& theCtx,
23                                                        Image_Format theFormat,
24                                                        bool theIsColorMap)
25 {
26   OpenGl_TextureFormat aFormat;
27   switch (theFormat)
28   {
29     case Image_Format_GrayF:
30     {
31       aFormat.SetNbComponents (1);
32       if (theCtx->core11 == NULL)
33       {
34         aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
35         aFormat.SetPixelFormat (GL_RED);
36       }
37       else
38       {
39       #if !defined(GL_ES_VERSION_2_0)
40         aFormat.SetInternalFormat (GL_LUMINANCE8);
41       #else
42         aFormat.SetInternalFormat (GL_LUMINANCE);
43       #endif
44         aFormat.SetPixelFormat (GL_LUMINANCE);
45       }
46       aFormat.SetDataType (GL_FLOAT);
47       return aFormat;
48     }
49     case Image_Format_AlphaF:
50     {
51       aFormat.SetNbComponents (1);
52       if (theCtx->core11 == NULL)
53       {
54         aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
55         aFormat.SetPixelFormat (GL_RED);
56       }
57       else
58       {
59       #if !defined(GL_ES_VERSION_2_0)
60         aFormat.SetInternalFormat (GL_ALPHA8);
61       #else
62         aFormat.SetInternalFormat (GL_ALPHA);
63       #endif
64         aFormat.SetPixelFormat (GL_ALPHA);
65       }
66       aFormat.SetDataType (GL_FLOAT);
67       return aFormat;
68     }
69     case Image_Format_RGF:
70     {
71       if (!theCtx->arbTexRG)
72       {
73         return OpenGl_TextureFormat();
74       }
75       aFormat.SetNbComponents (2);
76       aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RG32F : GL_RG8);
77       aFormat.SetPixelFormat (GL_RG);
78       aFormat.SetDataType (GL_FLOAT);
79       return aFormat;
80     }
81     case Image_Format_RGBAF:
82     {
83       aFormat.SetNbComponents (4);
84       aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
85       aFormat.SetPixelFormat (GL_RGBA);
86       aFormat.SetDataType (GL_FLOAT);
87       return aFormat;
88     }
89     case Image_Format_BGRAF:
90     {
91       if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
92       {
93         return OpenGl_TextureFormat();
94       }
95       aFormat.SetNbComponents (4);
96       aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
97       aFormat.SetPixelFormat (GL_BGRA_EXT); // equals to GL_BGRA
98       aFormat.SetDataType (GL_FLOAT);
99       return aFormat;
100     }
101     case Image_Format_RGBF:
102     {
103       aFormat.SetNbComponents (3);
104       aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
105       aFormat.SetPixelFormat (GL_RGB);
106       aFormat.SetDataType (GL_FLOAT);
107       return aFormat;
108     }
109     case Image_Format_BGRF:
110     {
111     #if !defined(GL_ES_VERSION_2_0)
112       aFormat.SetNbComponents (3);
113       aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
114       aFormat.SetPixelFormat (GL_BGR);     // equals to GL_BGR_EXT
115       aFormat.SetDataType (GL_FLOAT);
116       return aFormat;
117     #else
118       return OpenGl_TextureFormat();
119     #endif
120     }
121     case Image_Format_RGBA:
122     {
123       aFormat.SetNbComponents (4);
124       aFormat.SetInternalFormat (GL_RGBA8);
125       aFormat.SetPixelFormat (GL_RGBA);
126       aFormat.SetDataType (GL_UNSIGNED_BYTE);
127       if (theIsColorMap
128        && theCtx->ToRenderSRGB())
129       {
130         aFormat.SetInternalFormat (GL_SRGB8_ALPHA8);
131       }
132       return aFormat;
133     }
134     case Image_Format_BGRA:
135     {
136     #if !defined(GL_ES_VERSION_2_0)
137       if (!theCtx->IsGlGreaterEqual (1, 2)
138        && !theCtx->extBgra)
139       {
140         return OpenGl_TextureFormat();
141       }
142       aFormat.SetNbComponents (4);
143       aFormat.SetInternalFormat (GL_RGBA8);
144       if (theIsColorMap
145        && theCtx->ToRenderSRGB())
146       {
147         aFormat.SetInternalFormat (GL_SRGB8_ALPHA8);
148       }
149     #else
150       if (theIsColorMap
151        && theCtx->ToRenderSRGB())
152       {
153         // GL_SRGB8_ALPHA8 with texture swizzling would be better
154       }
155       if (!theCtx->extBgra)
156       {
157         return OpenGl_TextureFormat();
158       }
159       aFormat.SetNbComponents (4);
160           aFormat.SetInternalFormat (GL_BGRA_EXT);
161     #endif
162       aFormat.SetPixelFormat (GL_BGRA_EXT); // equals to GL_BGRA
163       aFormat.SetDataType (GL_UNSIGNED_BYTE);
164       return aFormat;
165     }
166     case Image_Format_RGB32:
167     {
168     #if !defined(GL_ES_VERSION_2_0)
169       // ask driver to convert data to RGB8 to save memory
170       aFormat.SetNbComponents (3);
171       aFormat.SetInternalFormat (GL_RGB8);
172       if (theIsColorMap
173        && theCtx->ToRenderSRGB())
174       {
175         aFormat.SetInternalFormat (GL_SRGB8);
176       }
177     #else
178       // conversion is not supported
179       aFormat.SetNbComponents (4);
180       aFormat.SetInternalFormat (GL_RGBA8);
181       if (theIsColorMap
182        && theCtx->ToRenderSRGB())
183       {
184         aFormat.SetInternalFormat (GL_SRGB8_ALPHA8);
185       }
186     #endif
187       aFormat.SetPixelFormat (GL_RGBA);
188       aFormat.SetDataType (GL_UNSIGNED_BYTE);
189       return aFormat;
190     }
191     case Image_Format_BGR32:
192     {
193     #if !defined(GL_ES_VERSION_2_0)
194       if (!theCtx->IsGlGreaterEqual(1, 2) && !theCtx->extBgra)
195       {
196         return OpenGl_TextureFormat();
197       }
198       aFormat.SetNbComponents (3);
199       aFormat.SetInternalFormat (GL_RGB8);
200       if (theIsColorMap
201        && theCtx->ToRenderSRGB())
202       {
203         aFormat.SetInternalFormat (GL_SRGB8);
204       }
205     #else
206       if (theIsColorMap
207        && theCtx->ToRenderSRGB())
208       {
209         // GL_SRGB8_ALPHA8 with texture swizzling would be better
210       }
211       if (!theCtx->extBgra)
212       {
213         return OpenGl_TextureFormat();
214       }
215       aFormat.SetNbComponents (4);
216       aFormat.SetInternalFormat (GL_BGRA_EXT);
217     #endif
218       aFormat.SetPixelFormat (GL_BGRA_EXT); // equals to GL_BGRA
219       aFormat.SetDataType (GL_UNSIGNED_BYTE);
220       return aFormat;
221     }
222     case Image_Format_RGB:
223     {
224       aFormat.SetNbComponents (3);
225       aFormat.SetInternalFormat (GL_RGB8);
226       aFormat.SetPixelFormat (GL_RGB);
227       aFormat.SetDataType (GL_UNSIGNED_BYTE);
228       if (theIsColorMap
229        && theCtx->ToRenderSRGB())
230       {
231         aFormat.SetInternalFormat (GL_SRGB8);
232       }
233       return aFormat;
234     }
235     case Image_Format_BGR:
236     {
237     #if !defined(GL_ES_VERSION_2_0)
238       if (!theCtx->IsGlGreaterEqual (1, 2)
239        && !theCtx->extBgra)
240       {
241         return OpenGl_TextureFormat();
242       }
243       aFormat.SetNbComponents (3);
244       aFormat.SetInternalFormat (GL_RGB8);
245       if (theIsColorMap
246        && theCtx->ToRenderSRGB())
247       {
248         aFormat.SetInternalFormat (GL_SRGB8);
249       }
250       aFormat.SetPixelFormat (GL_BGR); // equals to GL_BGR_EXT
251       aFormat.SetDataType (GL_UNSIGNED_BYTE);
252     #endif
253       return aFormat;
254     }
255     case Image_Format_Gray:
256     {
257       aFormat.SetNbComponents (1);
258       if (theCtx->core11 == NULL)
259       {
260         aFormat.SetInternalFormat (GL_R8);
261         aFormat.SetPixelFormat (GL_RED);
262       }
263       else
264       {
265       #if !defined(GL_ES_VERSION_2_0)
266         aFormat.SetInternalFormat (GL_LUMINANCE8);
267       #else
268         aFormat.SetInternalFormat (GL_LUMINANCE);
269       #endif
270         aFormat.SetPixelFormat (GL_LUMINANCE);
271       }
272       aFormat.SetDataType (GL_UNSIGNED_BYTE);
273       return aFormat;
274     }
275     case Image_Format_Alpha:
276     {
277       aFormat.SetNbComponents (1);
278       if (theCtx->core11 == NULL)
279       {
280         aFormat.SetInternalFormat (GL_R8);
281         aFormat.SetPixelFormat (GL_RED);
282       }
283       else
284       {
285       #if !defined(GL_ES_VERSION_2_0)
286         aFormat.SetInternalFormat (GL_ALPHA8);
287       #else
288         aFormat.SetInternalFormat (GL_ALPHA);
289       #endif
290         aFormat.SetPixelFormat (GL_ALPHA);
291       }
292       aFormat.SetDataType (GL_UNSIGNED_BYTE);
293       return aFormat;
294     }
295     case Image_Format_UNKNOWN:
296     {
297       return OpenGl_TextureFormat();
298     }
299   }
300   return OpenGl_TextureFormat();
301 }
302
303 // =======================================================================
304 // function : FindSizedFormat
305 // purpose  :
306 // =======================================================================
307 OpenGl_TextureFormat OpenGl_TextureFormat::FindSizedFormat (const Handle(OpenGl_Context)& theCtx,
308                                                             GLint theSizedFormat)
309 {
310   OpenGl_TextureFormat aFormat;
311   switch (theSizedFormat)
312   {
313     case GL_RGBA32F:
314     {
315       aFormat.SetNbComponents (4);
316       aFormat.SetInternalFormat (theSizedFormat);
317       aFormat.SetPixelFormat (GL_RGBA);
318       aFormat.SetDataType (GL_FLOAT);
319       return aFormat;
320     }
321     case GL_R32F:
322     {
323       aFormat.SetNbComponents (1);
324       aFormat.SetInternalFormat (theSizedFormat);
325       aFormat.SetPixelFormat (GL_RED);
326       aFormat.SetDataType (GL_FLOAT);
327       return aFormat;
328     }
329     case GL_RGBA16F:
330     {
331       aFormat.SetNbComponents (4);
332       aFormat.SetInternalFormat (theSizedFormat);
333       aFormat.SetPixelFormat (GL_RGBA);
334       aFormat.SetDataType (GL_HALF_FLOAT);
335       if (theCtx->hasHalfFloatBuffer == OpenGl_FeatureInExtensions)
336       {
337       #if defined(GL_ES_VERSION_2_0)
338         aFormat.SetDataType (GL_HALF_FLOAT_OES);
339       #else
340         aFormat.SetDataType (GL_FLOAT);
341       #endif
342       }
343       return aFormat;
344     }
345     case GL_R16F:
346     {
347       aFormat.SetNbComponents (1);
348       aFormat.SetInternalFormat (theSizedFormat);
349       aFormat.SetPixelFormat (GL_RED);
350       aFormat.SetDataType (GL_HALF_FLOAT);
351       if (theCtx->hasHalfFloatBuffer == OpenGl_FeatureInExtensions)
352       {
353       #if defined(GL_ES_VERSION_2_0)
354         aFormat.SetDataType (GL_HALF_FLOAT_OES);
355       #else
356         aFormat.SetDataType (GL_FLOAT);
357       #endif
358       }
359       return aFormat;
360     }
361     case GL_SRGB8_ALPHA8:
362     case GL_RGBA8:
363     case GL_RGBA:
364     {
365       aFormat.SetNbComponents (4);
366       aFormat.SetInternalFormat (theSizedFormat);
367       aFormat.SetPixelFormat (GL_RGBA);
368       aFormat.SetDataType (GL_UNSIGNED_BYTE);
369       if (theSizedFormat == GL_SRGB8_ALPHA8
370       && !theCtx->ToRenderSRGB())
371       {
372         aFormat.SetInternalFormat (GL_RGBA8); // fallback format
373       }
374       return aFormat;
375     }
376     case GL_SRGB8:
377     case GL_RGB8:
378     case GL_RGB:
379     {
380       aFormat.SetNbComponents (3);
381       aFormat.SetInternalFormat (theSizedFormat);
382       aFormat.SetPixelFormat (GL_RGB);
383       aFormat.SetDataType (GL_UNSIGNED_BYTE);
384       if (theSizedFormat == GL_SRGB8
385       && !theCtx->ToRenderSRGB())
386       {
387         aFormat.SetInternalFormat (GL_RGB8); // fallback format
388       }
389       return aFormat;
390     }
391     // integer types
392     case GL_R32I:
393     {
394       aFormat.SetNbComponents (1);
395       aFormat.SetInternalFormat (theSizedFormat);
396       aFormat.SetPixelFormat (GL_RED_INTEGER);
397       aFormat.SetDataType (GL_INT);
398       return aFormat;
399     }
400     case GL_RG32I:
401     {
402       aFormat.SetNbComponents (2);
403       aFormat.SetInternalFormat (theSizedFormat);
404       aFormat.SetPixelFormat (GL_RG_INTEGER);
405       aFormat.SetDataType (GL_INT);
406       return aFormat;
407     }
408     // depth formats
409     case GL_DEPTH24_STENCIL8:
410     {
411       aFormat.SetNbComponents (2);
412       aFormat.SetInternalFormat (theSizedFormat);
413       aFormat.SetPixelFormat (GL_DEPTH_STENCIL);
414       aFormat.SetDataType (GL_UNSIGNED_INT_24_8);
415       return aFormat;
416     }
417     case GL_DEPTH32F_STENCIL8:
418     {
419       aFormat.SetNbComponents (2);
420       aFormat.SetInternalFormat (theSizedFormat);
421       aFormat.SetPixelFormat (GL_DEPTH_STENCIL);
422       aFormat.SetDataType (GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
423       return aFormat;
424     }
425     case GL_DEPTH_COMPONENT16:
426     {
427       aFormat.SetNbComponents (1);
428       aFormat.SetInternalFormat (theSizedFormat);
429       aFormat.SetPixelFormat (GL_DEPTH_COMPONENT);
430       aFormat.SetDataType (GL_UNSIGNED_SHORT);
431       return aFormat;
432     }
433     case GL_DEPTH_COMPONENT24:
434     {
435       aFormat.SetNbComponents (1);
436       aFormat.SetInternalFormat (theSizedFormat);
437       aFormat.SetPixelFormat (GL_DEPTH_COMPONENT);
438       aFormat.SetDataType (GL_UNSIGNED_INT);
439       return aFormat;
440     }
441     case GL_DEPTH_COMPONENT32F:
442     {
443       aFormat.SetNbComponents (1);
444       aFormat.SetInternalFormat (theSizedFormat);
445       aFormat.SetPixelFormat (GL_DEPTH_COMPONENT);
446       aFormat.SetDataType (GL_FLOAT);
447       return aFormat;
448     }
449   }
450   return aFormat;
451 }