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:
parent
c786cb9572
commit
cd1b134ddc
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
140
src/OpenGL.cpp
140
src/OpenGL.cpp
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue
Block a user