0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
[occt.git] / src / OpenGl / OpenGl_TextureFormat.cxx
CommitLineData
ba00aab7 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// =======================================================================
22OpenGl_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 {
67312b79 34 aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
ba00aab7 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 {
67312b79 54 aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
ba00aab7 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 }
67312b79 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 }
ba00aab7 81 case Image_Format_RGBAF:
82 {
83 aFormat.SetNbComponents (4);
67312b79 84 aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
ba00aab7 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);
67312b79 96 aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
ba00aab7 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);
67312b79 104 aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
ba00aab7 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);
67312b79 113 aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
ba00aab7 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// =======================================================================
307OpenGl_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}