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