1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
#ifndef GL_RT_COMMON_H
#define GL_RT_COMMON_H
// internal header
// common RT-related stuff
// as we might need both gles and gles20 linked we a forced to use external defines here
#ifndef GL_RT_COMMON_GLES
#define GL_RT_COMMON_GLES 0
#endif
#ifndef GL_RT_COMMON_GLES2
#define GL_RT_COMMON_GLES2 0
#endif
#ifndef GL_RT_COMMON_GL
#define GL_RT_COMMON_GL 0
#endif
#if GL_RT_COMMON_GLES==0 && GL_RT_COMMON_GLES2==0 && GL_RT_COMMON_GL==0
#error dont include this header without specifying api used
#endif
#if GL_RT_COMMON_GLES
#define CHECK GL_CHK
#define EXT_CALL(f) f##OES
#define EXT_ENUM(x) x##_OES
#define MANGLE_NAME(f) f##GLES
#elif GL_RT_COMMON_GLES2
#define CHECK GLES_CHK
#define EXT_CALL(f) f
#define EXT_ENUM(x) x
#define MANGLE_NAME(f) f##GLES2
#elif GL_RT_COMMON_GL
#define CHECK GL_CHK
#define EXT_CALL(f) f##EXT
#define EXT_ENUM(x) x##_EXT
#define MANGLE_NAME(f) f##GL
#endif
//==============================================================================
// rt format handling
//==============================================================================
inline GLenum MANGLE_NAME(RTColorTextureFormat)(RenderTextureFormat fmt)
{
switch( fmt )
{
case kRTFormatARGB32:
case kRTFormatARGB4444:
case kRTFormatARGB1555:
case kRTFormatARGBHalf:
case kRTFormatARGBFloat:
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
return GL_RGBA;
#else
return GL_BGRA;
#endif
case kRTFormatRGB565:
return GL_RGB;
case kRTFormatR8:
case kRTFormatRHalf:
case kRTFormatRFloat:
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
return 0x1903; // GL_RED_EXT
#else
return GL_RED;
#endif
case kRTFormatRGHalf:
case kRTFormatRGFloat:
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
return 0x8227; // GL_RG_EXT
#else
return 0x8227; // GL_RG
#endif
// int formats are not supported
case kRTFormatARGBInt:
case kRTFormatRInt:
case kRTFormatRGInt:
break;
default:
break;
}
Assert( false && "wrong color rt format" );
return 0;
}
inline GLenum MANGLE_NAME(RTColorInternalFormat)(RenderTextureFormat fmt)
{
switch( fmt )
{
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
case kRTFormatARGB32: return GL_RGBA;
case kRTFormatARGB4444: return GL_RGBA;
case kRTFormatARGB1555: return GL_RGBA;
case kRTFormatRGB565: return GL_RGB;
case kRTFormatARGBHalf: return GL_RGBA;
case kRTFormatARGBFloat: return GL_RGBA;
case kRTFormatR8: return 0x1903; // GL_RED_EXT
case kRTFormatRHalf: return 0x1903; // GL_RED_EXT
case kRTFormatRFloat: return 0x1903; // GL_RED_EXT
case kRTFormatRGHalf: return 0x8227; // GL_RG_EXT
case kRTFormatRGFloat: return 0x8227; // GL_RG_EXT
#else
case kRTFormatARGB32: return GL_RGBA;
case kRTFormatARGB4444: return GL_RGBA4;
case kRTFormatARGB1555: return GL_RGB5_A1;
case kRTFormatRGB565: return GL_RGB5;
case kRTFormatARGBHalf: return GL_RGBA16F_ARB;
case kRTFormatARGBFloat: return GL_RGBA32F_ARB;
case kRTFormatR8: return 0x8229; // GL_R8
case kRTFormatRHalf: return 0x822D; // GL_R16F
case kRTFormatRFloat: return 0x822E; // GL_R32F
case kRTFormatRGHalf: return 0x822F; // GL_RG16F
case kRTFormatRGFloat: return 0x8230; // GL_RG32F
#endif
case kRTFormatARGBInt: break;
case kRTFormatRInt: break;
case kRTFormatRGInt: break;
default:
break;
}
Assert( false && "wrong color rt format" );
return 0;
}
inline GLenum MANGLE_NAME(RBColorInternalFormat)(RenderTextureFormat fmt)
{
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
switch( fmt )
{
case kRTFormatARGB32: return GL_RGBA8_OES;
case kRTFormatRGB565: return EXT_ENUM(GL_RGB565);
default: break;
}
Assert(false && "wrong color rb format");
return 0;
#else
return RTColorTextureFormatGL(fmt);
#endif
}
inline GLenum MANGLE_NAME(RTColorTextureFormatSRGB)(RenderTextureFormat fmt)
{
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
switch( fmt )
{
case kRTFormatARGB32: return 0x8C42; // GL_SRGB_ALPHA_EXT
default: break;
}
return MANGLE_NAME(RTColorTextureFormat)(fmt);
#else
return RTColorTextureFormatGL(fmt);
#endif
}
inline GLenum MANGLE_NAME(RTColorInternalFormatSRGB)(RenderTextureFormat fmt)
{
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
switch( fmt )
{
case kRTFormatARGB32: return 0x8C42; // GL_SRGB_ALPHA_EXT
default: break;
}
return MANGLE_NAME(RTColorInternalFormat)(fmt);
#else
switch( fmt )
{
case kRTFormatARGB32: return GL_SRGB8_ALPHA8_EXT;
default: break;
}
return RTColorInternalFormatGL(fmt);
#endif
Assert( false && "wrong color rt format" );
return 0;
}
inline GLenum MANGLE_NAME(RTColorTextureType)(RenderTextureFormat fmt)
{
switch( fmt )
{
case kRTFormatARGB32: return GL_UNSIGNED_BYTE;
case kRTFormatARGB4444: return GL_UNSIGNED_SHORT_4_4_4_4;
case kRTFormatARGB1555: return GL_UNSIGNED_SHORT_5_5_5_1;
case kRTFormatRGB565: return GL_UNSIGNED_SHORT_5_6_5;
case kRTFormatR8: return GL_UNSIGNED_BYTE;
case kRTFormatARGBHalf:
case kRTFormatRHalf:
case kRTFormatRGHalf:
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
return 0x8D61; // GL_HALF_FLOAT_OES;
#else
return GL_HALF_FLOAT_ARB;
#endif
case kRTFormatARGBFloat:
case kRTFormatRFloat:
case kRTFormatRGFloat:
return GL_FLOAT;
case kRTFormatARGBInt:
case kRTFormatRInt:
case kRTFormatRGInt:
break;
default:
break;
}
Assert( false && "wrong color rt format" );
return 0;
}
//==============================================================================
// rt format support
//==============================================================================
#if GL_RT_COMMON_GLES
#define DEPTH_ENUM GL_DEPTH_COMPONENT16_OES
#elif GL_RT_COMMON_GLES2
#define DEPTH_ENUM GL_DEPTH_COMPONENT16
#elif GL_RT_COMMON_GL
#define DEPTH_ENUM GL_DEPTH_COMPONENT
#endif
struct MANGLE_NAME(FBColorFormatChecker)
{
GLint oldFB;
GLint oldRB;
GLuint fb;
GLuint depth;
GLuint color;
static const int FBExt = 8;
MANGLE_NAME(FBColorFormatChecker)()
{
#if UNITY_IPHONE
CHECK(glGetIntegerv(EXT_ENUM(GL_FRAMEBUFFER_BINDING), &oldFB));
CHECK(glGetIntegerv(EXT_ENUM(GL_RENDERBUFFER_BINDING), &oldRB));
#else
oldFB = oldRB = 0;
#endif
CHECK(EXT_CALL(glGenFramebuffers)(1, &fb));
CHECK(EXT_CALL(glBindFramebuffer)(EXT_ENUM(GL_FRAMEBUFFER), fb));
CHECK(EXT_CALL(glGenRenderbuffers)(1, &depth));
CHECK(EXT_CALL(glBindRenderbuffer)(EXT_ENUM(GL_RENDERBUFFER), depth));
CHECK(EXT_CALL(glRenderbufferStorage)(EXT_ENUM(GL_RENDERBUFFER), DEPTH_ENUM, FBExt, FBExt));
CHECK(glGenTextures(1, &color));
}
~MANGLE_NAME(FBColorFormatChecker)()
{
// gives out warning under emu
#if !UNITY_GLES_EMU
CHECK(EXT_CALL(glFramebufferTexture2D)(EXT_ENUM(GL_FRAMEBUFFER), EXT_ENUM(GL_COLOR_ATTACHMENT0), GL_TEXTURE_2D, 0, 0));
CHECK(EXT_CALL(glFramebufferRenderbuffer)(EXT_ENUM(GL_FRAMEBUFFER), EXT_ENUM(GL_DEPTH_ATTACHMENT), EXT_ENUM(GL_RENDERBUFFER), 0));
#endif
CHECK(EXT_CALL(glBindFramebuffer)(EXT_ENUM(GL_FRAMEBUFFER), oldFB));
CHECK(EXT_CALL(glDeleteFramebuffers)(1, &fb));
CHECK(EXT_CALL(glBindRenderbuffer)(EXT_ENUM(GL_RENDERBUFFER), oldRB));
CHECK(EXT_CALL(glDeleteRenderbuffers)(1, &depth));
CHECK(glDeleteTextures(1, &color));
}
bool CheckFormatSupported(GLint internalFormat, GLenum format, GLenum type)
{
#if !GL_RT_COMMON_GLES2
CHECK(glEnable(GL_TEXTURE_2D));
#endif
CHECK(glBindTexture(GL_TEXTURE_2D, color));
CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
#if GL_RT_COMMON_GL
CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
CHECK(glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, FBExt, FBExt, 0, format, type, 0));
CHECK(EXT_CALL(glFramebufferTexture2D)(EXT_ENUM(GL_FRAMEBUFFER), EXT_ENUM(GL_COLOR_ATTACHMENT0), GL_TEXTURE_2D, color, 0));
CHECK(EXT_CALL(glFramebufferRenderbuffer)(EXT_ENUM(GL_FRAMEBUFFER), EXT_ENUM(GL_DEPTH_ATTACHMENT), EXT_ENUM(GL_RENDERBUFFER), depth));
GLenum status = EXT_CALL(glCheckFramebufferStatus)(EXT_ENUM(GL_FRAMEBUFFER));
CHECK(glBindTexture(GL_TEXTURE_2D, 0));
return (status == EXT_ENUM(GL_FRAMEBUFFER_COMPLETE));
}
};
//==============================================================================
// fb/rt format query
//==============================================================================
// for now
#if GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
inline RenderTextureFormat MANGLE_NAME(QueryFBColorFormat)()
{
GLint rbits=0, gbits=0, bbits=0, abits=0;
CHECK(glGetIntegerv(GL_RED_BITS, &rbits));
CHECK(glGetIntegerv(GL_GREEN_BITS, &gbits));
CHECK(glGetIntegerv(GL_BLUE_BITS, &bbits));
CHECK(glGetIntegerv(GL_ALPHA_BITS, &abits));
if(rbits==8 && gbits==8 && bbits==8 && abits==8)
return kRTFormatARGB32;
else if(rbits==4 && gbits==4 && bbits==4 && abits==4)
return kRTFormatARGB4444;
else if(rbits==5 && gbits==5 && bbits==5 && abits==1)
return kRTFormatARGB1555;
else if(rbits==5 && gbits==6 && bbits==5 && abits==0)
return kRTFormatRGB565;
#if UNITY_ANDROID
//we can end up with 32bits without alpha
if(rbits==8 && gbits==8 && bbits==8)
return kRTFormatARGB32;
#endif
return kRTFormatARGB32;
}
inline DepthBufferFormat MANGLE_NAME(QueryFBDepthFormat)()
{
GLint dbits=0;
CHECK(glGetIntegerv(GL_DEPTH_BITS, &dbits));
if(dbits == 0)
return kDepthFormatNone;
return dbits == 16 ? kDepthFormat16 : kDepthFormat24;
}
#endif // GL_RT_COMMON_GLES || GL_RT_COMMON_GLES2
#endif // GL_RT_COMMON_H
|