GLES1Shaders.inc (34539B)
1 // 2 // Copyright 2018 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // GLES1Shaders.inc: Defines GLES1 emulation shader. 8 9 // The following variables are added in GLES1Renderer::initializeRendererProgram 10 // bool clip_plane_enables 11 // bool enable_alpha_test 12 // bool enable_clip_planes 13 // bool enable_color_material 14 // bool enable_draw_texture 15 // bool enable_fog 16 // bool enable_lighting 17 // bool enable_normalize 18 // bool enable_rescale_normal 19 // bool enable_texture_2d[kMaxTexUnits] 20 // bool enable_texture_cube_map[kMaxTexUnits] 21 // bool light_enables[kMaxLights] 22 // bool light_model_two_sided 23 // bool point_rasterization 24 // bool point_sprite_coord_replace 25 // bool point_sprite_enabled 26 // bool shade_model_flat 27 // int texture_format[kMaxTexUnits]; 28 // int texture_env_mode[kMaxTexUnits]; 29 // int combine_rgb[kMaxTexUnits]; 30 // int combine_alpha[kMaxTexUnits]; 31 // int src0_rgb[kMaxTexUnits]; 32 // int src0_alpha[kMaxTexUnits]; 33 // int src1_rgb[kMaxTexUnits]; 34 // int src1_alpha[kMaxTexUnits]; 35 // int src2_rgb[kMaxTexUnits]; 36 // int src2_alpha[kMaxTexUnits]; 37 // int op0_rgb[kMaxTexUnits]; 38 // int op0_alpha[kMaxTexUnits]; 39 // int op1_rgb[kMaxTexUnits]; 40 // int op1_alpha[kMaxTexUnits]; 41 // int op2_rgb[kMaxTexUnits]; 42 // int op2_alpha[kMaxTexUnits]; 43 // int alpha_func; 44 // int fog_mode; 45 46 constexpr char kGLES1DrawVShaderHeader[] = R"(#version 300 es 47 precision highp float; 48 49 #define kMaxTexUnits 4 50 #define kMaxLights 8 51 )"; 52 53 constexpr char kGLES1DrawVShader[] = R"( 54 55 in vec4 pos; 56 in vec3 normal; 57 in vec4 color; 58 in float pointsize; 59 in vec4 texcoord0; 60 in vec4 texcoord1; 61 in vec4 texcoord2; 62 in vec4 texcoord3; 63 64 uniform mat4 projection; 65 uniform mat4 modelview; 66 uniform mat4 modelview_invtr; 67 uniform mat4 texture_matrix[kMaxTexUnits]; 68 69 // Point rasterization////////////////////////////////////////////////////////// 70 71 uniform float point_size_min; 72 uniform float point_size_max; 73 uniform vec3 point_distance_attenuation; 74 75 // Shading: flat shading, lighting, and materials/////////////////////////////// 76 77 uniform vec4 material_ambient; 78 uniform vec4 material_diffuse; 79 uniform vec4 material_specular; 80 uniform vec4 material_emissive; 81 uniform float material_specular_exponent; 82 83 uniform vec4 light_model_scene_ambient; 84 85 uniform vec4 light_ambients[kMaxLights]; 86 uniform vec4 light_diffuses[kMaxLights]; 87 uniform vec4 light_speculars[kMaxLights]; 88 uniform vec4 light_positions[kMaxLights]; 89 uniform vec3 light_directions[kMaxLights]; 90 uniform float light_spotlight_exponents[kMaxLights]; 91 uniform float light_spotlight_cutoff_angles[kMaxLights]; 92 uniform float light_attenuation_consts[kMaxLights]; 93 uniform float light_attenuation_linears[kMaxLights]; 94 uniform float light_attenuation_quadratics[kMaxLights]; 95 96 // GL_OES_draw_texture uniforms///////////////////////////////////////////////// 97 98 uniform vec4 draw_texture_coords; 99 uniform vec2 draw_texture_dims; 100 uniform vec4 draw_texture_normalized_crop_rect[kMaxTexUnits]; 101 102 // Varyings///////////////////////////////////////////////////////////////////// 103 104 out vec4 pos_varying; 105 out vec3 normal_varying; 106 out vec4 color_varying; 107 flat out vec4 color_varying_flat; 108 out vec4 texcoord0_varying; 109 out vec4 texcoord1_varying; 110 out vec4 texcoord2_varying; 111 out vec4 texcoord3_varying; 112 113 float posDot(vec3 a, vec3 b) 114 { 115 return max(dot(a, b), 0.0); 116 } 117 118 vec4 doLighting(vec4 vertexColor) 119 { 120 vec4 materialAmbientActual = material_ambient; 121 vec4 materialDiffuseActual = material_diffuse; 122 123 if (enable_color_material) 124 { 125 materialAmbientActual = vertexColor; 126 materialDiffuseActual = vertexColor; 127 } 128 129 vec4 lightingResult = material_emissive + materialAmbientActual * light_model_scene_ambient; 130 131 for (int i = 0; i < kMaxLights; i++) 132 { 133 134 if (!light_enables[i]) 135 continue; 136 137 vec4 lightAmbient = light_ambients[i]; 138 vec4 lightDiffuse = light_diffuses[i]; 139 vec4 lightSpecular = light_speculars[i]; 140 vec4 lightPos = light_positions[i]; 141 vec3 lightDir = light_directions[i]; 142 float attConst = light_attenuation_consts[i]; 143 float attLinear = light_attenuation_linears[i]; 144 float attQuadratic = light_attenuation_quadratics[i]; 145 float spotAngle = light_spotlight_cutoff_angles[i]; 146 float spotExponent = light_spotlight_exponents[i]; 147 148 vec3 toLight; 149 if (lightPos.w == 0.0) 150 { 151 toLight = lightPos.xyz; 152 } 153 else 154 { 155 toLight = (lightPos.xyz / lightPos.w - pos_varying.xyz); 156 } 157 158 float lightDist = length(toLight); 159 vec3 h = normalize(toLight) + vec3(0.0, 0.0, 1.0); 160 float ndotL = posDot(normal_varying, normalize(toLight)); 161 float ndoth = posDot(normal_varying, normalize(h)); 162 163 float specAtt; 164 165 if (ndotL != 0.0) 166 { 167 specAtt = 1.0; 168 } 169 else 170 { 171 specAtt = 0.0; 172 } 173 174 float att; 175 176 if (lightPos.w != 0.0) 177 { 178 float attDenom = 179 (attConst + attLinear * lightDist + attQuadratic * lightDist * lightDist); 180 att = 1.0 / attDenom; 181 } 182 else 183 { 184 att = 1.0; 185 } 186 187 float spot; 188 189 float spotAngleCos = cos(radians(spotAngle)); 190 vec3 toSurfaceDir = -normalize(toLight); 191 float spotDot = posDot(toSurfaceDir, normalize(lightDir)); 192 193 if (spotAngle == 180.0 || lightPos.w == 0.0) 194 { 195 spot = 1.0; 196 } 197 else 198 { 199 if (spotDot < spotAngleCos) 200 { 201 spot = 0.0; 202 } 203 else 204 { 205 spot = pow(spotDot, spotExponent); 206 } 207 } 208 209 vec4 contrib = materialAmbientActual * lightAmbient; 210 contrib += ndotL * materialDiffuseActual * lightDiffuse; 211 if (ndoth > 0.0 && material_specular_exponent > 0.0) 212 { 213 contrib += specAtt * pow(ndoth, material_specular_exponent) * material_specular * 214 lightSpecular; 215 } 216 else 217 { 218 if (ndoth > 0.0) 219 { 220 contrib += specAtt * material_specular * lightSpecular; 221 } 222 } 223 contrib *= att * spot; 224 lightingResult += contrib; 225 } 226 227 return lightingResult; 228 } 229 230 const vec4 drawTextureVertices[6] = vec4[]( 231 vec4(0.0, 0.0, 0.0, 1.0), 232 vec4(1.0, 0.0, 0.0, 1.0), 233 vec4(1.0, 1.0, 0.0, 1.0), 234 vec4(0.0, 0.0, 0.0, 1.0), 235 vec4(1.0, 1.0, 0.0, 1.0), 236 vec4(0.0, 1.0, 0.0, 1.0)); 237 238 vec4 drawTexturePosition(int vertexId) 239 { 240 241 float drawTexX = draw_texture_coords[0]; 242 float drawTexY = draw_texture_coords[1]; 243 float drawTexZ = draw_texture_coords[2]; 244 float drawTexW = draw_texture_dims[0]; 245 float drawTexH = draw_texture_dims[1]; 246 247 return vec4(drawTexX, drawTexY, drawTexZ, 0.0) + 248 drawTextureVertices[vertexId] * 249 vec4(drawTexW, drawTexH, 1.0, 1.0); 250 } 251 252 vec4 drawTextureTexCoord(int vertexId, int textureUnit) 253 { 254 float texCropU = draw_texture_normalized_crop_rect[textureUnit].x; 255 float texCropV = draw_texture_normalized_crop_rect[textureUnit].y; 256 float texCropW = draw_texture_normalized_crop_rect[textureUnit].z; 257 float texCropH = draw_texture_normalized_crop_rect[textureUnit].w; 258 259 return vec4(texCropU, texCropV, 0.0, 0.0) + 260 drawTextureVertices[vertexId] * 261 vec4(texCropW, texCropH, 0.0, 0.0); 262 } 263 264 vec4 calcWorldPosition(vec4 posInput) 265 { 266 return modelview * posInput; 267 } 268 269 vec4 calcNdcFromWorldPosition(vec4 worldPos) 270 { 271 return projection * worldPos; 272 } 273 274 float calcPointSize(vec4 ndcPos) 275 { 276 float dist = length(ndcPos.z); 277 float attConst = point_distance_attenuation[0]; 278 float attLinear = point_distance_attenuation[1]; 279 float attQuad = point_distance_attenuation[2]; 280 float attPart = attConst + attLinear * dist + attQuad * dist * dist; 281 float attPointSize = pointsize / pow(attPart, 0.5); 282 283 return clamp(attPointSize, point_size_min, point_size_max); 284 } 285 286 vec3 calcNormal(vec3 normalInput) 287 { 288 mat3 mvInvTr3 = mat3(modelview_invtr); 289 vec3 result = mvInvTr3 * normalInput; 290 291 if (enable_rescale_normal) 292 { 293 float rescale = 1.0; 294 vec3 rescaleVec = vec3(mvInvTr3[2]); 295 float len = length(rescaleVec); 296 if (len > 0.0) 297 { 298 rescale = 1.0 / len; 299 } 300 result *= rescale; 301 } 302 303 if (enable_normalize) 304 { 305 result = normalize(result); 306 } 307 308 return result; 309 } 310 311 void main() 312 { 313 if (enable_draw_texture) 314 { 315 int vertexId = gl_VertexID; 316 vec4 posDrawTexture = drawTexturePosition(vertexId); 317 318 gl_Position = posDrawTexture; 319 pos_varying = posDrawTexture; 320 321 normal_varying = normal; 322 323 gl_PointSize = pointsize; 324 325 texcoord0_varying = drawTextureTexCoord(vertexId, 0); 326 texcoord1_varying = drawTextureTexCoord(vertexId, 1); 327 texcoord2_varying = drawTextureTexCoord(vertexId, 2); 328 texcoord3_varying = drawTextureTexCoord(vertexId, 3); 329 } 330 else 331 { 332 vec4 worldPos = calcWorldPosition(pos); 333 vec4 ndcPos = calcNdcFromWorldPosition(worldPos); 334 335 gl_Position = ndcPos; 336 pos_varying = worldPos; 337 338 normal_varying = calcNormal(normal); 339 340 // Avoid calculating point size stuff 341 // if we are not rendering points. 342 if (point_rasterization) 343 { 344 gl_PointSize = calcPointSize(ndcPos); 345 } 346 else 347 { 348 gl_PointSize = pointsize; 349 } 350 351 texcoord0_varying = texture_matrix[0] * texcoord0; 352 texcoord1_varying = texture_matrix[1] * texcoord1; 353 texcoord2_varying = texture_matrix[2] * texcoord2; 354 texcoord3_varying = texture_matrix[3] * texcoord3; 355 } 356 357 vec4 vertex_color = color; 358 359 if (enable_lighting) 360 { 361 vertex_color = doLighting(color); 362 } 363 364 vertex_color = clamp(vertex_color, vec4(0), vec4(1)); 365 366 color_varying = vertex_color; 367 color_varying_flat = vertex_color; 368 } 369 )"; 370 371 constexpr char kGLES1DrawFShaderVersion[] = R"(#version 300 es 372 )"; 373 374 constexpr char kGLES1DrawFShaderHeader[] = R"(precision highp float; 375 376 // Defines for GL constants 377 #define kMaxTexUnits 4 378 #define kMaxClipPlanes 6 379 380 #define kModulate 0x2100 381 #define kDecal 0x2101 382 #define kCombine 0x8570 383 #define kReplace 0x1E01 384 #define kBlend 0x0BE2 385 #define kAdd 0x0104 386 387 #define kAddSigned 0x8574 388 #define kInterpolate 0x8575 389 #define kSubtract 0x84E7 390 #define kDot3Rgb 0x86AE 391 #define kDot3Rgba 0x86AF 392 393 #define kAlpha 0x1906 394 #define kRGB 0x1907 395 #define kRGBA 0x1908 396 #define kLuminance 0x1909 397 #define kLuminanceAlpha 0x190A 398 399 #define kTexture 0x1702 400 #define kConstant 0x8576 401 #define kPrimaryColor 0x8577 402 #define kPrevious 0x8578 403 404 #define kSrcColor 0x0300 405 #define kOneMinusSrcColor 0x0301 406 #define kSrcAlpha 0x0302 407 #define kOneMinusSrcAlpha 0x0303 408 409 #define kLinear 0x2601 410 #define kExp 0x0800 411 #define kExp2 0x0801 412 413 #define kNever 0x0200 414 #define kLess 0x0201 415 #define kEqual 0x0202 416 #define kLequal 0x0203 417 #define kGreater 0x0204 418 #define kNotequal 0x0205 419 #define kGequal 0x0206 420 #define kAlways 0x0207 421 #define kZero 0x0 422 #define kOne 0x1 423 424 #define kAnd 0u 425 #define kAndInverted 1u 426 #define kAndReverse 2u 427 #define kClear 3u 428 #define kCopy 4u 429 #define kCopyInverted 5u 430 #define kEquiv 6u 431 #define kInvert 7u 432 #define kNand 8u 433 #define kNoop 9u 434 #define kNor 10u 435 #define kOr 11u 436 #define kOrInverted 12u 437 #define kOrReverse 13u 438 #define kSet 14u 439 #define kXor 15u 440 )"; 441 442 constexpr char kGLES1DrawFShaderUniformDefs[] = R"( 443 444 // Texture units /////////////////////////////////////////////////////////////// 445 446 // These are not arrays because hw support for arrays 447 // of samplers is rather lacking. 448 449 uniform sampler2D tex_sampler0; 450 uniform samplerCube tex_cube_sampler0; 451 452 uniform sampler2D tex_sampler1; 453 uniform samplerCube tex_cube_sampler1; 454 455 uniform sampler2D tex_sampler2; 456 uniform samplerCube tex_cube_sampler2; 457 458 uniform sampler2D tex_sampler3; 459 uniform samplerCube tex_cube_sampler3; 460 461 uniform vec4 texture_env_color[kMaxTexUnits]; 462 uniform float texture_env_rgb_scale[kMaxTexUnits]; 463 uniform float texture_env_alpha_scale[kMaxTexUnits]; 464 465 // Vertex attributes//////////////////////////////////////////////////////////// 466 467 in vec4 pos_varying; 468 in vec3 normal_varying; 469 in vec4 color_varying; 470 flat in vec4 color_varying_flat; 471 in vec4 texcoord0_varying; 472 in vec4 texcoord1_varying; 473 in vec4 texcoord2_varying; 474 in vec4 texcoord3_varying; 475 476 // Alpha test/////////////////////////////////////////////////////////////////// 477 478 uniform float alpha_test_ref; 479 480 // Fog ///////////////////////////////////////////////////////////////////////// 481 482 uniform float fog_density; 483 uniform float fog_start; 484 uniform float fog_end; 485 uniform vec4 fog_color; 486 487 // User clip plane ///////////////////////////////////////////////////////////// 488 489 uniform vec4 clip_planes[kMaxClipPlanes]; 490 491 // Logic Op //////////////////////////////////////////////////////////////////// 492 493 // Format is: 494 // - 4x4 bits depicting the bit width of each channel of color output 495 // - 4 bits for the op based on LogicalOperation's packing 496 uniform highp uint logic_op; 497 498 // Point rasterization////////////////////////////////////////////////////////// 499 500 // GL_OES_draw_texture////////////////////////////////////////////////////////// 501 )"; 502 503 constexpr char kGLES1DrawFShaderOutputDef[] = R"( 504 out vec4 frag_color; 505 )"; 506 507 constexpr char kGLES1DrawFShaderFramebufferFetchOutputDef[] = R"( 508 inout vec4 frag_color; 509 )"; 510 511 constexpr char kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef[] = R"( 512 layout(noncoherent) inout vec4 frag_color; 513 )"; 514 515 constexpr char kGLES1DrawFShaderFunctions[] = R"( 516 517 bool doAlphaTest(vec4 currentFragment) 518 { 519 bool shouldPassAlpha = false; 520 float incAlpha = currentFragment.a; 521 522 switch (alpha_func) 523 { 524 case kNever: 525 shouldPassAlpha = false; 526 break; 527 case kLess: 528 shouldPassAlpha = incAlpha < alpha_test_ref; 529 break; 530 case kLequal: 531 shouldPassAlpha = incAlpha <= alpha_test_ref; 532 break; 533 case kEqual: 534 shouldPassAlpha = incAlpha == alpha_test_ref; 535 break; 536 case kGequal: 537 shouldPassAlpha = incAlpha >= alpha_test_ref; 538 break; 539 case kGreater: 540 shouldPassAlpha = incAlpha > alpha_test_ref; 541 break; 542 case kNotequal: 543 shouldPassAlpha = incAlpha != alpha_test_ref; 544 break; 545 case kAlways: 546 default: 547 shouldPassAlpha = true; 548 break; 549 } 550 551 return shouldPassAlpha; 552 } 553 554 bool doClipPlaneTest() 555 { 556 bool res = true; 557 558 for (int i = 0; i < kMaxClipPlanes; i++) 559 { 560 if (clip_plane_enables[i]) 561 { 562 float dist = dot(clip_planes[i].xyz, pos_varying.xyz) + clip_planes[i].w * pos_varying.w; 563 res = res && (dist >= 0.0); 564 } 565 } 566 567 return res; 568 } 569 570 vec4 doFog(vec4 currentFragment) 571 { 572 573 float eyeDist = -pos_varying.z / pos_varying.w; 574 float f = 1.0; 575 switch (fog_mode) 576 { 577 case kExp: 578 f = exp(-fog_density * eyeDist); 579 break; 580 case kExp2: 581 f = exp(-(pow(fog_density * eyeDist, 2.0))); 582 break; 583 case kLinear: 584 f = (fog_end - eyeDist) / (fog_end - fog_start); 585 break; 586 default: 587 break; 588 } 589 590 f = clamp(f, 0.0, 1.0); 591 vec4 result = vec4(f * currentFragment.rgb + (1.0 - f) * fog_color.rgb, currentFragment.a); 592 return result; 593 } 594 )"; 595 596 constexpr char kGLES1DrawFShaderLogicOpFramebufferFetchDisabled[] = R"( 597 vec4 applyLogicOp(vec4 currentFragment) 598 { 599 return currentFragment; 600 } 601 )"; 602 603 // applyLogicOp takes logic-op information from a packed uniform and applies it to the color 604 // attachment using framebuffer fetch. See the description of logic_op above for the format of the 605 // uniform. 606 // 607 // In particular, 4 bits in logic_op (at offset 16) contain the packed logical operation (of 608 // LogicalOperation type). Based on the selected operation, the formula specified in the spec is 609 // applied (applied as bitwise operations on unorm values). 610 constexpr char kGLES1DrawFShaderLogicOpFramebufferFetchEnabled[] = R"( 611 vec4 applyLogicOp(vec4 currentFragment) 612 { 613 vec4 previousFragment = frag_color; 614 615 mediump uvec4 channelWidths = uvec4(logic_op & 0xFu, 616 logic_op >> 4u & 0xFu, 617 logic_op >> 8u & 0xFu, 618 logic_op >> 12u & 0xFu); 619 620 mediump uvec4 channelMasks = (uvec4(1) << channelWidths) - 1u; 621 622 mediump uvec4 src = uvec4(round(currentFragment * vec4(channelMasks))); 623 mediump uvec4 dst = uvec4(round(previousFragment * vec4(channelMasks))); 624 mediump uvec4 result; 625 626 switch (logic_op >> 16u & 0xFu) 627 { 628 case kAnd: 629 result = src & dst; 630 break; 631 case kAndInverted: 632 result = ~src & dst; 633 break; 634 case kAndReverse: 635 result = src & ~dst; 636 break; 637 case kClear: 638 result = uvec4(0); 639 break; 640 case kCopy: 641 result = src; 642 break; 643 case kCopyInverted: 644 result = ~src; 645 break; 646 case kEquiv: 647 result = ~(src ^ dst); 648 break; 649 case kInvert: 650 result = ~dst; 651 break; 652 case kNand: 653 result = ~(src & dst); 654 break; 655 case kNoop: 656 result = dst; 657 break; 658 case kNor: 659 result = ~(src | dst); 660 break; 661 case kOr: 662 result = src | dst; 663 break; 664 case kOrInverted: 665 result = ~src | dst; 666 break; 667 case kOrReverse: 668 result = src | ~dst; 669 break; 670 case kSet: 671 result = channelMasks; 672 break; 673 case kXor: 674 result = src ^ dst; 675 break; 676 } 677 678 result &= channelMasks; 679 680 // Avoid division by zero for formats without alpha 681 channelMasks.a = max(channelMasks.a, 1u); 682 683 return vec4(result) / vec4(channelMasks); 684 } 685 )"; 686 687 constexpr char kGLES1DrawFShaderMultitexturing[] = R"( 688 689 bool isTextureUnitEnabled(int unit) 690 { 691 return enable_texture_2d[unit] || enable_texture_cube_map[unit]; 692 } 693 694 vec4 getTextureColor(int unit) 695 { 696 vec4 res; 697 698 switch (unit) 699 { 700 case 0: 701 if (enable_texture_2d[0]) 702 { 703 res = texture(tex_sampler0, texcoord0_varying.xy); 704 } 705 else if (enable_texture_cube_map[0]) 706 { 707 res = texture(tex_cube_sampler0, texcoord0_varying.xyz); 708 } 709 break; 710 case 1: 711 if (enable_texture_2d[1]) 712 { 713 res = texture(tex_sampler1, texcoord1_varying.xy); 714 } 715 else if (enable_texture_cube_map[1]) 716 { 717 res = texture(tex_cube_sampler1, texcoord1_varying.xyz); 718 } 719 break; 720 case 2: 721 if (enable_texture_2d[2]) 722 { 723 res = texture(tex_sampler2, texcoord2_varying.xy); 724 } 725 else if (enable_texture_cube_map[2]) 726 { 727 res = texture(tex_cube_sampler2, texcoord2_varying.xyz); 728 } 729 break; 730 case 3: 731 if (enable_texture_2d[3]) 732 { 733 res = texture(tex_sampler3, texcoord3_varying.xy); 734 } 735 else if (enable_texture_cube_map[3]) 736 { 737 // TODO: Weird stuff happens 738 // res = texture(tex_cube_sampler3, texcoord3_varying.xyz); 739 } 740 break; 741 default: 742 break; 743 } 744 745 return res; 746 } 747 748 vec4 getPointSpriteTextureColor(int unit) 749 { 750 vec4 res; 751 752 switch (unit) 753 { 754 case 0: 755 if (enable_texture_2d[0]) 756 { 757 res = texture(tex_sampler0, gl_PointCoord.xy); 758 } 759 break; 760 case 1: 761 if (enable_texture_2d[1]) 762 { 763 res = texture(tex_sampler1, gl_PointCoord.xy); 764 } 765 break; 766 case 2: 767 if (enable_texture_2d[2]) 768 { 769 res = texture(tex_sampler2, gl_PointCoord.xy); 770 } 771 break; 772 case 3: 773 if (enable_texture_2d[3]) 774 { 775 res = texture(tex_sampler3, gl_PointCoord.xy); 776 } 777 break; 778 default: 779 break; 780 } 781 782 return res; 783 } 784 785 vec3 textureCombineSrcnOpnRgb(int srcnRgb, 786 int opnRgb, 787 vec4 textureEnvColor, 788 vec4 vertexColor, 789 vec4 texturePrevColor, 790 vec4 textureColor) 791 { 792 vec3 res; 793 vec4 op; 794 795 switch (srcnRgb) 796 { 797 case kTexture: 798 op = textureColor; 799 break; 800 case kConstant: 801 op = textureEnvColor; 802 break; 803 case kPrimaryColor: 804 op = vertexColor; 805 break; 806 case kPrevious: 807 op = texturePrevColor; 808 break; 809 default: 810 op = texturePrevColor; 811 break; 812 } 813 814 switch (opnRgb) 815 { 816 case kSrcColor: 817 res = op.rgb; 818 break; 819 case kOneMinusSrcColor: 820 res = 1.0 - op.rgb; 821 break; 822 case kSrcAlpha: 823 res = vec3(op.a, op.a, op.a); 824 break; 825 case kOneMinusSrcAlpha: 826 res = vec3(1.0 - op.a, 1.0 - op.a, 1.0 - op.a); 827 break; 828 default: 829 break; 830 } 831 832 return res; 833 } 834 835 float textureCombineSrcnOpnAlpha(int srcn, 836 int opn, 837 vec4 textureEnvColor, 838 vec4 vertexColor, 839 vec4 texturePrevColor, 840 vec4 textureColor) 841 { 842 float res; 843 vec4 op; 844 845 switch (srcn) 846 { 847 case kTexture: 848 op = textureColor; 849 break; 850 case kConstant: 851 op = textureEnvColor; 852 break; 853 case kPrimaryColor: 854 op = vertexColor; 855 break; 856 case kPrevious: 857 op = texturePrevColor; 858 break; 859 default: 860 op = texturePrevColor; 861 break; 862 } 863 864 switch (opn) 865 { 866 case kSrcAlpha: 867 res = op.a; 868 break; 869 case kOneMinusSrcAlpha: 870 res = 1.0 - op.a; 871 break; 872 default: 873 break; 874 } 875 876 return res; 877 } 878 879 vec4 textureCombine(int combineRgb, 880 int combineAlpha, 881 int src0Rgb, 882 int src0Alpha, 883 int src1Rgb, 884 int src1Alpha, 885 int src2Rgb, 886 int src2Alpha, 887 int op0Rgb, 888 int op0Alpha, 889 int op1Rgb, 890 int op1Alpha, 891 int op2Rgb, 892 int op2Alpha, 893 vec4 textureEnvColor, 894 float rgbScale, 895 float alphaScale, 896 vec4 vertexColor, 897 vec4 texturePrevColor, 898 vec4 textureColor) 899 { 900 901 vec3 resRgb; 902 float resAlpha; 903 904 vec3 arg0Rgb; 905 float arg0Alpha; 906 vec3 arg1Rgb; 907 float arg1Alpha; 908 vec3 arg2Rgb; 909 float arg2Alpha; 910 float dotVal; 911 912 arg0Rgb = textureCombineSrcnOpnRgb(src0Rgb, op0Rgb, textureEnvColor, vertexColor, 913 texturePrevColor, textureColor); 914 arg0Alpha = textureCombineSrcnOpnAlpha(src0Alpha, op0Alpha, textureEnvColor, vertexColor, 915 texturePrevColor, textureColor); 916 917 if (combineRgb != kReplace) 918 { 919 arg1Rgb = textureCombineSrcnOpnRgb(src1Rgb, op1Rgb, textureEnvColor, vertexColor, 920 texturePrevColor, textureColor); 921 } 922 923 if (combineAlpha != kReplace) 924 { 925 arg1Alpha = textureCombineSrcnOpnAlpha(src1Alpha, op1Alpha, textureEnvColor, vertexColor, 926 texturePrevColor, textureColor); 927 } 928 929 if (combineRgb == kInterpolate) 930 { 931 arg2Rgb = textureCombineSrcnOpnRgb(src2Rgb, op2Rgb, textureEnvColor, vertexColor, 932 texturePrevColor, textureColor); 933 } 934 935 if (combineAlpha == kInterpolate) 936 { 937 arg2Alpha = textureCombineSrcnOpnAlpha(src2Alpha, op2Alpha, textureEnvColor, vertexColor, 938 texturePrevColor, textureColor); 939 } 940 941 switch (combineRgb) 942 { 943 case kReplace: 944 resRgb = arg0Rgb; 945 break; 946 case kModulate: 947 resRgb = arg0Rgb * arg1Rgb; 948 break; 949 case kAdd: 950 resRgb = arg0Rgb + arg1Rgb; 951 break; 952 case kAddSigned: 953 resRgb = arg0Rgb + arg1Rgb - 0.5; 954 break; 955 case kInterpolate: 956 resRgb = arg0Rgb * arg2Rgb + arg1Rgb * (1.0 - arg2Rgb); 957 break; 958 case kSubtract: 959 resRgb = arg0Rgb - arg1Rgb; 960 break; 961 default: 962 break; 963 } 964 965 switch (combineAlpha) 966 { 967 case kReplace: 968 resAlpha = arg0Alpha; 969 break; 970 case kModulate: 971 resAlpha = arg0Alpha * arg1Alpha; 972 break; 973 case kAdd: 974 resAlpha = arg0Alpha + arg1Alpha; 975 break; 976 case kAddSigned: 977 resAlpha = arg0Alpha + arg1Alpha - 0.5; 978 break; 979 case kInterpolate: 980 resAlpha = arg0Alpha * arg2Alpha + arg1Alpha * (1.0 - arg2Alpha); 981 break; 982 case kSubtract: 983 resAlpha = arg0Alpha - arg1Alpha; 984 break; 985 default: 986 break; 987 } 988 989 if (combineRgb == kDot3Rgb || combineRgb == kDot3Rgba) 990 { 991 dotVal = 4.0 * dot(arg0Rgb - 0.5, arg1Rgb - 0.5); 992 993 if (combineRgb == kDot3Rgb) 994 { 995 return vec4(dotVal, dotVal, dotVal, resAlpha); 996 } 997 else 998 { 999 return vec4(dotVal, dotVal, dotVal, dotVal); 1000 } 1001 } 1002 else 1003 { 1004 return vec4(resRgb, resAlpha); 1005 } 1006 } 1007 1008 vec4 textureFunction(int unit, 1009 int texFormat, 1010 int envMode, 1011 int combineRgb, 1012 int combineAlpha, 1013 int src0Rgb, 1014 int src0Alpha, 1015 int src1Rgb, 1016 int src1Alpha, 1017 int src2Rgb, 1018 int src2Alpha, 1019 int op0Rgb, 1020 int op0Alpha, 1021 int op1Rgb, 1022 int op1Alpha, 1023 int op2Rgb, 1024 int op2Alpha, 1025 vec4 textureEnvColor, 1026 float rgbScale, 1027 float alphaScale, 1028 vec4 vertexColor, 1029 vec4 texturePrevColor, 1030 vec4 textureColor) 1031 { 1032 1033 if (!isTextureUnitEnabled(unit)) 1034 { 1035 return texturePrevColor; 1036 } 1037 1038 vec4 res; 1039 1040 switch (envMode) 1041 { 1042 case kReplace: 1043 switch (texFormat) 1044 { 1045 case kAlpha: 1046 res.rgb = texturePrevColor.rgb; 1047 res.a = textureColor.a; 1048 break; 1049 case kRGBA: 1050 case kLuminanceAlpha: 1051 res.rgba = textureColor.rgba; 1052 break; 1053 case kRGB: 1054 case kLuminance: 1055 default: 1056 res.rgb = textureColor.rgb; 1057 res.a = texturePrevColor.a; 1058 break; 1059 } 1060 break; 1061 case kModulate: 1062 switch (texFormat) 1063 { 1064 case kAlpha: 1065 res.rgb = texturePrevColor.rgb; 1066 res.a = texturePrevColor.a * textureColor.a; 1067 break; 1068 case kRGBA: 1069 case kLuminanceAlpha: 1070 res.rgba = texturePrevColor.rgba * textureColor.rgba; 1071 break; 1072 case kRGB: 1073 case kLuminance: 1074 default: 1075 res.rgb = texturePrevColor.rgb * textureColor.rgb; 1076 res.a = texturePrevColor.a; 1077 break; 1078 } 1079 break; 1080 case kDecal: 1081 switch (texFormat) 1082 { 1083 case kRGB: 1084 res.rgb = textureColor.rgb; 1085 res.a = texturePrevColor.a; 1086 break; 1087 case kRGBA: 1088 res.rgb = texturePrevColor.rgb * (1.0 - textureColor.a) + 1089 textureColor.rgb * textureColor.a; 1090 res.a = texturePrevColor.a; 1091 break; 1092 case kAlpha: 1093 case kLuminance: 1094 case kLuminanceAlpha: 1095 default: 1096 res.rgb = texturePrevColor.rgb * textureColor.rgb; 1097 res.a = texturePrevColor.a; 1098 break; 1099 } 1100 break; 1101 case kBlend: 1102 switch (texFormat) 1103 { 1104 case kAlpha: 1105 res.rgb = texturePrevColor.rgb; 1106 res.a = textureColor.a * texturePrevColor.a; 1107 break; 1108 case kLuminance: 1109 case kRGB: 1110 res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) + 1111 textureEnvColor.rgb * textureColor.rgb; 1112 res.a = texturePrevColor.a; 1113 break; 1114 case kLuminanceAlpha: 1115 case kRGBA: 1116 default: 1117 res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) + 1118 textureEnvColor.rgb * textureColor.rgb; 1119 res.a = textureColor.a * texturePrevColor.a; 1120 break; 1121 } 1122 break; 1123 case kAdd: 1124 switch (texFormat) 1125 { 1126 case kAlpha: 1127 res.rgb = texturePrevColor.rgb; 1128 res.a = textureColor.a * texturePrevColor.a; 1129 break; 1130 case kLuminance: 1131 case kRGB: 1132 res.rgb = texturePrevColor.rgb + textureColor.rgb; 1133 res.a = texturePrevColor.a; 1134 break; 1135 case kLuminanceAlpha: 1136 case kRGBA: 1137 default: 1138 res.rgb = texturePrevColor.rgb + textureColor.rgb; 1139 res.a = textureColor.a * texturePrevColor.a; 1140 break; 1141 } 1142 break; 1143 case kCombine: 1144 res = textureCombine(combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha, 1145 src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb, 1146 op2Alpha, textureEnvColor, rgbScale, alphaScale, vertexColor, 1147 texturePrevColor, textureColor); 1148 res.rgb *= rgbScale; 1149 res.a *= alphaScale; 1150 break; 1151 default: 1152 break; 1153 } 1154 1155 return clamp(res, 0.0, 1.0); 1156 } 1157 )"; 1158 1159 constexpr char kGLES1DrawFShaderMain[] = R"( 1160 void main() 1161 { 1162 if (enable_clip_planes && !enable_draw_texture) 1163 { 1164 if (!doClipPlaneTest()) 1165 { 1166 discard; 1167 } 1168 } 1169 1170 vec4 vertex_color; 1171 1172 if (shade_model_flat) 1173 { 1174 vertex_color = color_varying_flat; 1175 } 1176 else 1177 { 1178 vertex_color = color_varying; 1179 } 1180 1181 vec4 currentFragment = vertex_color; 1182 1183 vec4 texturePrevColor = currentFragment; 1184 1185 for (int i = 0; i < kMaxTexUnits; i++) 1186 { 1187 vec4 textureColor; 1188 1189 if (point_rasterization && point_sprite_enabled && 1190 point_sprite_coord_replace[i]) { 1191 textureColor = getPointSpriteTextureColor(i); 1192 } else { 1193 textureColor = getTextureColor(i); 1194 } 1195 1196 currentFragment = textureFunction( 1197 i, texture_format[i], texture_env_mode[i], combine_rgb[i], combine_alpha[i], 1198 src0_rgb[i], src0_alpha[i], src1_rgb[i], src1_alpha[i], src2_rgb[i], src2_alpha[i], 1199 op0_rgb[i], op0_alpha[i], op1_rgb[i], op1_alpha[i], op2_rgb[i], op2_alpha[i], 1200 texture_env_color[i], texture_env_rgb_scale[i], texture_env_alpha_scale[i], 1201 vertex_color, texturePrevColor, textureColor); 1202 1203 texturePrevColor = currentFragment; 1204 } 1205 1206 if (enable_fog) 1207 { 1208 currentFragment = doFog(currentFragment); 1209 } 1210 1211 if (enable_alpha_test && !doAlphaTest(currentFragment)) 1212 { 1213 discard; 1214 } 1215 1216 frag_color = applyLogicOp(currentFragment); 1217 } 1218 )";