Commit 6c60641d by Lingfeng Yang Committed by Commit Bot

GLES1: Multitexture pipeline

- Update test expectations BUG=angleproject:2306 Change-Id: I4a0376db1d095d7b14e00a5779631dcf2a6c427c Reviewed-on: https://chromium-review.googlesource.com/1093795 Commit-Queue: Lingfeng Yang <lfy@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 071fc3f9
...@@ -115,6 +115,8 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState) ...@@ -115,6 +115,8 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState)
std::array<GLint, kTexUnitCount> &tex2DEnables = uniformBuffers.tex2DEnables; std::array<GLint, kTexUnitCount> &tex2DEnables = uniformBuffers.tex2DEnables;
std::array<GLint, kTexUnitCount> &texCubeEnables = uniformBuffers.texCubeEnables; std::array<GLint, kTexUnitCount> &texCubeEnables = uniformBuffers.texCubeEnables;
std::vector<int> tex2DFormats = {GL_RGBA, GL_RGBA, GL_RGBA, GL_RGBA};
for (int i = 0; i < kTexUnitCount; i++) for (int i = 0; i < kTexUnitCount; i++)
{ {
// GL_OES_cube_map allows only one of TEXTURE_2D / TEXTURE_CUBE_MAP // GL_OES_cube_map allows only one of TEXTURE_2D / TEXTURE_CUBE_MAP
...@@ -138,12 +140,93 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState) ...@@ -138,12 +140,93 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState)
texCubeEnables[i] = gles1State.isTextureTargetEnabled(i, TextureType::CubeMap); texCubeEnables[i] = gles1State.isTextureTargetEnabled(i, TextureType::CubeMap);
tex2DEnables[i] = tex2DEnables[i] =
!texCubeEnables[i] && (gles1State.isTextureTargetEnabled(i, TextureType::_2D)); !texCubeEnables[i] && (gles1State.isTextureTargetEnabled(i, TextureType::_2D));
Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D);
if (curr2DTexture)
{
tex2DFormats[i] = gl::GetUnsizedFormat(
curr2DTexture->getFormat(TextureTarget::_2D, 0).info->internalFormat);
}
} }
setUniform1iv(programObject, mProgramState.enableTexture2DLoc, kTexUnitCount, setUniform1iv(programObject, mProgramState.enableTexture2DLoc, kTexUnitCount,
tex2DEnables.data()); tex2DEnables.data());
setUniform1iv(programObject, mProgramState.enableTextureCubeMapLoc, kTexUnitCount, setUniform1iv(programObject, mProgramState.enableTextureCubeMapLoc, kTexUnitCount,
texCubeEnables.data()); texCubeEnables.data());
setUniform1iv(programObject, mProgramState.textureFormatLoc, kTexUnitCount,
tex2DFormats.data());
for (int i = 0; i < kTexUnitCount; i++)
{
const auto &env = gles1State.textureEnvironment(i);
uniformBuffers.texEnvModes[i] = ToGLenum(env.mode);
uniformBuffers.texCombineRgbs[i] = ToGLenum(env.combineRgb);
uniformBuffers.texCombineAlphas[i] = ToGLenum(env.combineAlpha);
uniformBuffers.texCombineSrc0Rgbs[i] = ToGLenum(env.src0Rgb);
uniformBuffers.texCombineSrc0Alphas[i] = ToGLenum(env.src0Alpha);
uniformBuffers.texCombineSrc1Rgbs[i] = ToGLenum(env.src1Rgb);
uniformBuffers.texCombineSrc1Alphas[i] = ToGLenum(env.src1Alpha);
uniformBuffers.texCombineSrc2Rgbs[i] = ToGLenum(env.src2Rgb);
uniformBuffers.texCombineSrc2Alphas[i] = ToGLenum(env.src2Alpha);
uniformBuffers.texCombineOp0Rgbs[i] = ToGLenum(env.op0Rgb);
uniformBuffers.texCombineOp0Alphas[i] = ToGLenum(env.op0Alpha);
uniformBuffers.texCombineOp1Rgbs[i] = ToGLenum(env.op1Rgb);
uniformBuffers.texCombineOp1Alphas[i] = ToGLenum(env.op1Alpha);
uniformBuffers.texCombineOp2Rgbs[i] = ToGLenum(env.op2Rgb);
uniformBuffers.texCombineOp2Alphas[i] = ToGLenum(env.op2Alpha);
uniformBuffers.texEnvColors[i][0] = env.color.red;
uniformBuffers.texEnvColors[i][1] = env.color.green;
uniformBuffers.texEnvColors[i][2] = env.color.blue;
uniformBuffers.texEnvColors[i][3] = env.color.alpha;
uniformBuffers.texEnvRgbScales[i] = env.rgbScale;
uniformBuffers.texEnvAlphaScales[i] = env.alphaScale;
}
setUniform1iv(programObject, mProgramState.textureEnvModeLoc, kTexUnitCount,
uniformBuffers.texEnvModes.data());
setUniform1iv(programObject, mProgramState.combineRgbLoc, kTexUnitCount,
uniformBuffers.texCombineRgbs.data());
setUniform1iv(programObject, mProgramState.combineAlphaLoc, kTexUnitCount,
uniformBuffers.texCombineAlphas.data());
setUniform1iv(programObject, mProgramState.src0rgbLoc, kTexUnitCount,
uniformBuffers.texCombineSrc0Rgbs.data());
setUniform1iv(programObject, mProgramState.src0alphaLoc, kTexUnitCount,
uniformBuffers.texCombineSrc0Alphas.data());
setUniform1iv(programObject, mProgramState.src1rgbLoc, kTexUnitCount,
uniformBuffers.texCombineSrc1Rgbs.data());
setUniform1iv(programObject, mProgramState.src1alphaLoc, kTexUnitCount,
uniformBuffers.texCombineSrc1Alphas.data());
setUniform1iv(programObject, mProgramState.src2rgbLoc, kTexUnitCount,
uniformBuffers.texCombineSrc2Rgbs.data());
setUniform1iv(programObject, mProgramState.src2alphaLoc, kTexUnitCount,
uniformBuffers.texCombineSrc2Alphas.data());
setUniform1iv(programObject, mProgramState.op0rgbLoc, kTexUnitCount,
uniformBuffers.texCombineOp0Rgbs.data());
setUniform1iv(programObject, mProgramState.op0alphaLoc, kTexUnitCount,
uniformBuffers.texCombineOp0Alphas.data());
setUniform1iv(programObject, mProgramState.op1rgbLoc, kTexUnitCount,
uniformBuffers.texCombineOp1Rgbs.data());
setUniform1iv(programObject, mProgramState.op1alphaLoc, kTexUnitCount,
uniformBuffers.texCombineOp1Alphas.data());
setUniform1iv(programObject, mProgramState.op2rgbLoc, kTexUnitCount,
uniformBuffers.texCombineOp2Rgbs.data());
setUniform1iv(programObject, mProgramState.op2alphaLoc, kTexUnitCount,
uniformBuffers.texCombineOp2Alphas.data());
setUniform4fv(programObject, mProgramState.textureEnvColorLoc, kTexUnitCount,
reinterpret_cast<float *>(uniformBuffers.texEnvColors.data()));
setUniform1fv(programObject, mProgramState.rgbScaleLoc, kTexUnitCount,
uniformBuffers.texEnvRgbScales.data());
setUniform1fv(programObject, mProgramState.alphaScaleLoc, kTexUnitCount,
uniformBuffers.texEnvAlphaScales.data());
} }
// Alpha test // Alpha test
...@@ -423,6 +506,7 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState) ...@@ -423,6 +506,7 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
fragmentStream << kGLES1DrawFShaderHeader; fragmentStream << kGLES1DrawFShaderHeader;
fragmentStream << kGLES1DrawFShaderUniformDefs; fragmentStream << kGLES1DrawFShaderUniformDefs;
fragmentStream << kGLES1DrawFShaderFunctions; fragmentStream << kGLES1DrawFShaderFunctions;
fragmentStream << kGLES1DrawFShaderMultitexturing;
fragmentStream << kGLES1DrawFShaderMain; fragmentStream << kGLES1DrawFShaderMain;
ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(), ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(),
...@@ -472,6 +556,26 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState) ...@@ -472,6 +556,26 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
mProgramState.enableTextureCubeMapLoc = mProgramState.enableTextureCubeMapLoc =
programObject->getUniformLocation("enable_texture_cube_map"); programObject->getUniformLocation("enable_texture_cube_map");
mProgramState.textureFormatLoc = programObject->getUniformLocation("texture_format");
mProgramState.textureEnvModeLoc = programObject->getUniformLocation("texture_env_mode");
mProgramState.combineRgbLoc = programObject->getUniformLocation("combine_rgb");
mProgramState.combineAlphaLoc = programObject->getUniformLocation("combine_alpha");
mProgramState.src0rgbLoc = programObject->getUniformLocation("src0_rgb");
mProgramState.src0alphaLoc = programObject->getUniformLocation("src0_alpha");
mProgramState.src1rgbLoc = programObject->getUniformLocation("src1_rgb");
mProgramState.src1alphaLoc = programObject->getUniformLocation("src1_alpha");
mProgramState.src2rgbLoc = programObject->getUniformLocation("src2_rgb");
mProgramState.src2alphaLoc = programObject->getUniformLocation("src2_alpha");
mProgramState.op0rgbLoc = programObject->getUniformLocation("op0_rgb");
mProgramState.op0alphaLoc = programObject->getUniformLocation("op0_alpha");
mProgramState.op1rgbLoc = programObject->getUniformLocation("op1_rgb");
mProgramState.op1alphaLoc = programObject->getUniformLocation("op1_alpha");
mProgramState.op2rgbLoc = programObject->getUniformLocation("op2_rgb");
mProgramState.op2alphaLoc = programObject->getUniformLocation("op2_alpha");
mProgramState.textureEnvColorLoc = programObject->getUniformLocation("texture_env_color");
mProgramState.rgbScaleLoc = programObject->getUniformLocation("texture_env_rgb_scale");
mProgramState.alphaScaleLoc = programObject->getUniformLocation("texture_env_alpha_scale");
mProgramState.enableAlphaTestLoc = programObject->getUniformLocation("enable_alpha_test"); mProgramState.enableAlphaTestLoc = programObject->getUniformLocation("enable_alpha_test");
mProgramState.alphaFuncLoc = programObject->getUniformLocation("alpha_func"); mProgramState.alphaFuncLoc = programObject->getUniformLocation("alpha_func");
mProgramState.alphaTestRefLoc = programObject->getUniformLocation("alpha_test_ref"); mProgramState.alphaTestRefLoc = programObject->getUniformLocation("alpha_test_ref");
......
...@@ -101,6 +101,27 @@ class GLES1Renderer final : angle::NonCopyable ...@@ -101,6 +101,27 @@ class GLES1Renderer final : angle::NonCopyable
std::array<GLint, kTexUnitCount> tex2DSamplerLocs; std::array<GLint, kTexUnitCount> tex2DSamplerLocs;
std::array<GLint, kTexUnitCount> texCubeSamplerLocs; std::array<GLint, kTexUnitCount> texCubeSamplerLocs;
GLint textureFormatLoc;
GLint textureEnvModeLoc;
GLint combineRgbLoc;
GLint combineAlphaLoc;
GLint src0rgbLoc;
GLint src0alphaLoc;
GLint src1rgbLoc;
GLint src1alphaLoc;
GLint src2rgbLoc;
GLint src2alphaLoc;
GLint op0rgbLoc;
GLint op0alphaLoc;
GLint op1rgbLoc;
GLint op1alphaLoc;
GLint op2rgbLoc;
GLint op2alphaLoc;
GLint textureEnvColorLoc;
GLint rgbScaleLoc;
GLint alphaScaleLoc;
// Alpha test // Alpha test
GLint enableAlphaTestLoc; GLint enableAlphaTestLoc;
GLint alphaFuncLoc; GLint alphaFuncLoc;
...@@ -154,6 +175,26 @@ class GLES1Renderer final : angle::NonCopyable ...@@ -154,6 +175,26 @@ class GLES1Renderer final : angle::NonCopyable
std::array<GLint, kTexUnitCount> tex2DEnables; std::array<GLint, kTexUnitCount> tex2DEnables;
std::array<GLint, kTexUnitCount> texCubeEnables; std::array<GLint, kTexUnitCount> texCubeEnables;
std::array<GLint, kTexUnitCount> texEnvModes;
std::array<GLint, kTexUnitCount> texCombineRgbs;
std::array<GLint, kTexUnitCount> texCombineAlphas;
std::array<GLint, kTexUnitCount> texCombineSrc0Rgbs;
std::array<GLint, kTexUnitCount> texCombineSrc0Alphas;
std::array<GLint, kTexUnitCount> texCombineSrc1Rgbs;
std::array<GLint, kTexUnitCount> texCombineSrc1Alphas;
std::array<GLint, kTexUnitCount> texCombineSrc2Rgbs;
std::array<GLint, kTexUnitCount> texCombineSrc2Alphas;
std::array<GLint, kTexUnitCount> texCombineOp0Rgbs;
std::array<GLint, kTexUnitCount> texCombineOp0Alphas;
std::array<GLint, kTexUnitCount> texCombineOp1Rgbs;
std::array<GLint, kTexUnitCount> texCombineOp1Alphas;
std::array<GLint, kTexUnitCount> texCombineOp2Rgbs;
std::array<GLint, kTexUnitCount> texCombineOp2Alphas;
std::array<Vec4Uniform, kTexUnitCount> texEnvColors;
std::array<GLfloat, kTexUnitCount> texEnvRgbScales;
std::array<GLfloat, kTexUnitCount> texEnvAlphaScales;
// Lighting // Lighting
std::array<GLint, kLightCount> lightEnables; std::array<GLint, kLightCount> lightEnables;
std::array<Vec4Uniform, kLightCount> lightAmbients; std::array<Vec4Uniform, kLightCount> lightAmbients;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
constexpr char kGLES1DrawVShader[] = R"(#version 300 es constexpr char kGLES1DrawVShader[] = R"(#version 300 es
precision highp float; precision highp float;
#define kMaxTexUnits 4 #define kMaxTexUnits 4
in vec4 pos; in vec4 pos;
in vec3 normal; in vec3 normal;
...@@ -40,34 +40,37 @@ out vec4 texcoord3_varying; ...@@ -40,34 +40,37 @@ out vec4 texcoord3_varying;
void main() void main()
{ {
pos_varying = modelview * pos; pos_varying = modelview * pos;
mat3 mvInvTr3 = mat3(modelview_invtr); mat3 mvInvTr3 = mat3(modelview_invtr);
normal_varying = mvInvTr3 * normal; normal_varying = mvInvTr3 * normal;
if (enable_rescale_normal) { if (enable_rescale_normal)
float rescale = 1.0; {
float rescale = 1.0;
vec3 rescaleVec = vec3(mvInvTr3[2]); vec3 rescaleVec = vec3(mvInvTr3[2]);
float len = length(rescaleVec); float len = length(rescaleVec);
if (len > 0.0) { if (len > 0.0)
{
rescale = 1.0 / len; rescale = 1.0 / len;
} }
normal_varying *= rescale; normal_varying *= rescale;
} }
if (enable_normalize) { if (enable_normalize)
{
normal_varying = normalize(normal_varying); normal_varying = normalize(normal_varying);
} }
color_varying = color; color_varying = color;
color_varying_flat = color; color_varying_flat = color;
pointsize_varying = pointsize; pointsize_varying = pointsize;
texcoord0_varying = texture_matrix[0] * texcoord0; texcoord0_varying = texture_matrix[0] * texcoord0;
texcoord1_varying = texture_matrix[1] * texcoord1; texcoord1_varying = texture_matrix[1] * texcoord1;
texcoord2_varying = texture_matrix[2] * texcoord2; texcoord2_varying = texture_matrix[2] * texcoord2;
texcoord3_varying = texture_matrix[3] * texcoord3; texcoord3_varying = texture_matrix[3] * texcoord3;
vec4 vertexPos = projection * modelview * pos; vec4 vertexPos = projection * modelview * pos;
gl_Position = vertexPos; gl_Position = vertexPos;
gl_PointSize = pointsize; gl_PointSize = pointsize;
} }
...@@ -165,6 +168,27 @@ uniform samplerCube tex_cube_sampler2; ...@@ -165,6 +168,27 @@ uniform samplerCube tex_cube_sampler2;
uniform sampler2D tex_sampler3; uniform sampler2D tex_sampler3;
uniform samplerCube tex_cube_sampler3; uniform samplerCube tex_cube_sampler3;
uniform int texture_format[kMaxTexUnits];
uniform int texture_env_mode[kMaxTexUnits];
uniform int combine_rgb[kMaxTexUnits];
uniform int combine_alpha[kMaxTexUnits];
uniform int src0_rgb[kMaxTexUnits];
uniform int src0_alpha[kMaxTexUnits];
uniform int src1_rgb[kMaxTexUnits];
uniform int src1_alpha[kMaxTexUnits];
uniform int src2_rgb[kMaxTexUnits];
uniform int src2_alpha[kMaxTexUnits];
uniform int op0_rgb[kMaxTexUnits];
uniform int op0_alpha[kMaxTexUnits];
uniform int op1_rgb[kMaxTexUnits];
uniform int op1_alpha[kMaxTexUnits];
uniform int op2_rgb[kMaxTexUnits];
uniform int op2_alpha[kMaxTexUnits];
uniform vec4 texture_env_color[kMaxTexUnits];
uniform float texture_env_rgb_scale[kMaxTexUnits];
uniform float texture_env_alpha_scale[kMaxTexUnits];
// Vertex attributes//////////////////////////////////////////////////////////// // Vertex attributes////////////////////////////////////////////////////////////
in vec4 pos_varying; in vec4 pos_varying;
...@@ -232,159 +256,113 @@ out vec4 frag_color; ...@@ -232,159 +256,113 @@ out vec4 frag_color;
constexpr char kGLES1DrawFShaderFunctions[] = R"( constexpr char kGLES1DrawFShaderFunctions[] = R"(
bool isTextureUnitEnabled(int unit) float posDot(vec3 a, vec3 b)
{ {
return enable_texture_2d[unit] || enable_texture_cube_map[unit];
}
vec4 getTextureColor(int unit)
{
vec4 res;
switch (unit)
{
case 0:
if (enable_texture_2d[0])
{
res = texture(tex_sampler0, texcoord0_varying.xy);
}
else if (enable_texture_cube_map[0])
{
res = texture(tex_cube_sampler0, texcoord0_varying.xyz);
}
break;
case 1:
if (enable_texture_2d[1])
{
res = texture(tex_sampler1, texcoord1_varying.xy);
}
else if (enable_texture_cube_map[1])
{
res = texture(tex_cube_sampler1, texcoord1_varying.xyz);
}
break;
case 2:
if (enable_texture_2d[2])
{
res = texture(tex_sampler2, texcoord2_varying.xy);
}
else if (enable_texture_cube_map[2])
{
res = texture(tex_cube_sampler2, texcoord2_varying.xyz);
}
break;
case 3:
if (enable_texture_2d[3])
{
res = texture(tex_sampler3, texcoord3_varying.xy);
}
else if (enable_texture_cube_map[3])
{
// TODO: Weird stuff happens
// res = texture(tex_cube_sampler3, texcoord3_varying.xyz);
}
break;
default:
break;
}
return res;
}
vec4 getColor(int unit, vec4 vertexColor)
{
if (!isTextureUnitEnabled(unit))
{
return vertexColor;
}
return getTextureColor(unit);
}
float posDot(vec3 a, vec3 b) {
return max(dot(a, b), 0.0); return max(dot(a, b), 0.0);
} }
vec4 doLighting(vec4 currentFragment) { vec4 doLighting(vec4 currentFragment)
{
vec4 materialAmbientActual = material_ambient; vec4 materialAmbientActual = material_ambient;
vec4 materialDiffuseActual = material_diffuse; vec4 materialDiffuseActual = material_diffuse;
if (enable_color_material || enable_texture_2d[0] || enable_texture_cube_map[0]) { if (enable_color_material || enable_texture_2d[0] || enable_texture_cube_map[0])
{
materialAmbientActual = currentFragment; materialAmbientActual = currentFragment;
materialDiffuseActual = currentFragment; materialDiffuseActual = currentFragment;
} }
vec4 lightingResult = material_emissive + vec4 lightingResult = material_emissive + materialAmbientActual * light_model_scene_ambient;
materialAmbientActual * light_model_scene_ambient;
for (int i = 0; i < kMaxLights; i++) { for (int i = 0; i < kMaxLights; i++)
{
if (!light_enables[i]) continue; if (!light_enables[i])
continue;
vec4 lightAmbient = light_ambients[i]; vec4 lightAmbient = light_ambients[i];
vec4 lightDiffuse = light_diffuses[i]; vec4 lightDiffuse = light_diffuses[i];
vec4 lightSpecular = light_speculars[i]; vec4 lightSpecular = light_speculars[i];
vec4 lightPos = light_positions[i]; vec4 lightPos = light_positions[i];
vec3 lightDir = light_directions[i]; vec3 lightDir = light_directions[i];
float attConst = light_attenuation_consts[i]; float attConst = light_attenuation_consts[i];
float attLinear = light_attenuation_linears[i]; float attLinear = light_attenuation_linears[i];
float attQuadratic = light_attenuation_quadratics[i]; float attQuadratic = light_attenuation_quadratics[i];
float spotAngle = light_spotlight_cutoff_angles[i]; float spotAngle = light_spotlight_cutoff_angles[i];
float spotExponent = light_spotlight_exponents[i]; float spotExponent = light_spotlight_exponents[i];
vec3 toLight; vec3 toLight;
if (lightPos.w == 0.0) { if (lightPos.w == 0.0)
{
toLight = lightPos.xyz; toLight = lightPos.xyz;
} else { }
else
{
toLight = (lightPos.xyz / lightPos.w - pos_varying.xyz); toLight = (lightPos.xyz / lightPos.w - pos_varying.xyz);
} }
float lightDist = length(toLight); float lightDist = length(toLight);
vec3 h = normalize(toLight) + vec3(0.0, 0.0, 1.0); vec3 h = normalize(toLight) + vec3(0.0, 0.0, 1.0);
float ndotL = posDot(normal_varying, normalize(toLight)); float ndotL = posDot(normal_varying, normalize(toLight));
float ndoth = posDot(normal_varying, normalize(h)); float ndoth = posDot(normal_varying, normalize(h));
float specAtt; float specAtt;
if (ndotL != 0.0) { if (ndotL != 0.0)
{
specAtt = 1.0; specAtt = 1.0;
} else { }
else
{
specAtt = 0.0; specAtt = 0.0;
} }
float att; float att;
if (lightPos.w != 0.0) { if (lightPos.w != 0.0)
float attDenom = (attConst + attLinear * lightDist + {
attQuadratic * lightDist * lightDist); float attDenom =
(attConst + attLinear * lightDist + attQuadratic * lightDist * lightDist);
att = 1.0 / attDenom; att = 1.0 / attDenom;
} else { }
else
{
att = 1.0; att = 1.0;
} }
float spot; float spot;
float spotAngleCos = cos(radians(spotAngle)); float spotAngleCos = cos(radians(spotAngle));
vec3 toSurfaceDir = -normalize(toLight); vec3 toSurfaceDir = -normalize(toLight);
float spotDot = posDot(toSurfaceDir, normalize(lightDir)); float spotDot = posDot(toSurfaceDir, normalize(lightDir));
if (spotAngle == 180.0 || lightPos.w == 0.0) { if (spotAngle == 180.0 || lightPos.w == 0.0)
{
spot = 1.0; spot = 1.0;
} else { }
if (spotDot < spotAngleCos) { else
{
if (spotDot < spotAngleCos)
{
spot = 0.0; spot = 0.0;
} else { }
else
{
spot = pow(spotDot, spotExponent); spot = pow(spotDot, spotExponent);
} }
} }
vec4 contrib = materialAmbientActual * lightAmbient; vec4 contrib = materialAmbientActual * lightAmbient;
contrib += ndotL * materialDiffuseActual * lightDiffuse; contrib += ndotL * materialDiffuseActual * lightDiffuse;
if (ndoth > 0.0 && material_specular_exponent > 0.0) { if (ndoth > 0.0 && material_specular_exponent > 0.0)
contrib += specAtt * pow(ndoth, material_specular_exponent) * {
material_specular * lightSpecular; contrib += specAtt * pow(ndoth, material_specular_exponent) * material_specular *
} else { lightSpecular;
if (ndoth > 0.0) { }
else
{
if (ndoth > 0.0)
{
contrib += specAtt * material_specular * lightSpecular; contrib += specAtt * material_specular * lightSpecular;
} }
} }
...@@ -398,7 +376,7 @@ vec4 doLighting(vec4 currentFragment) { ...@@ -398,7 +376,7 @@ vec4 doLighting(vec4 currentFragment) {
bool doAlphaTest(vec4 currentFragment) bool doAlphaTest(vec4 currentFragment)
{ {
bool shouldPassAlpha = false; bool shouldPassAlpha = false;
float incAlpha = currentFragment.a; float incAlpha = currentFragment.a;
switch (alpha_func) switch (alpha_func)
{ {
...@@ -432,24 +410,29 @@ bool doAlphaTest(vec4 currentFragment) ...@@ -432,24 +410,29 @@ bool doAlphaTest(vec4 currentFragment)
return shouldPassAlpha; return shouldPassAlpha;
} }
bool doClipPlaneTest() { bool doClipPlaneTest()
{
bool res = true; bool res = true;
for (int i = 0; i < kMaxClipPlanes; i++) { for (int i = 0; i < kMaxClipPlanes; i++)
if (clip_plane_enables[i]) { {
if (clip_plane_enables[i])
{
float dist = dot(clip_planes[i].xyz, pos_varying.xyz) + clip_planes[i].w; float dist = dot(clip_planes[i].xyz, pos_varying.xyz) + clip_planes[i].w;
res = res && (dist >= 0.0); res = res && (dist >= 0.0);
} }
} }
return res; return res;
} }
vec4 doFog(vec4 currentFragment) { vec4 doFog(vec4 currentFragment)
{
float eyeDist = -pos_varying.z / pos_varying.w; float eyeDist = -pos_varying.z / pos_varying.w;
float f = 1.0; float f = 1.0;
switch (fog_mode) { switch (fog_mode)
{
case kExp: case kExp:
f = exp(-fog_density * eyeDist); f = exp(-fog_density * eyeDist);
break; break;
...@@ -469,11 +452,448 @@ vec4 doFog(vec4 currentFragment) { ...@@ -469,11 +452,448 @@ vec4 doFog(vec4 currentFragment) {
)"; )";
constexpr char kGLES1DrawFShaderMultitexturing[] = R"(
bool isTextureUnitEnabled(int unit)
{
return enable_texture_2d[unit] || enable_texture_cube_map[unit];
}
vec4 getTextureColor(int unit)
{
vec4 res;
switch (unit)
{
case 0:
if (enable_texture_2d[0])
{
res = texture(tex_sampler0, texcoord0_varying.xy);
}
else if (enable_texture_cube_map[0])
{
res = texture(tex_cube_sampler0, texcoord0_varying.xyz);
}
break;
case 1:
if (enable_texture_2d[1])
{
res = texture(tex_sampler1, texcoord1_varying.xy);
}
else if (enable_texture_cube_map[1])
{
res = texture(tex_cube_sampler1, texcoord1_varying.xyz);
}
break;
case 2:
if (enable_texture_2d[2])
{
res = texture(tex_sampler2, texcoord2_varying.xy);
}
else if (enable_texture_cube_map[2])
{
res = texture(tex_cube_sampler2, texcoord2_varying.xyz);
}
break;
case 3:
if (enable_texture_2d[3])
{
res = texture(tex_sampler3, texcoord3_varying.xy);
}
else if (enable_texture_cube_map[3])
{
// TODO: Weird stuff happens
// res = texture(tex_cube_sampler3, texcoord3_varying.xyz);
}
break;
default:
break;
}
return res;
}
vec3 textureCombineSrcnOpnRgb(int srcnRgb,
int opnRgb,
vec4 textureEnvColor,
vec4 vertexColor,
vec4 texturePrevColor,
vec4 textureColor)
{
vec3 res;
vec4 op;
switch (srcnRgb)
{
case kTexture:
op = textureColor;
break;
case kConstant:
op = textureEnvColor;
break;
case kPrimaryColor:
op = vertexColor;
break;
case kPrevious:
op = texturePrevColor;
break;
default:
op = texturePrevColor;
break;
}
switch (opnRgb)
{
case kSrcColor:
res = op.rgb;
break;
case kOneMinusSrcColor:
res = 1.0 - op.rgb;
break;
case kSrcAlpha:
res = vec3(op.a, op.a, op.a);
break;
case kOneMinusSrcAlpha:
res = vec3(1.0 - op.a, 1.0 - op.a, 1.0 - op.a);
break;
default:
break;
}
return res;
}
float textureCombineSrcnOpnAlpha(int srcn,
int opn,
vec4 textureEnvColor,
vec4 vertexColor,
vec4 texturePrevColor,
vec4 textureColor)
{
float res;
vec4 op;
switch (srcn)
{
case kTexture:
op = textureColor;
break;
case kConstant:
op = textureEnvColor;
break;
case kPrimaryColor:
op = vertexColor;
break;
case kPrevious:
op = texturePrevColor;
break;
default:
op = texturePrevColor;
break;
}
switch (opn)
{
case kSrcAlpha:
res = op.a;
break;
case kOneMinusSrcAlpha:
res = 1.0 - op.a;
break;
default:
break;
}
return res;
}
vec4 textureCombine(int combineRgb,
int combineAlpha,
int src0Rgb,
int src0Alpha,
int src1Rgb,
int src1Alpha,
int src2Rgb,
int src2Alpha,
int op0Rgb,
int op0Alpha,
int op1Rgb,
int op1Alpha,
int op2Rgb,
int op2Alpha,
vec4 textureEnvColor,
float rgbScale,
float alphaScale,
vec4 vertexColor,
vec4 texturePrevColor,
vec4 textureColor)
{
vec3 resRgb;
float resAlpha;
vec3 arg0Rgb;
float arg0Alpha;
vec3 arg1Rgb;
float arg1Alpha;
vec3 arg2Rgb;
float arg2Alpha;
float dotVal;
arg0Rgb = textureCombineSrcnOpnRgb(src0Rgb, op0Rgb, textureEnvColor, vertexColor,
texturePrevColor, textureColor);
arg0Alpha = textureCombineSrcnOpnAlpha(src0Alpha, op0Alpha, textureEnvColor, vertexColor,
texturePrevColor, textureColor);
if (combineRgb != kReplace)
{
arg1Rgb = textureCombineSrcnOpnRgb(src1Rgb, op1Rgb, textureEnvColor, vertexColor,
texturePrevColor, textureColor);
}
if (combineAlpha != kReplace)
{
arg1Alpha = textureCombineSrcnOpnAlpha(src1Alpha, op1Alpha, textureEnvColor, vertexColor,
texturePrevColor, textureColor);
}
if (combineRgb == kInterpolate)
{
arg2Rgb = textureCombineSrcnOpnRgb(src2Rgb, op2Rgb, textureEnvColor, vertexColor,
texturePrevColor, textureColor);
}
if (combineAlpha == kInterpolate)
{
arg2Alpha = textureCombineSrcnOpnAlpha(src2Alpha, op2Alpha, textureEnvColor, vertexColor,
texturePrevColor, textureColor);
}
switch (combineRgb)
{
case kReplace:
resRgb = arg0Rgb;
break;
case kModulate:
resRgb = arg0Rgb * arg1Rgb;
break;
case kAdd:
resRgb = arg0Rgb + arg1Rgb;
break;
case kAddSigned:
resRgb = arg0Rgb + arg1Rgb - 0.5;
break;
case kInterpolate:
resRgb = arg0Rgb * arg2Rgb + arg1Rgb * (1.0 - arg2Rgb);
break;
case kSubtract:
resRgb = arg0Rgb - arg1Rgb;
break;
default:
break;
}
switch (combineAlpha)
{
case kReplace:
resAlpha = arg0Alpha;
break;
case kModulate:
resAlpha = arg0Alpha * arg1Alpha;
break;
case kAdd:
resAlpha = arg0Alpha + arg1Alpha;
break;
case kAddSigned:
resAlpha = arg0Alpha + arg1Alpha - 0.5;
break;
case kInterpolate:
resAlpha = arg0Alpha * arg2Alpha + arg1Alpha * (1.0 - arg2Alpha);
break;
case kSubtract:
resAlpha = arg0Alpha - arg1Alpha;
break;
default:
break;
}
if (combineRgb == kDot3Rgb || combineRgb == kDot3Rgba)
{
dotVal = 4.0 * dot(arg0Rgb - 0.5, arg1Rgb - 0.5);
if (combineRgb == kDot3Rgb)
{
return vec4(dotVal, dotVal, dotVal, resAlpha);
}
else
{
return vec4(dotVal, dotVal, dotVal, dotVal);
}
}
else
{
return vec4(resRgb, resAlpha);
}
}
vec4 textureFunction(int unit,
int texFormat,
int envMode,
int combineRgb,
int combineAlpha,
int src0Rgb,
int src0Alpha,
int src1Rgb,
int src1Alpha,
int src2Rgb,
int src2Alpha,
int op0Rgb,
int op0Alpha,
int op1Rgb,
int op1Alpha,
int op2Rgb,
int op2Alpha,
vec4 textureEnvColor,
float rgbScale,
float alphaScale,
vec4 vertexColor,
vec4 texturePrevColor,
vec4 textureColor)
{
if (!isTextureUnitEnabled(unit))
{
return texturePrevColor;
}
vec4 res;
switch (envMode)
{
case kReplace:
switch (texFormat)
{
case kAlpha:
res.rgb = texturePrevColor.rgb;
res.a = textureColor.a;
break;
case kRGBA:
case kLuminanceAlpha:
res.rgba = textureColor.rgba;
break;
case kRGB:
case kLuminance:
default:
res.rgb = textureColor.rgb;
res.a = texturePrevColor.a;
break;
}
break;
case kModulate:
switch (texFormat)
{
case kAlpha:
res.rgb = texturePrevColor.rgb;
res.a = texturePrevColor.a * textureColor.a;
break;
case kRGBA:
case kLuminanceAlpha:
res.rgba = texturePrevColor.rgba * textureColor.rgba;
break;
case kRGB:
case kLuminance:
default:
res.rgb = texturePrevColor.rgb * textureColor.rgb;
res.a = texturePrevColor.a;
break;
}
break;
case kDecal:
switch (texFormat)
{
case kRGB:
res.rgb = textureColor.rgb;
res.a = texturePrevColor.a;
break;
case kRGBA:
res.rgb = texturePrevColor.rgb * (1.0 - textureColor.a) +
textureColor.rgb * textureColor.a;
res.a = texturePrevColor.a;
break;
case kAlpha:
case kLuminance:
case kLuminanceAlpha:
default:
res.rgb = texturePrevColor.rgb * textureColor.rgb;
res.a = texturePrevColor.a;
break;
}
break;
case kBlend:
switch (texFormat)
{
case kAlpha:
res.rgb = texturePrevColor.rgb;
res.a = textureColor.a * texturePrevColor.a;
break;
case kLuminance:
case kRGB:
res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) +
textureEnvColor.rgb * textureColor.rgb;
res.a = texturePrevColor.a;
break;
case kLuminanceAlpha:
case kRGBA:
default:
res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) +
textureEnvColor.rgb * textureColor.rgb;
res.a = textureColor.a * texturePrevColor.a;
break;
}
break;
case kAdd:
switch (texFormat)
{
case kAlpha:
res.rgb = texturePrevColor.rgb;
res.a = textureColor.a * texturePrevColor.a;
break;
case kLuminance:
case kRGB:
res.rgb = texturePrevColor.rgb + textureColor.rgb;
res.a = texturePrevColor.a;
break;
case kLuminanceAlpha:
case kRGBA:
default:
res.rgb = texturePrevColor.rgb + textureColor.rgb;
res.a = textureColor.a * texturePrevColor.a;
break;
}
break;
case kCombine:
res = textureCombine(combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha,
src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb,
op2Alpha, textureEnvColor, rgbScale, alphaScale, vertexColor,
texturePrevColor, textureColor);
res.rgb *= rgbScale;
res.a *= alphaScale;
break;
default:
break;
}
return clamp(res, 0.0, 1.0);
}
)";
constexpr char kGLES1DrawFShaderMain[] = R"( constexpr char kGLES1DrawFShaderMain[] = R"(
void main() void main()
{ {
if (enable_clip_planes) { if (enable_clip_planes)
if (!doClipPlaneTest()) { {
if (!doClipPlaneTest())
{
discard; discard;
} }
} }
...@@ -490,14 +910,28 @@ void main() ...@@ -490,14 +910,28 @@ void main()
vertex_color = color_varying; vertex_color = color_varying;
} }
// Unit 0 only for now currentFragment = vertex_color;
currentFragment = getColor(0, vertex_color);
vec4 texturePrevColor = currentFragment;
if (enable_lighting) { for (int i = 0; i < kMaxTexUnits; i++)
{
currentFragment = textureFunction(
i, texture_format[i], texture_env_mode[i], combine_rgb[i], combine_alpha[i],
src0_rgb[i], src0_alpha[i], src1_rgb[i], src1_alpha[i], src2_rgb[i], src2_alpha[i],
op0_rgb[i], op0_alpha[i], op1_rgb[i], op1_alpha[i], op2_rgb[i], op2_alpha[i],
texture_env_color[i], texture_env_rgb_scale[i], texture_env_alpha_scale[i],
vertex_color, texturePrevColor, getTextureColor(i));
texturePrevColor = currentFragment;
}
if (enable_lighting)
{
currentFragment = doLighting(currentFragment); currentFragment = doLighting(currentFragment);
} }
if (enable_fog) { if (enable_fog)
{
currentFragment = doFog(currentFragment); currentFragment = doFog(currentFragment);
} }
......
...@@ -69,7 +69,9 @@ TEST_P(BasicDrawTest, EnableDisableTexture) ...@@ -69,7 +69,9 @@ TEST_P(BasicDrawTest, EnableDisableTexture)
// Texturing is disabled; still red; // Texturing is disabled; still red;
drawRedQuad(); drawRedQuad();
// Texturing enabled; is green. glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Texturing enabled; is green (provided modulate w/ white)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
......
...@@ -197,7 +197,6 @@ TEST_P(GLES1ConformanceTest, ColRamp) ...@@ -197,7 +197,6 @@ TEST_P(GLES1ConformanceTest, ColRamp)
TEST_P(GLES1ConformanceTest, CopyTex) TEST_P(GLES1ConformanceTest, CopyTex)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, CopyTexExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, CopyTexExec());
} }
...@@ -304,7 +303,6 @@ TEST_P(GLES1ConformanceTest, MatrixStack) ...@@ -304,7 +303,6 @@ TEST_P(GLES1ConformanceTest, MatrixStack)
TEST_P(GLES1ConformanceTest, MultiTex) TEST_P(GLES1ConformanceTest, MultiTex)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, MultiTexExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, MultiTexExec());
} }
...@@ -414,7 +412,6 @@ TEST_P(GLES1ConformanceTest, SpotExpDir) ...@@ -414,7 +412,6 @@ TEST_P(GLES1ConformanceTest, SpotExpDir)
TEST_P(GLES1ConformanceTest, TexDecal) TEST_P(GLES1ConformanceTest, TexDecal)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, TexDecalExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, TexDecalExec());
} }
...@@ -426,7 +423,6 @@ TEST_P(GLES1ConformanceTest, TexPalet) ...@@ -426,7 +423,6 @@ TEST_P(GLES1ConformanceTest, TexPalet)
TEST_P(GLES1ConformanceTest, TextureEdgeClamp) TEST_P(GLES1ConformanceTest, TextureEdgeClamp)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, TextureEdgeClampExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, TextureEdgeClampExec());
} }
...@@ -531,7 +527,6 @@ TEST_P(GLES1ConformanceTest, Gets) ...@@ -531,7 +527,6 @@ TEST_P(GLES1ConformanceTest, Gets)
TEST_P(GLES1ConformanceTest, TexCombine) TEST_P(GLES1ConformanceTest, TexCombine)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, TexCombineExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, TexCombineExec());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment