SDL_shaders_gles2.c (20031B)
1 /* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2020 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 #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED 24 25 #include "SDL_video.h" 26 #include "SDL_opengles2.h" 27 #include "SDL_shaders_gles2.h" 28 #include "SDL_stdinc.h" 29 30 /************************************************************************************************* 31 * Vertex/fragment shader source * 32 *************************************************************************************************/ 33 /* Notes on a_angle: 34 * It is a vector containing sin and cos for rotation matrix 35 * To get correct rotation for most cases when a_angle is disabled cos 36 value is decremented by 1.0 to get proper output with 0.0 which is 37 default value 38 */ 39 static const Uint8 GLES2_VertexSrc_Default_[] = " \ 40 uniform mat4 u_projection; \ 41 attribute vec2 a_position; \ 42 attribute vec2 a_texCoord; \ 43 attribute vec2 a_angle; \ 44 attribute vec2 a_center; \ 45 varying vec2 v_texCoord; \ 46 \ 47 void main() \ 48 { \ 49 float s = a_angle[0]; \ 50 float c = a_angle[1] + 1.0; \ 51 mat2 rotationMatrix = mat2(c, -s, s, c); \ 52 vec2 position = rotationMatrix * (a_position - a_center) + a_center; \ 53 v_texCoord = a_texCoord; \ 54 gl_Position = u_projection * vec4(position, 0.0, 1.0);\ 55 gl_PointSize = 1.0; \ 56 } \ 57 "; 58 59 static const Uint8 GLES2_FragmentSrc_SolidSrc_[] = " \ 60 precision mediump float; \ 61 uniform vec4 u_color; \ 62 \ 63 void main() \ 64 { \ 65 gl_FragColor = u_color; \ 66 } \ 67 "; 68 69 static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_[] = " \ 70 precision mediump float; \ 71 uniform sampler2D u_texture; \ 72 uniform vec4 u_color; \ 73 varying vec2 v_texCoord; \ 74 \ 75 void main() \ 76 { \ 77 gl_FragColor = texture2D(u_texture, v_texCoord); \ 78 gl_FragColor *= u_color; \ 79 } \ 80 "; 81 82 /* ARGB to ABGR conversion */ 83 static const Uint8 GLES2_FragmentSrc_TextureARGBSrc_[] = " \ 84 precision mediump float; \ 85 uniform sampler2D u_texture; \ 86 uniform vec4 u_color; \ 87 varying vec2 v_texCoord; \ 88 \ 89 void main() \ 90 { \ 91 vec4 abgr = texture2D(u_texture, v_texCoord); \ 92 gl_FragColor = abgr; \ 93 gl_FragColor.r = abgr.b; \ 94 gl_FragColor.b = abgr.r; \ 95 gl_FragColor *= u_color; \ 96 } \ 97 "; 98 99 /* RGB to ABGR conversion */ 100 static const Uint8 GLES2_FragmentSrc_TextureRGBSrc_[] = " \ 101 precision mediump float; \ 102 uniform sampler2D u_texture; \ 103 uniform vec4 u_color; \ 104 varying vec2 v_texCoord; \ 105 \ 106 void main() \ 107 { \ 108 vec4 abgr = texture2D(u_texture, v_texCoord); \ 109 gl_FragColor = abgr; \ 110 gl_FragColor.r = abgr.b; \ 111 gl_FragColor.b = abgr.r; \ 112 gl_FragColor.a = 1.0; \ 113 gl_FragColor *= u_color; \ 114 } \ 115 "; 116 117 /* BGR to ABGR conversion */ 118 static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ 119 precision mediump float; \ 120 uniform sampler2D u_texture; \ 121 uniform vec4 u_color; \ 122 varying vec2 v_texCoord; \ 123 \ 124 void main() \ 125 { \ 126 vec4 abgr = texture2D(u_texture, v_texCoord); \ 127 gl_FragColor = abgr; \ 128 gl_FragColor.a = 1.0; \ 129 gl_FragColor *= u_color; \ 130 } \ 131 "; 132 133 #define JPEG_SHADER_CONSTANTS \ 134 "// YUV offset \n" \ 135 "const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \ 136 "\n" \ 137 "// RGB coefficients \n" \ 138 "const mat3 matrix = mat3( 1, 1, 1,\n" \ 139 " 0, -0.3441, 1.772,\n" \ 140 " 1.402, -0.7141, 0);\n" \ 141 142 #define BT601_SHADER_CONSTANTS \ 143 "// YUV offset \n" \ 144 "const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \ 145 "\n" \ 146 "// RGB coefficients \n" \ 147 "const mat3 matrix = mat3( 1.1644, 1.1644, 1.1644,\n" \ 148 " 0, -0.3918, 2.0172,\n" \ 149 " 1.596, -0.813, 0);\n" \ 150 151 #define BT709_SHADER_CONSTANTS \ 152 "// YUV offset \n" \ 153 "const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \ 154 "\n" \ 155 "// RGB coefficients \n" \ 156 "const mat3 matrix = mat3( 1.1644, 1.1644, 1.1644,\n" \ 157 " 0, -0.2132, 2.1124,\n" \ 158 " 1.7927, -0.5329, 0);\n" \ 159 160 161 #define YUV_SHADER_PROLOGUE \ 162 "precision mediump float;\n" \ 163 "uniform sampler2D u_texture;\n" \ 164 "uniform sampler2D u_texture_u;\n" \ 165 "uniform sampler2D u_texture_v;\n" \ 166 "uniform vec4 u_color;\n" \ 167 "varying vec2 v_texCoord;\n" \ 168 "\n" \ 169 170 #define YUV_SHADER_BODY \ 171 "\n" \ 172 "void main()\n" \ 173 "{\n" \ 174 " mediump vec3 yuv;\n" \ 175 " lowp vec3 rgb;\n" \ 176 "\n" \ 177 " // Get the YUV values \n" \ 178 " yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ 179 " yuv.y = texture2D(u_texture_u, v_texCoord).r;\n" \ 180 " yuv.z = texture2D(u_texture_v, v_texCoord).r;\n" \ 181 "\n" \ 182 " // Do the color transform \n" \ 183 " yuv += offset;\n" \ 184 " rgb = matrix * yuv;\n" \ 185 "\n" \ 186 " // That was easy. :) \n" \ 187 " gl_FragColor = vec4(rgb, 1);\n" \ 188 " gl_FragColor *= u_color;\n" \ 189 "}" \ 190 191 #define NV12_SHADER_BODY \ 192 "\n" \ 193 "void main()\n" \ 194 "{\n" \ 195 " mediump vec3 yuv;\n" \ 196 " lowp vec3 rgb;\n" \ 197 "\n" \ 198 " // Get the YUV values \n" \ 199 " yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ 200 " yuv.yz = texture2D(u_texture_u, v_texCoord).ra;\n" \ 201 "\n" \ 202 " // Do the color transform \n" \ 203 " yuv += offset;\n" \ 204 " rgb = matrix * yuv;\n" \ 205 "\n" \ 206 " // That was easy. :) \n" \ 207 " gl_FragColor = vec4(rgb, 1);\n" \ 208 " gl_FragColor *= u_color;\n" \ 209 "}" \ 210 211 #define NV21_SHADER_BODY \ 212 "\n" \ 213 "void main()\n" \ 214 "{\n" \ 215 " mediump vec3 yuv;\n" \ 216 " lowp vec3 rgb;\n" \ 217 "\n" \ 218 " // Get the YUV values \n" \ 219 " yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ 220 " yuv.yz = texture2D(u_texture_u, v_texCoord).ar;\n" \ 221 "\n" \ 222 " // Do the color transform \n" \ 223 " yuv += offset;\n" \ 224 " rgb = matrix * yuv;\n" \ 225 "\n" \ 226 " // That was easy. :) \n" \ 227 " gl_FragColor = vec4(rgb, 1);\n" \ 228 " gl_FragColor *= u_color;\n" \ 229 "}" \ 230 231 /* YUV to ABGR conversion */ 232 static const Uint8 GLES2_FragmentSrc_TextureYUVJPEGSrc_[] = \ 233 YUV_SHADER_PROLOGUE \ 234 JPEG_SHADER_CONSTANTS \ 235 YUV_SHADER_BODY \ 236 ; 237 static const Uint8 GLES2_FragmentSrc_TextureYUVBT601Src_[] = \ 238 YUV_SHADER_PROLOGUE \ 239 BT601_SHADER_CONSTANTS \ 240 YUV_SHADER_BODY \ 241 ; 242 static const Uint8 GLES2_FragmentSrc_TextureYUVBT709Src_[] = \ 243 YUV_SHADER_PROLOGUE \ 244 BT709_SHADER_CONSTANTS \ 245 YUV_SHADER_BODY \ 246 ; 247 248 /* NV12 to ABGR conversion */ 249 static const Uint8 GLES2_FragmentSrc_TextureNV12JPEGSrc_[] = \ 250 YUV_SHADER_PROLOGUE \ 251 JPEG_SHADER_CONSTANTS \ 252 NV12_SHADER_BODY \ 253 ; 254 static const Uint8 GLES2_FragmentSrc_TextureNV12BT601Src_[] = \ 255 YUV_SHADER_PROLOGUE \ 256 BT601_SHADER_CONSTANTS \ 257 NV12_SHADER_BODY \ 258 ; 259 static const Uint8 GLES2_FragmentSrc_TextureNV12BT709Src_[] = \ 260 YUV_SHADER_PROLOGUE \ 261 BT709_SHADER_CONSTANTS \ 262 NV12_SHADER_BODY \ 263 ; 264 265 /* NV21 to ABGR conversion */ 266 static const Uint8 GLES2_FragmentSrc_TextureNV21JPEGSrc_[] = \ 267 YUV_SHADER_PROLOGUE \ 268 JPEG_SHADER_CONSTANTS \ 269 NV21_SHADER_BODY \ 270 ; 271 static const Uint8 GLES2_FragmentSrc_TextureNV21BT601Src_[] = \ 272 YUV_SHADER_PROLOGUE \ 273 BT601_SHADER_CONSTANTS \ 274 NV21_SHADER_BODY \ 275 ; 276 static const Uint8 GLES2_FragmentSrc_TextureNV21BT709Src_[] = \ 277 YUV_SHADER_PROLOGUE \ 278 BT709_SHADER_CONSTANTS \ 279 NV21_SHADER_BODY \ 280 ; 281 282 /* Custom Android video format texture */ 283 static const Uint8 GLES2_FragmentSrc_TextureExternalOESSrc_[] = " \ 284 #extension GL_OES_EGL_image_external : require\n\ 285 precision mediump float; \ 286 uniform samplerExternalOES u_texture; \ 287 uniform vec4 u_color; \ 288 varying vec2 v_texCoord; \ 289 \ 290 void main() \ 291 { \ 292 gl_FragColor = texture2D(u_texture, v_texCoord); \ 293 gl_FragColor *= u_color; \ 294 } \ 295 "; 296 297 static const GLES2_ShaderInstance GLES2_VertexSrc_Default = { 298 GL_VERTEX_SHADER, 299 GLES2_SOURCE_SHADER, 300 sizeof(GLES2_VertexSrc_Default_), 301 GLES2_VertexSrc_Default_ 302 }; 303 304 static const GLES2_ShaderInstance GLES2_FragmentSrc_SolidSrc = { 305 GL_FRAGMENT_SHADER, 306 GLES2_SOURCE_SHADER, 307 sizeof(GLES2_FragmentSrc_SolidSrc_), 308 GLES2_FragmentSrc_SolidSrc_ 309 }; 310 311 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureABGRSrc = { 312 GL_FRAGMENT_SHADER, 313 GLES2_SOURCE_SHADER, 314 sizeof(GLES2_FragmentSrc_TextureABGRSrc_), 315 GLES2_FragmentSrc_TextureABGRSrc_ 316 }; 317 318 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureARGBSrc = { 319 GL_FRAGMENT_SHADER, 320 GLES2_SOURCE_SHADER, 321 sizeof(GLES2_FragmentSrc_TextureARGBSrc_), 322 GLES2_FragmentSrc_TextureARGBSrc_ 323 }; 324 325 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureRGBSrc = { 326 GL_FRAGMENT_SHADER, 327 GLES2_SOURCE_SHADER, 328 sizeof(GLES2_FragmentSrc_TextureRGBSrc_), 329 GLES2_FragmentSrc_TextureRGBSrc_ 330 }; 331 332 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureBGRSrc = { 333 GL_FRAGMENT_SHADER, 334 GLES2_SOURCE_SHADER, 335 sizeof(GLES2_FragmentSrc_TextureBGRSrc_), 336 GLES2_FragmentSrc_TextureBGRSrc_ 337 }; 338 339 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVJPEGSrc = { 340 GL_FRAGMENT_SHADER, 341 GLES2_SOURCE_SHADER, 342 sizeof(GLES2_FragmentSrc_TextureYUVJPEGSrc_), 343 GLES2_FragmentSrc_TextureYUVJPEGSrc_ 344 }; 345 346 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVBT601Src = { 347 GL_FRAGMENT_SHADER, 348 GLES2_SOURCE_SHADER, 349 sizeof(GLES2_FragmentSrc_TextureYUVBT601Src_), 350 GLES2_FragmentSrc_TextureYUVBT601Src_ 351 }; 352 353 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVBT709Src = { 354 GL_FRAGMENT_SHADER, 355 GLES2_SOURCE_SHADER, 356 sizeof(GLES2_FragmentSrc_TextureYUVBT709Src_), 357 GLES2_FragmentSrc_TextureYUVBT709Src_ 358 }; 359 360 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12JPEGSrc = { 361 GL_FRAGMENT_SHADER, 362 GLES2_SOURCE_SHADER, 363 sizeof(GLES2_FragmentSrc_TextureNV12JPEGSrc_), 364 GLES2_FragmentSrc_TextureNV12JPEGSrc_ 365 }; 366 367 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT601Src = { 368 GL_FRAGMENT_SHADER, 369 GLES2_SOURCE_SHADER, 370 sizeof(GLES2_FragmentSrc_TextureNV12BT601Src_), 371 GLES2_FragmentSrc_TextureNV12BT601Src_ 372 }; 373 374 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21BT709Src = { 375 GL_FRAGMENT_SHADER, 376 GLES2_SOURCE_SHADER, 377 sizeof(GLES2_FragmentSrc_TextureNV21BT709Src_), 378 GLES2_FragmentSrc_TextureNV21BT709Src_ 379 }; 380 381 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21JPEGSrc = { 382 GL_FRAGMENT_SHADER, 383 GLES2_SOURCE_SHADER, 384 sizeof(GLES2_FragmentSrc_TextureNV21JPEGSrc_), 385 GLES2_FragmentSrc_TextureNV21JPEGSrc_ 386 }; 387 388 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21BT601Src = { 389 GL_FRAGMENT_SHADER, 390 GLES2_SOURCE_SHADER, 391 sizeof(GLES2_FragmentSrc_TextureNV21BT601Src_), 392 GLES2_FragmentSrc_TextureNV21BT601Src_ 393 }; 394 395 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT709Src = { 396 GL_FRAGMENT_SHADER, 397 GLES2_SOURCE_SHADER, 398 sizeof(GLES2_FragmentSrc_TextureNV12BT709Src_), 399 GLES2_FragmentSrc_TextureNV12BT709Src_ 400 }; 401 402 static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureExternalOESSrc = { 403 GL_FRAGMENT_SHADER, 404 GLES2_SOURCE_SHADER, 405 sizeof(GLES2_FragmentSrc_TextureExternalOESSrc_), 406 GLES2_FragmentSrc_TextureExternalOESSrc_ 407 }; 408 409 410 /************************************************************************************************* 411 * Vertex/fragment shader definitions * 412 *************************************************************************************************/ 413 414 static GLES2_Shader GLES2_VertexShader_Default = { 415 1, 416 { 417 &GLES2_VertexSrc_Default 418 } 419 }; 420 421 static GLES2_Shader GLES2_FragmentShader_SolidSrc = { 422 1, 423 { 424 &GLES2_FragmentSrc_SolidSrc 425 } 426 }; 427 428 static GLES2_Shader GLES2_FragmentShader_TextureABGRSrc = { 429 1, 430 { 431 &GLES2_FragmentSrc_TextureABGRSrc 432 } 433 }; 434 435 static GLES2_Shader GLES2_FragmentShader_TextureARGBSrc = { 436 1, 437 { 438 &GLES2_FragmentSrc_TextureARGBSrc 439 } 440 }; 441 442 static GLES2_Shader GLES2_FragmentShader_TextureRGBSrc = { 443 1, 444 { 445 &GLES2_FragmentSrc_TextureRGBSrc 446 } 447 }; 448 449 static GLES2_Shader GLES2_FragmentShader_TextureBGRSrc = { 450 1, 451 { 452 &GLES2_FragmentSrc_TextureBGRSrc 453 } 454 }; 455 456 static GLES2_Shader GLES2_FragmentShader_TextureYUVJPEGSrc = { 457 1, 458 { 459 &GLES2_FragmentSrc_TextureYUVJPEGSrc 460 } 461 }; 462 463 static GLES2_Shader GLES2_FragmentShader_TextureYUVBT601Src = { 464 1, 465 { 466 &GLES2_FragmentSrc_TextureYUVBT601Src 467 } 468 }; 469 470 static GLES2_Shader GLES2_FragmentShader_TextureYUVBT709Src = { 471 1, 472 { 473 &GLES2_FragmentSrc_TextureYUVBT709Src 474 } 475 }; 476 477 static GLES2_Shader GLES2_FragmentShader_TextureNV12JPEGSrc = { 478 1, 479 { 480 &GLES2_FragmentSrc_TextureNV12JPEGSrc 481 } 482 }; 483 484 static GLES2_Shader GLES2_FragmentShader_TextureNV12BT601Src = { 485 1, 486 { 487 &GLES2_FragmentSrc_TextureNV12BT601Src 488 } 489 }; 490 491 static GLES2_Shader GLES2_FragmentShader_TextureNV12BT709Src = { 492 1, 493 { 494 &GLES2_FragmentSrc_TextureNV12BT709Src 495 } 496 }; 497 498 static GLES2_Shader GLES2_FragmentShader_TextureNV21JPEGSrc = { 499 1, 500 { 501 &GLES2_FragmentSrc_TextureNV21JPEGSrc 502 } 503 }; 504 505 static GLES2_Shader GLES2_FragmentShader_TextureNV21BT601Src = { 506 1, 507 { 508 &GLES2_FragmentSrc_TextureNV21BT601Src 509 } 510 }; 511 512 static GLES2_Shader GLES2_FragmentShader_TextureNV21BT709Src = { 513 1, 514 { 515 &GLES2_FragmentSrc_TextureNV21BT709Src 516 } 517 }; 518 519 static GLES2_Shader GLES2_FragmentShader_TextureExternalOESSrc = { 520 1, 521 { 522 &GLES2_FragmentSrc_TextureExternalOESSrc 523 } 524 }; 525 526 527 /************************************************************************************************* 528 * Shader selector * 529 *************************************************************************************************/ 530 531 const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type) 532 { 533 switch (type) { 534 case GLES2_SHADER_VERTEX_DEFAULT: 535 return &GLES2_VertexShader_Default; 536 case GLES2_SHADER_FRAGMENT_SOLID_SRC: 537 return &GLES2_FragmentShader_SolidSrc; 538 case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC: 539 return &GLES2_FragmentShader_TextureABGRSrc; 540 case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC: 541 return &GLES2_FragmentShader_TextureARGBSrc; 542 case GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC: 543 return &GLES2_FragmentShader_TextureRGBSrc; 544 case GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC: 545 return &GLES2_FragmentShader_TextureBGRSrc; 546 case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC: 547 return &GLES2_FragmentShader_TextureYUVJPEGSrc; 548 case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC: 549 return &GLES2_FragmentShader_TextureYUVBT601Src; 550 case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC: 551 return &GLES2_FragmentShader_TextureYUVBT709Src; 552 case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC: 553 return &GLES2_FragmentShader_TextureNV12JPEGSrc; 554 case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC: 555 return &GLES2_FragmentShader_TextureNV12BT601Src; 556 case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC: 557 return &GLES2_FragmentShader_TextureNV12BT709Src; 558 case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC: 559 return &GLES2_FragmentShader_TextureNV21JPEGSrc; 560 case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC: 561 return &GLES2_FragmentShader_TextureNV21BT601Src; 562 case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC: 563 return &GLES2_FragmentShader_TextureNV21BT709Src; 564 case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC: 565 return &GLES2_FragmentShader_TextureExternalOESSrc; 566 default: 567 return NULL; 568 } 569 } 570 571 #endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */ 572 573 /* vi: set ts=4 sw=4 expandtab: */