1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Add legacy blending option:

Use old, fixed functionality based method for emulation of N64 blending modes.
This commit is contained in:
Sergey Lipskiy 2016-07-17 11:15:02 +06:00
parent c786cb9572
commit cd1b134ddc
11 changed files with 184 additions and 13 deletions

View File

@ -375,7 +375,7 @@ Storage format:
uint32 - number of shaders
shaders in binary form
*/
static const u32 ShaderStorageFormatVersion = 0x07U;
static const u32 ShaderStorageFormatVersion = 0x08U;
void CombinerInfo::_saveShadersStorage() const
{
if (m_shadersLoaded >= m_combiners.size())

View File

@ -36,6 +36,7 @@ void Config::resetToDefaults()
generalEmulation.enableShadersStorage = 1;
generalEmulation.correctTexrectCoords = tcDisable;
generalEmulation.enableNativeResTexrects = 0;
generalEmulation.enableLegacyBlending = 0;
generalEmulation.hacks = 0;
#ifdef ANDROID
generalEmulation.forcePolygonOffset = 0;

View File

@ -4,7 +4,7 @@
#include <string>
#include "Types.h"
#define CONFIG_VERSION_CURRENT 11U
#define CONFIG_VERSION_CURRENT 12U
#define BILINEAR_3POINT 0
#define BILINEAR_STANDARD 1
@ -49,6 +49,7 @@ struct Config
u32 enableShadersStorage;
u32 correctTexrectCoords;
u32 enableNativeResTexrects;
u32 enableLegacyBlending;
u32 hacks;
#ifdef ANDROID
u32 forcePolygonOffset;

View File

@ -149,12 +149,12 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
if (usesTexture()) {
strFragmentShader.assign(fragment_shader_header_common_variables);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
if (gDP.otherMode.cycleType == G_CYC_2CYCLE && config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_header_common_variables_blend_mux_2cycle);
strFragmentShader.append(fragment_shader_header_common_functions);
} else {
strFragmentShader.assign(fragment_shader_header_common_variables_notex);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
if (gDP.otherMode.cycleType == G_CYC_2CYCLE && config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_header_common_variables_blend_mux_2cycle);
strFragmentShader.append(fragment_shader_header_common_functions_notex);
}
@ -328,6 +328,9 @@ void ShaderCombiner::updateFogMode(bool _bForce)
void ShaderCombiner::updateBlendMode(bool _bForce)
{
if (config.generalEmulation.enableLegacyBlending != 0)
return;
if (gDP.otherMode.cycleType <= G_CYC_2CYCLE) {
m_uniforms.uBlendMux1.set(gDP.otherMode.c1_m1a,
gDP.otherMode.c1_m1b,
@ -356,6 +359,9 @@ void ShaderCombiner::updateBlendMode(bool _bForce)
void ShaderCombiner::disableBlending()
{
if (config.generalEmulation.enableLegacyBlending != 0)
return;
m_uniforms.uForceBlendCycle1.set(0, false);
m_uniforms.uForceBlendCycle2.set(0, false);
}

View File

@ -157,6 +157,7 @@ SHADER_VERSION
"uniform lowp float uK5; \n"
"uniform mediump vec2 uScreenScale; \n"
"uniform lowp int uAlphaCompareMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp ivec2 uFbMonochrome; \n"
"uniform lowp ivec2 uFbFixedAlpha;\n"
"uniform lowp int uEnableAlphaTest; \n"
@ -194,6 +195,7 @@ SHADER_VERSION
"uniform lowp float uK5; \n"
"uniform mediump vec2 uScreenScale; \n"
"uniform lowp int uAlphaCompareMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"

View File

@ -310,7 +310,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
if (usesTexture()) {
strFragmentShader.assign(fragment_shader_header_common_variables);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
if (gDP.otherMode.cycleType == G_CYC_2CYCLE && config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_header_common_variables_blend_mux_2cycle);
#ifdef GL_MULTISAMPLING_SUPPORT
@ -342,7 +342,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
} else {
strFragmentShader.assign(fragment_shader_header_common_variables_notex);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
if (gDP.otherMode.cycleType == G_CYC_2CYCLE && config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_header_common_variables_blend_mux_2cycle);
strFragmentShader.append(fragment_shader_header_noise);
strFragmentShader.append(fragment_shader_header_noise_dither);
@ -634,6 +634,9 @@ void ShaderCombiner::updateFogMode(bool _bForce)
void ShaderCombiner::updateBlendMode(bool _bForce)
{
if (config.generalEmulation.enableLegacyBlending != 0)
return;
if (gDP.otherMode.cycleType <= G_CYC_2CYCLE) {
m_uniforms.uBlendMux1.set(gDP.otherMode.c1_m1a,
gDP.otherMode.c1_m1b,
@ -662,6 +665,9 @@ void ShaderCombiner::updateBlendMode(bool _bForce)
void ShaderCombiner::disableBlending()
{
if (config.generalEmulation.enableLegacyBlending != 0)
return;
m_uniforms.uForceBlendCycle1.set(0, false);
m_uniforms.uForceBlendCycle2.set(0, false);
}
@ -849,6 +855,7 @@ void ShaderCombiner::getShaderCombinerOptionsSet(std::vector<u32> & _vecOptions)
_vecOptions.push_back(config.generalEmulation.enableNoise);
_vecOptions.push_back(config.generalEmulation.enableLOD);
_vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare);
_vecOptions.push_back(config.generalEmulation.enableLegacyBlending);
}
#ifdef GL_IMAGE_TEXTURES_SUPPORT

View File

@ -181,6 +181,7 @@ MAIN_SHADER_VERSION
"uniform lowp int uAlphaCompareMode;\n"
"uniform lowp int uAlphaDitherMode; \n"
"uniform lowp int uColorDitherMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp ivec2 uFbMonochrome; \n"
"uniform lowp ivec2 uFbFixedAlpha; \n"
"uniform lowp int uEnableAlphaTest; \n"
@ -242,6 +243,7 @@ MAIN_SHADER_VERSION
"uniform lowp int uAlphaCompareMode;\n"
"uniform lowp int uAlphaDitherMode; \n"
"uniform lowp int uColorDitherMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"

View File

@ -691,8 +691,148 @@ void OGLRender::addTriangle(int _v0, int _v1, int _v2)
#endif
}
void OGLRender::_legacySetBlendMode() const
{
const u32 blendmode = gDP.otherMode.l >> 16;
// 0x7000 = CVG_X_ALPHA|ALPHA_CVG_SEL|FORCE_BL
if (gDP.otherMode.alphaCvgSel != 0 && (gDP.otherMode.l & 0x7000) != 0x7000) {
switch (blendmode) {
case 0x4055: // Mario Golf
case 0x5055: // Paper Mario intro clr_mem * a_in + clr_mem * a_mem
glEnable(GL_BLEND);
glBlendFunc(GL_ZERO, GL_ONE);
break;
default:
glDisable(GL_BLEND);
}
return;
}
if (gDP.otherMode.forceBlender != 0 && gDP.otherMode.cycleType < G_CYC_COPY) {
glEnable(GL_BLEND);
switch (blendmode)
{
// Mace objects
case 0x0382:
// Mace special blend mode, see GLSLCombiner.cpp
case 0x0091:
// 1080 Sky
case 0x0C08:
// Used LOTS of places
case 0x0F0A:
//DK64 blue prints
case 0x0302:
// Bomberman 2 special blend mode, see GLSLCombiner.cpp
case 0xA500:
//Sin and Punishment
case 0xCB02:
// Battlezone
// clr_in * a + clr_in * (1-a)
case 0xC800:
// Conker BFD
// clr_in * a_fog + clr_fog * (1-a)
// clr_in * 0 + clr_in * 1
case 0x07C2:
case 0x00C0:
//ISS64
case 0xC302:
// Donald Duck
case 0xC702:
glBlendFunc(GL_ONE, GL_ZERO);
break;
case 0x55f0:
// Bust-A-Move 3 DX
// CLR_MEM * A_FOG + CLR_FOG * 1MA
glBlendFunc(GL_ONE, GL_SRC_ALPHA);
break;
case 0x0F1A:
if (gDP.otherMode.cycleType == G_CYC_1CYCLE)
glBlendFunc(GL_ONE, GL_ZERO);
else
glBlendFunc(GL_ZERO, GL_ONE);
break;
//Space Invaders
case 0x0448: // Add
case 0x055A:
glBlendFunc(GL_ONE, GL_ONE);
break;
case 0xc712: // Pokemon Stadium?
case 0xAF50: // LOT in Zelda: MM
case 0x0F5A: // LOT in Zelda: MM
case 0x0FA5: // Seems to be doing just blend color - maybe combiner can be used for this?
case 0x5055: // Used in Paper Mario intro, I'm not sure if this is right...
//clr_in * 0 + clr_mem * 1
glBlendFunc(GL_ZERO, GL_ONE);
break;
case 0x5F50: //clr_mem * 0 + clr_mem * (1-a)
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
break;
case 0xF550: //clr_fog * a_fog + clr_mem * (1-a)
case 0x0150: // spiderman
case 0x0550: // bomberman 64
case 0x0D18: //clr_in * a_fog + clr_mem * (1-a)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case 0xC912: //40 winks, clr_in * a_fog + clr_mem * 1
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
break;
case 0x0040: // Fzero
case 0xC810: // Blends fog
case 0x0C18: // Standard interpolated blend
case 0x0050: // Standard interpolated blend
case 0x0051: // Standard interpolated blend
case 0x0055: // Used for antialiasing
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case 0x0C19: // Used for antialiasing
case 0xC811: // Blends fog
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
break;
case 0x5000: // V8 explosions
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
break;
case 0xFA00: // Bomberman second attack
glBlendFunc(GL_ONE, GL_ZERO);
break;
default:
//LOG(LOG_VERBOSE, "Unhandled blend mode=%x", gDP.otherMode.l >> 16);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
}
}
else if ((config.generalEmulation.hacks & hack_pilotWings) != 0 && (gDP.otherMode.l & 0x80) != 0) { //CLR_ON_CVG without FORCE_BL
glEnable(GL_BLEND);
glBlendFunc(GL_ZERO, GL_ONE);
}
else if ((config.generalEmulation.hacks & hack_blastCorps) != 0 && gDP.otherMode.cycleType < G_CYC_COPY && gSP.texture.on == 0 && currentCombiner()->usesTexture()) { // Blast Corps
glEnable(GL_BLEND);
glBlendFunc(GL_ZERO, GL_ONE);
}
else {
glDisable(GL_BLEND);
}
}
void OGLRender::_setBlendMode() const
{
if (config.generalEmulation.enableLegacyBlending != 0) {
_legacySetBlendMode();
return;
}
if (gDP.otherMode.forceBlender != 0 && gDP.otherMode.cycleType < G_CYC_COPY) {
GLenum srcFactor = GL_ONE;
GLenum dstFactor = GL_ZERO;

View File

@ -187,6 +187,7 @@ private:
void _setColorArray() const;
void _setTexCoordArrays() const;
void _setBlendMode() const;
void _legacySetBlendMode() const;
void _updateCullFace() const;
void _updateViewport() const;
void _updateScreenCoordsViewport() const;

View File

@ -316,14 +316,22 @@ int compileCombiner(Combiner & _color, Combiner & _alpha, std::string & _strShad
}
#endif
if (gDP.otherMode.cycleType <= G_CYC_2CYCLE)
_strShader.append(fragment_shader_blender1);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
_strShader.append(fragment_shader_blender2);
if (config.generalEmulation.enableLegacyBlending == 0) {
if (gDP.otherMode.cycleType <= G_CYC_2CYCLE)
_strShader.append(fragment_shader_blender1);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
_strShader.append(fragment_shader_blender2);
_strShader.append(
" fragColor = vec4(color2, alpha2); \n"
);
_strShader.append(
" fragColor = vec4(color2, alpha2); \n"
);
} else {
_strShader.append(
" fragColor = vec4(color2, alpha2); \n"
" if (uFogUsage == 1) \n"
" fragColor.rgb = mix(fragColor.rgb, uFogColor.rgb, vShadeColor.a); \n"
);
}
return nInputs;
}

View File

@ -74,6 +74,8 @@ bool Config_SetDefault()
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "enableNativeResTexrects", config.generalEmulation.enableNativeResTexrects, "Render 2D texrects in native resolution to fix misalignment between parts of 2D image.");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "enableLegacyBlending", config.generalEmulation.enableLegacyBlending, "Do not use shaders to emulate N64 blending modes. Works faster on slow GPU. Can cause glitches.");
assert(res == M64ERR_SUCCESS);
#ifdef ANDROID
res = ConfigSetDefaultBool(g_configVideoGliden64, "ForcePolygonOffset", config.generalEmulation.forcePolygonOffset, "If true, use polygon offset values specified below");
assert(res == M64ERR_SUCCESS);
@ -205,6 +207,7 @@ void Config_LoadConfig()
config.generalEmulation.enableShadersStorage = ConfigGetParamBool(g_configVideoGliden64, "EnableShadersStorage");
config.generalEmulation.correctTexrectCoords = ConfigGetParamInt(g_configVideoGliden64, "CorrectTexrectCoords");
config.generalEmulation.enableNativeResTexrects = ConfigGetParamBool(g_configVideoGliden64, "enableNativeResTexrects");
config.generalEmulation.enableLegacyBlending = ConfigGetParamBool(g_configVideoGliden64, "enableLegacyBlending");
#ifdef ANDROID
config.generalEmulation.forcePolygonOffset = ConfigGetParamBool(g_configVideoGliden64, "ForcePolygonOffset");
config.generalEmulation.polygonOffsetFactor = ConfigGetParamFloat(g_configVideoGliden64, "PolygonOffsetFactor");