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