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