summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c')
-rw-r--r--contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c b/contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c
new file mode 100644
index 0000000..1387968
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/render/opengles2/SDL_shaders_gles2.c
@@ -0,0 +1,387 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_RENDER_OGL_ES2
24
25#include <SDL3/SDL_opengles2.h>
26#include "SDL_shaders_gles2.h"
27
28/* *INDENT-OFF* */ // clang-format off
29
30/*************************************************************************************************
31 * Vertex/fragment shader source *
32 *************************************************************************************************/
33
34static const char GLES2_Fragment_Include_Best_Texture_Precision[] = \
35"#ifdef GL_FRAGMENT_PRECISION_HIGH\n" \
36"#define SDL_TEXCOORD_PRECISION highp\n" \
37"#else\n" \
38"#define SDL_TEXCOORD_PRECISION mediump\n" \
39"#endif\n" \
40"\n" \
41"precision mediump float;\n" \
42"\n" \
43;
44
45static const char GLES2_Fragment_Include_Medium_Texture_Precision[] = \
46"#define SDL_TEXCOORD_PRECISION mediump\n" \
47"precision mediump float;\n" \
48"\n" \
49;
50
51static const char GLES2_Fragment_Include_High_Texture_Precision[] = \
52"#define SDL_TEXCOORD_PRECISION highp\n" \
53"precision mediump float;\n" \
54"\n" \
55;
56
57static const char GLES2_Fragment_Include_Undef_Precision[] = \
58"#define mediump\n" \
59"#define highp\n" \
60"#define lowp\n" \
61"#define SDL_TEXCOORD_PRECISION\n" \
62"\n" \
63;
64
65static const char GLES2_Vertex_Default[] = \
66"uniform mat4 u_projection;\n" \
67"attribute vec2 a_position;\n" \
68"attribute vec4 a_color;\n" \
69"attribute vec2 a_texCoord;\n" \
70"varying vec2 v_texCoord;\n" \
71"varying vec4 v_color;\n" \
72"\n" \
73"void main()\n" \
74"{\n" \
75" v_texCoord = a_texCoord;\n" \
76" gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n" \
77" gl_PointSize = 1.0;\n" \
78" v_color = a_color;\n" \
79"}\n" \
80;
81
82static const char GLES2_Fragment_Solid[] = \
83"varying mediump vec4 v_color;\n" \
84"\n" \
85"void main()\n" \
86"{\n" \
87" gl_FragColor = v_color;\n" \
88"}\n" \
89;
90
91static const char GLES2_Fragment_TextureABGR[] = \
92"uniform sampler2D u_texture;\n" \
93"varying mediump vec4 v_color;\n" \
94"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
95"\n" \
96"void main()\n" \
97"{\n" \
98" gl_FragColor = texture2D(u_texture, v_texCoord);\n" \
99" gl_FragColor *= v_color;\n" \
100"}\n" \
101;
102
103// ARGB to ABGR conversion
104static const char GLES2_Fragment_TextureARGB[] = \
105"uniform sampler2D u_texture;\n" \
106"varying mediump vec4 v_color;\n" \
107"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
108"\n" \
109"void main()\n" \
110"{\n" \
111" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \
112" gl_FragColor = abgr;\n" \
113" gl_FragColor.r = abgr.b;\n" \
114" gl_FragColor.b = abgr.r;\n" \
115" gl_FragColor *= v_color;\n" \
116"}\n" \
117;
118
119// RGB to ABGR conversion
120static const char GLES2_Fragment_TextureRGB[] = \
121"uniform sampler2D u_texture;\n" \
122"varying mediump vec4 v_color;\n" \
123"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
124"\n" \
125"void main()\n" \
126"{\n" \
127" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \
128" gl_FragColor = abgr;\n" \
129" gl_FragColor.r = abgr.b;\n" \
130" gl_FragColor.b = abgr.r;\n" \
131" gl_FragColor.a = 1.0;\n" \
132" gl_FragColor *= v_color;\n" \
133"}\n" \
134;
135
136// BGR to ABGR conversion
137static const char GLES2_Fragment_TextureBGR[] = \
138"uniform sampler2D u_texture;\n" \
139"varying mediump vec4 v_color;\n" \
140"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
141"\n" \
142"void main()\n" \
143"{\n" \
144" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \
145" gl_FragColor = abgr;\n" \
146" gl_FragColor.a = 1.0;\n" \
147" gl_FragColor *= v_color;\n" \
148"}\n" \
149;
150
151#ifdef SDL_HAVE_YUV
152
153#define YUV_SHADER_PROLOGUE \
154"uniform sampler2D u_texture;\n" \
155"uniform sampler2D u_texture_u;\n" \
156"uniform sampler2D u_texture_v;\n" \
157"uniform vec3 u_offset;\n" \
158"uniform mat3 u_matrix;\n" \
159"varying mediump vec4 v_color;\n" \
160"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
161"\n" \
162
163#define YUV_SHADER_BODY \
164"void main()\n" \
165"{\n" \
166" mediump vec3 yuv;\n" \
167" lowp vec3 rgb;\n" \
168"\n" \
169" // Get the YUV values \n" \
170" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
171" yuv.y = texture2D(u_texture_u, v_texCoord).r;\n" \
172" yuv.z = texture2D(u_texture_v, v_texCoord).r;\n" \
173"\n" \
174" // Do the color transform \n" \
175" yuv += u_offset;\n" \
176" rgb = yuv * u_matrix;\n" \
177"\n" \
178" // That was easy. :) \n" \
179" gl_FragColor = vec4(rgb, 1);\n" \
180" gl_FragColor *= v_color;\n" \
181"}" \
182
183#define NV12_RA_SHADER_BODY \
184"void main()\n" \
185"{\n" \
186" mediump vec3 yuv;\n" \
187" lowp vec3 rgb;\n" \
188"\n" \
189" // Get the YUV values \n" \
190" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
191" yuv.yz = texture2D(u_texture_u, v_texCoord).ra;\n" \
192"\n" \
193" // Do the color transform \n" \
194" yuv += u_offset;\n" \
195" rgb = yuv * u_matrix;\n" \
196"\n" \
197" // That was easy. :) \n" \
198" gl_FragColor = vec4(rgb, 1);\n" \
199" gl_FragColor *= v_color;\n" \
200"}" \
201
202#define NV12_RG_SHADER_BODY \
203"void main()\n" \
204"{\n" \
205" mediump vec3 yuv;\n" \
206" lowp vec3 rgb;\n" \
207"\n" \
208" // Get the YUV values \n" \
209" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
210" yuv.yz = texture2D(u_texture_u, v_texCoord).rg;\n" \
211"\n" \
212" // Do the color transform \n" \
213" yuv += u_offset;\n" \
214" rgb = yuv * u_matrix;\n" \
215"\n" \
216" // That was easy. :) \n" \
217" gl_FragColor = vec4(rgb, 1);\n" \
218" gl_FragColor *= v_color;\n" \
219"}" \
220
221#define NV21_RA_SHADER_BODY \
222"void main()\n" \
223"{\n" \
224" mediump vec3 yuv;\n" \
225" lowp vec3 rgb;\n" \
226"\n" \
227" // Get the YUV values \n" \
228" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
229" yuv.yz = texture2D(u_texture_u, v_texCoord).ar;\n" \
230"\n" \
231" // Do the color transform \n" \
232" yuv += u_offset;\n" \
233" rgb = yuv * u_matrix;\n" \
234"\n" \
235" // That was easy. :) \n" \
236" gl_FragColor = vec4(rgb, 1);\n" \
237" gl_FragColor *= v_color;\n" \
238"}" \
239
240#define NV21_RG_SHADER_BODY \
241"void main()\n" \
242"{\n" \
243" mediump vec3 yuv;\n" \
244" lowp vec3 rgb;\n" \
245"\n" \
246" // Get the YUV values \n" \
247" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
248" yuv.yz = texture2D(u_texture_u, v_texCoord).gr;\n" \
249"\n" \
250" // Do the color transform \n" \
251" yuv += u_offset;\n" \
252" rgb = yuv * u_matrix;\n" \
253"\n" \
254" // That was easy. :) \n" \
255" gl_FragColor = vec4(rgb, 1);\n" \
256" gl_FragColor *= v_color;\n" \
257"}" \
258
259// YUV to ABGR conversion
260static const char GLES2_Fragment_TextureYUV[] = \
261 YUV_SHADER_PROLOGUE \
262 YUV_SHADER_BODY \
263;
264
265// NV12 to ABGR conversion
266static const char GLES2_Fragment_TextureNV12_RA[] = \
267 YUV_SHADER_PROLOGUE \
268 NV12_RA_SHADER_BODY \
269;
270static const char GLES2_Fragment_TextureNV12_RG[] = \
271 YUV_SHADER_PROLOGUE \
272 NV12_RG_SHADER_BODY \
273;
274
275// NV21 to ABGR conversion
276static const char GLES2_Fragment_TextureNV21_RA[] = \
277 YUV_SHADER_PROLOGUE \
278 NV21_RA_SHADER_BODY \
279;
280static const char GLES2_Fragment_TextureNV21_RG[] = \
281 YUV_SHADER_PROLOGUE \
282 NV21_RG_SHADER_BODY \
283;
284#endif
285
286// Custom Android video format texture
287static const char GLES2_Fragment_TextureExternalOES_Prologue[] = \
288"#extension GL_OES_EGL_image_external : require\n" \
289"\n" \
290;
291static const char GLES2_Fragment_TextureExternalOES[] = \
292"uniform samplerExternalOES u_texture;\n" \
293"varying mediump vec4 v_color;\n" \
294"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
295"\n" \
296"void main()\n" \
297"{\n" \
298" gl_FragColor = texture2D(u_texture, v_texCoord);\n" \
299" gl_FragColor *= v_color;\n" \
300"}\n" \
301;
302
303/* *INDENT-ON* */ // clang-format on
304
305/*************************************************************************************************
306 * Shader selector *
307 *************************************************************************************************/
308
309const char *GLES2_GetShaderPrologue(GLES2_ShaderType type)
310{
311 switch (type) {
312 case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
313 return GLES2_Fragment_TextureExternalOES_Prologue;
314 default:
315 return "";
316 }
317}
318
319const char *GLES2_GetShaderInclude(GLES2_ShaderIncludeType type)
320{
321 switch (type) {
322 case GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION:
323 return GLES2_Fragment_Include_Undef_Precision;
324 case GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION:
325 return GLES2_Fragment_Include_Best_Texture_Precision;
326 case GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION:
327 return GLES2_Fragment_Include_Medium_Texture_Precision;
328 case GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION:
329 return GLES2_Fragment_Include_High_Texture_Precision;
330 default:
331 return "";
332 }
333}
334
335GLES2_ShaderIncludeType GLES2_GetTexCoordPrecisionEnumFromHint(void)
336{
337 const char *texcoord_hint = SDL_GetHint("SDL_RENDER_OPENGLES2_TEXCOORD_PRECISION");
338 GLES2_ShaderIncludeType value = GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION;
339 if (texcoord_hint) {
340 if (SDL_strcmp(texcoord_hint, "undefined") == 0) {
341 return GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION;
342 }
343 if (SDL_strcmp(texcoord_hint, "high") == 0) {
344 return GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION;
345 }
346 if (SDL_strcmp(texcoord_hint, "medium") == 0) {
347 return GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION;
348 }
349 }
350 return value;
351}
352
353const char *GLES2_GetShader(GLES2_ShaderType type)
354{
355 switch (type) {
356 case GLES2_SHADER_VERTEX_DEFAULT:
357 return GLES2_Vertex_Default;
358 case GLES2_SHADER_FRAGMENT_SOLID:
359 return GLES2_Fragment_Solid;
360 case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR:
361 return GLES2_Fragment_TextureABGR;
362 case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB:
363 return GLES2_Fragment_TextureARGB;
364 case GLES2_SHADER_FRAGMENT_TEXTURE_RGB:
365 return GLES2_Fragment_TextureRGB;
366 case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
367 return GLES2_Fragment_TextureBGR;
368#ifdef SDL_HAVE_YUV
369 case GLES2_SHADER_FRAGMENT_TEXTURE_YUV:
370 return GLES2_Fragment_TextureYUV;
371 case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA:
372 return GLES2_Fragment_TextureNV12_RA;
373 case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG:
374 return GLES2_Fragment_TextureNV12_RG;
375 case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_RA:
376 return GLES2_Fragment_TextureNV21_RA;
377 case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_RG:
378 return GLES2_Fragment_TextureNV21_RG;
379#endif
380 case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
381 return GLES2_Fragment_TextureExternalOES;
382 default:
383 return NULL;
384 }
385}
386
387#endif // SDL_VIDEO_RENDER_OGL_ES2