3
0
Fork 0
forked from suyu/suyu

Merge pull request #2725 from wwylele/texture-sampler

gl_shader: refactor texture sampler into its own function
This commit is contained in:
Yuri Kunde Schlesner 2017-05-27 03:26:50 -07:00 committed by GitHub
commit 96528b3aab

View file

@ -144,12 +144,40 @@ static bool IsPassThroughTevStage(const TevStageConfig& stage) {
stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1);
}
static std::string TexCoord(const PicaShaderConfig& config, int texture_unit) {
if (texture_unit == 2 && config.state.texture2_use_coord1) {
return "texcoord[1]";
static std::string SampleTexture(const PicaShaderConfig& config, unsigned texture_unit) {
const auto& state = config.state;
switch (texture_unit) {
case 0:
// Only unit 0 respects the texturing type
switch (state.texture0_type) {
case TexturingRegs::TextureConfig::Texture2D:
return "texture(tex[0], texcoord[0])";
case TexturingRegs::TextureConfig::Projection2D:
return "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))";
default:
LOG_CRITICAL(HW_GPU, "Unhandled texture type %x",
static_cast<int>(state.texture0_type));
UNIMPLEMENTED();
return "texture(tex[0], texcoord[0])";
}
case 1:
return "texture(tex[1], texcoord[1])";
case 2:
if (state.texture2_use_coord1)
return "texture(tex[2], texcoord[1])";
else
return "texture(tex[2], texcoord[2])";
case 3:
if (state.proctex.enable) {
return "ProcTex()";
} else {
LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it");
return "vec4(0.0)";
}
default:
UNREACHABLE();
return "";
}
return "texcoord[" + std::to_string(texture_unit) + "]";
}
/// Writes the specified TEV stage source component(s)
@ -168,35 +196,16 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config,
out += "secondary_fragment_color";
break;
case Source::Texture0:
// Only unit 0 respects the texturing type (according to 3DBrew)
switch (state.texture0_type) {
case TexturingRegs::TextureConfig::Texture2D:
out += "texture(tex[0], texcoord[0])";
break;
case TexturingRegs::TextureConfig::Projection2D:
out += "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))";
break;
default:
out += "texture(tex[0], texcoord[0])";
LOG_CRITICAL(HW_GPU, "Unhandled texture type %x",
static_cast<int>(state.texture0_type));
UNIMPLEMENTED();
break;
}
out += SampleTexture(config, 0);
break;
case Source::Texture1:
out += "texture(tex[1], texcoord[1])";
out += SampleTexture(config, 1);
break;
case Source::Texture2:
out += "texture(tex[2], " + TexCoord(config, 2) + ")";
out += SampleTexture(config, 2);
break;
case Source::Texture3:
if (config.state.proctex.enable) {
out += "ProcTex()";
} else {
LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it");
out += "vec4(0.0)";
}
out += SampleTexture(config, 3);
break;
case Source::PreviousBuffer:
out += "combiner_buffer";
@ -506,18 +515,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
if (lighting.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
// Bump mapping is enabled using a normal map, read perturbation vector from the selected
// texture
if (lighting.bump_selector == 3) {
if (config.state.proctex.enable) {
out += "vec3 surface_normal = 2.0 * ProcTex().rgb - 1.0;\n";
} else {
LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it");
out += "vec3 surface_normal = vec3(-1.0);\n";
}
} else {
std::string bump_selector = std::to_string(lighting.bump_selector);
out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], " +
TexCoord(config, lighting.bump_selector) + ").rgb - 1.0;\n";
}
out += "vec3 surface_normal = 2.0 * (" + SampleTexture(config, lighting.bump_selector) +
").rgb - 1.0;\n";
// Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher
// precision result