mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-02 09:03:37 +00:00
Implement YUV-to-RGB color space conversion. See 12.5 of programming manual
Up shader storage version. Fixed Killer Instinct Gold: Improper Projectile Effects. #1513
This commit is contained in:
parent
77ffe6106e
commit
adc2b547e8
|
@ -926,63 +926,96 @@ public:
|
|||
ShaderFragmentHeaderReadTex (const opengl::GLInfo & _glinfo)
|
||||
{
|
||||
if (!_glinfo.isGLES2) {
|
||||
m_part =
|
||||
"uniform lowp ivec2 uTextureFormat; \n"
|
||||
"uniform lowp ivec2 uBiLerp; \n"
|
||||
"uniform lowp ivec2 uTextureConvert; \n"
|
||||
"uniform mediump ivec4 uConvertParams; \n"
|
||||
"uniform lowp int uTextureFilterMode; \n"
|
||||
"#define YUVCONVERT_TEX(name, tex, texCoord, convert, format, prev) \\\n"
|
||||
" { \\\n"
|
||||
" if (convert != 0) name = prev; \\\n"
|
||||
" else name = texture(tex, texCoord); \\\n"
|
||||
" mediump ivec4 icolor = ivec4(name*255.0); \\\n"
|
||||
" if (format == 1) \\\n"
|
||||
" icolor.rg -= 128; \\\n"
|
||||
" mediump ivec4 iconvert; \\\n"
|
||||
" iconvert.r = icolor.b + (uConvertParams[0]*icolor.g + 128)/256; \\\n"
|
||||
" iconvert.g = icolor.b + (uConvertParams[1]*icolor.r + uConvertParams[2]*icolor.g + 128)/256; \\\n"
|
||||
" iconvert.b = icolor.b + (uConvertParams[3]*icolor.r + 128)/256; \\\n"
|
||||
" iconvert.a = icolor.b; \\\n"
|
||||
" name = vec4(iconvert)/255.0; \\\n"
|
||||
" } \n"
|
||||
;
|
||||
if (config.texture.bilinearMode == BILINEAR_3POINT) {
|
||||
m_part =
|
||||
"uniform lowp int uTextureFilterMode; \n"
|
||||
// 3 point texture filtering.
|
||||
// Original author: ArthurCarvalho
|
||||
// GLSL implementation: twinaphex, mupen64plus-libretro project.
|
||||
"#define TEX_OFFSET(tex, texCoord, off) texture(tex, texCoord - (off)/texSize) \n"
|
||||
"#define FILTER_3POINT(tex, texCoord) \\\n"
|
||||
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
|
||||
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
|
||||
" offset -= step(1.0, offset.x + offset.y); \\\n"
|
||||
" lowp vec4 c0 = TEX_OFFSET(tex, texCoord, offset); \\\n"
|
||||
// 3 point texture filtering.
|
||||
// Original author: ArthurCarvalho
|
||||
// GLSL implementation: twinaphex, mupen64plus-libretro project.
|
||||
m_part +=
|
||||
"#define TEX_OFFSET(tex, texCoord, off) texture(tex, texCoord - (off)/texSize) \n"
|
||||
"#define TEX_FILTER(name, tex, texCoord) \\\n"
|
||||
" { \\\n"
|
||||
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
|
||||
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
|
||||
" offset -= step(1.0, offset.x + offset.y); \\\n"
|
||||
" lowp vec4 c0 = TEX_OFFSET(tex, texCoord, offset); \\\n"
|
||||
" lowp vec4 c1 = TEX_OFFSET(tex, texCoord, vec2(offset.x - sign(offset.x), offset.y)); \\\n"
|
||||
" lowp vec4 c2 = TEX_OFFSET(tex, texCoord, vec2(offset.x, offset.y - sign(offset.y))); \\\n"
|
||||
" lowp vec4 tex3Point = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n"
|
||||
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
|
||||
" { \\\n"
|
||||
" if (fbMonochrome == 3) { \\\n"
|
||||
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \\\n"
|
||||
" name = texelFetch(tex, coord, 0); \\\n"
|
||||
" } else { \\\n"
|
||||
" lowp vec4 texStandard = texture(tex, texCoord); \\\n"
|
||||
" FILTER_3POINT(tex, texCoord); \\\n"
|
||||
" name = uTextureFilterMode == 0 ? texStandard : tex3Point; \\\n"
|
||||
" } \\\n"
|
||||
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
|
||||
" else if (fbMonochrome == 2) \\\n"
|
||||
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
|
||||
" else if (fbMonochrome == 3) { \\\n"
|
||||
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
|
||||
" name.a = 0.0; \\\n"
|
||||
" } \\\n"
|
||||
" if (fbFixedAlpha == 1) name.a = 0.825; \\\n"
|
||||
" } \n"
|
||||
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
|
||||
" } \n"
|
||||
;
|
||||
} else {
|
||||
m_part =
|
||||
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
|
||||
" { \\\n"
|
||||
" if (fbMonochrome == 3) { \\\n"
|
||||
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \\\n"
|
||||
" name = texelFetch(tex, coord, 0); \\\n"
|
||||
" } else name = texture(tex, texCoord); \\\n"
|
||||
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
|
||||
" else if (fbMonochrome == 2) \\\n"
|
||||
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
|
||||
" else if (fbMonochrome == 3) { \\\n"
|
||||
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
|
||||
" name.a = 0.0; \\\n"
|
||||
" } \\\n"
|
||||
" if (fbFixedAlpha == 1) name.a = 0.825; \\\n"
|
||||
" } \n"
|
||||
m_part +=
|
||||
"#define TEX_OFFSET(off, tex, texCoord) texture(tex, texCoord - (off)/texSize) \n"
|
||||
"#define TEX_FILTER(name, tex, texCoord) \\\n"
|
||||
"{ \\\n"
|
||||
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
|
||||
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
|
||||
" offset -= step(1.0, offset.x + offset.y); \\\n"
|
||||
" lowp vec4 zero = vec4(0.0); \\\n"
|
||||
" \\\n"
|
||||
" lowp vec4 p0q0 = TEX_OFFSET(offset, tex, texCoord); \\\n"
|
||||
" lowp vec4 p1q0 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord); \\\n"
|
||||
" \\\n"
|
||||
" lowp vec4 p0q1 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord); \\\n"
|
||||
" lowp vec4 p1q1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord); \\\n"
|
||||
" \\\n"
|
||||
" mediump vec2 interpolationFactor = abs(offset); \\\n"
|
||||
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n" // Interpolates top row in X direction.
|
||||
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n" // Interpolates bottom row in X direction.
|
||||
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n" // Interpolate in Y direction.
|
||||
"} \n"
|
||||
;
|
||||
}
|
||||
m_part +=
|
||||
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
|
||||
" { \\\n"
|
||||
" if (fbMonochrome == 3) { \\\n"
|
||||
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \\\n"
|
||||
" name = texelFetch(tex, coord, 0); \\\n"
|
||||
" } else { \\\n"
|
||||
" if (uTextureFilterMode == 0) name = texture(tex, texCoord); \\\n"
|
||||
" else TEX_FILTER(name, tex, texCoord); \\\n"
|
||||
" } \\\n"
|
||||
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
|
||||
" else if (fbMonochrome == 2) \\\n"
|
||||
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
|
||||
" else if (fbMonochrome == 3) { \\\n"
|
||||
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
|
||||
" name.a = 0.0; \\\n"
|
||||
" } \\\n"
|
||||
" if (fbFixedAlpha == 1) name.a = 0.825; \\\n"
|
||||
" } \n"
|
||||
;
|
||||
} else {
|
||||
m_part =
|
||||
"uniform lowp ivec2 uTextureFormat; \n"
|
||||
"uniform lowp ivec2 uBiLerp; \n"
|
||||
"uniform lowp ivec2 uTextureConvert; \n"
|
||||
"uniform mediump ivec4 uConvertParams; \n"
|
||||
"uniform lowp int uTextureFilterMode; \n"
|
||||
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha); \n"
|
||||
"lowp vec4 YUV_Convert(in sampler2D tex, in mediump vec2 texCoord, in lowp int convert, in lowp int format, in lowp vec4 prev); \n"
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -1068,19 +1101,30 @@ public:
|
|||
if (_glinfo.isGLES2) {
|
||||
m_part =
|
||||
" nCurrentTile = 0; \n"
|
||||
" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
|
||||
" lowp vec4 readtex0; \n"
|
||||
" if (uBiLerp[0] != 0) \n"
|
||||
" readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
|
||||
" else \n"
|
||||
" readtex0 = YUV_Convert(uTex0, vTexCoord0, uTextureConvert[0], uTextureFormat[0], readtex0); \n"
|
||||
;
|
||||
} else {
|
||||
if (config.video.multisampling > 0) {
|
||||
m_part =
|
||||
" lowp vec4 readtex0; \n"
|
||||
" if (uMSTexEnabled[0] == 0) READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
|
||||
" else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
|
||||
" lowp vec4 readtex0; \n"
|
||||
" if (uMSTexEnabled[0] == 0) { \n"
|
||||
" if (uBiLerp[0] != 0) \n"
|
||||
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
|
||||
" else \n"
|
||||
" YUVCONVERT_TEX(readtex0, uTex0, vTexCoord0, uTextureConvert[0], uTextureFormat[0], readtex0) \n"
|
||||
" } else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]);\n"
|
||||
;
|
||||
} else {
|
||||
m_part =
|
||||
" lowp vec4 readtex0; \n"
|
||||
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
|
||||
" lowp vec4 readtex0; \n"
|
||||
" if (uBiLerp[0] != 0) \n"
|
||||
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
|
||||
" else \n"
|
||||
" YUVCONVERT_TEX(readtex0, uTex0, vTexCoord0, uTextureConvert[0], uTextureFormat[0], readtex0)\n"
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -1095,19 +1139,30 @@ public:
|
|||
if (_glinfo.isGLES2) {
|
||||
m_part =
|
||||
" nCurrentTile = 1; \n"
|
||||
" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
|
||||
" lowp vec4 readtex1; \n"
|
||||
" if (uBiLerp[1] != 0) \n"
|
||||
" readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
|
||||
" else \n"
|
||||
" readtex1 = YUV_Convert(uTex1, vTexCoord1, uTextureConvert[1], uTextureFormat[1], readtex0); \n"
|
||||
;
|
||||
} else {
|
||||
if (config.video.multisampling > 0) {
|
||||
m_part =
|
||||
" lowp vec4 readtex1; \n"
|
||||
" if (uMSTexEnabled[1] == 0) READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
|
||||
" else readtex1 = readTexMS(uMSTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
|
||||
" if (uMSTexEnabled[1] == 0) { \n"
|
||||
" if (uBiLerp[1] != 0) \n"
|
||||
" READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
|
||||
" else \n"
|
||||
" YUVCONVERT_TEX(readtex1, uTex1, vTexCoord1, uTextureConvert[1], uTextureFormat[1], readtex0) \n"
|
||||
" } else readtex1 = readTexMS(uMSTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]);\n"
|
||||
;
|
||||
} else {
|
||||
m_part =
|
||||
" lowp vec4 readtex1; \n"
|
||||
" READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
|
||||
" if (uBiLerp[1] != 0) \n"
|
||||
" READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
|
||||
" else \n"
|
||||
" YUVCONVERT_TEX(readtex1, uTex1, vTexCoord1, uTextureConvert[1], uTextureFormat[1], readtex0)\n"
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -1465,15 +1520,31 @@ public:
|
|||
ShaderReadtex(const opengl::GLInfo & _glinfo)
|
||||
{
|
||||
if (_glinfo.isGLES2) {
|
||||
m_part =
|
||||
"lowp vec4 YUV_Convert(in sampler2D tex, in mediump vec2 texCoord, in lowp int convert, in lowp int format, in lowp vec4 prev) \n"
|
||||
"{ \n"
|
||||
" lowp vec4 texColor; \n"
|
||||
" if (convert != 0) texColor = prev; \n"
|
||||
" else texColor = texture2D(tex, texCoord); \n"
|
||||
" mediump ivec4 icolor = ivec4(texColor*255.0); \n"
|
||||
" if (format == 1) \n"
|
||||
" icolor.rg -= 128; \n"
|
||||
" mediump ivec4 iconvert; \n"
|
||||
" iconvert.r = icolor.b + (uConvertParams[0]*icolor.g + 128)/256; \n"
|
||||
" iconvert.g = icolor.b + (uConvertParams[1]*icolor.r + uConvertParams[2]*icolor.g + 128)/256; \n"
|
||||
" iconvert.b = icolor.b + (uConvertParams[3]*icolor.r + 128)/256; \n"
|
||||
" iconvert.a = icolor.b; \n"
|
||||
" return vec4(iconvert)/255.0; \n"
|
||||
" } \n"
|
||||
;
|
||||
if (config.texture.bilinearMode == BILINEAR_3POINT) {
|
||||
m_part =
|
||||
m_part +=
|
||||
"uniform mediump vec2 uTextureSize[2]; \n"
|
||||
"uniform lowp int uTextureFilterMode; \n"
|
||||
// 3 point texture filtering.
|
||||
// Original author: ArthurCarvalho
|
||||
// GLSL implementation: twinaphex, mupen64plus-libretro project.
|
||||
"#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n"
|
||||
"lowp vec4 filter3point(in sampler2D tex, in mediump vec2 texCoord) \n"
|
||||
"lowp vec4 TextureFilter(in sampler2D tex, in mediump vec2 texCoord) \n"
|
||||
"{ \n"
|
||||
" mediump vec2 texSize; \n"
|
||||
" if (nCurrentTile == 0) \n"
|
||||
|
@ -1487,23 +1558,42 @@ public:
|
|||
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n"
|
||||
" return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n"
|
||||
"} \n"
|
||||
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
|
||||
"{ \n"
|
||||
" lowp vec4 texStandard = texture2D(tex, texCoord); \n"
|
||||
" lowp vec4 tex3Point = filter3point(tex, texCoord); \n"
|
||||
" lowp vec4 texColor = uTextureFilterMode == 0 ? texStandard : tex3Point; \n"
|
||||
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
|
||||
" else if (fbMonochrome == 2) \n"
|
||||
" texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n"
|
||||
" if (fbFixedAlpha == 1) texColor.a = 0.825; \n"
|
||||
" return texColor; \n"
|
||||
"} \n"
|
||||
;
|
||||
;
|
||||
} else {
|
||||
m_part =
|
||||
m_part +=
|
||||
// bilinear filtering.
|
||||
"uniform mediump vec2 uTextureSize[2]; \n"
|
||||
"#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n"
|
||||
"lowp vec4 TextureFilter(in sampler2D tex, in mediump vec2 texCoord) \n"
|
||||
"{ \n"
|
||||
" mediump vec2 texSize; \n"
|
||||
" if (nCurrentTile == 0) \n"
|
||||
" texSize = uTextureSize[0]; \n"
|
||||
" else \n"
|
||||
" texSize = uTextureSize[1]; \n"
|
||||
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n"
|
||||
" offset -= step(1.0, offset.x + offset.y); \n"
|
||||
" lowp vec4 zero = vec4(0.0); \n"
|
||||
" \n"
|
||||
" lowp vec4 p0q0 = TEX_OFFSET(offset, tex, texCoord); \n"
|
||||
" lowp vec4 p1q0 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord);\n"
|
||||
" \n"
|
||||
" lowp vec4 p0q1 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord);\n"
|
||||
" lowp vec4 p1q1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord);\n"
|
||||
" \n"
|
||||
" mediump vec2 interpolationFactor = abs(offset); \n"
|
||||
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \n" // Interpolates top row in X direction.
|
||||
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \n" // Interpolates bottom row in X direction.
|
||||
" return mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \n" // Interpolate in Y direction.
|
||||
"} \n"
|
||||
;
|
||||
}
|
||||
m_part +=
|
||||
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
|
||||
"{ \n"
|
||||
" lowp vec4 texColor = texture2D(tex, texCoord); \n"
|
||||
" lowp vec4 texColor; \n"
|
||||
" if (uTextureFilterMode == 0) texColor = texture2D(tex, texCoord); \n"
|
||||
" else texColor = TextureFilter(tex, texCoord); \n"
|
||||
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
|
||||
" else if (fbMonochrome == 2) \n"
|
||||
" texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n"
|
||||
|
@ -1511,7 +1601,6 @@ public:
|
|||
" return texColor; \n"
|
||||
"} \n"
|
||||
;
|
||||
}
|
||||
} else {
|
||||
if (config.video.multisampling > 0) {
|
||||
m_part =
|
||||
|
|
|
@ -444,20 +444,36 @@ private:
|
|||
iUniform uTexturePersp;
|
||||
};
|
||||
|
||||
class UTextureFilterMode : public UniformGroup
|
||||
class UTextureFetchMode : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureFilterMode(GLuint _program) {
|
||||
UTextureFetchMode(GLuint _program) {
|
||||
LocateUniform(uTextureFilterMode);
|
||||
LocateUniform(uTextureFormat);
|
||||
LocateUniform(uBiLerp);
|
||||
LocateUniform(uTextureConvert);
|
||||
LocateUniform(uConvertParams);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uTextureFilterMode.set(gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP), _force);
|
||||
int textureFilter = gDP.otherMode.textureFilter;
|
||||
if ((gSP.objRendermode&G_OBJRM_BILERP) != 0)
|
||||
textureFilter |= 2;
|
||||
uTextureFilterMode.set(textureFilter, _force);
|
||||
uBiLerp.set(gDP.otherMode.bi_lerp0, gDP.otherMode.bi_lerp1, _force);
|
||||
uTextureFormat.set(gSP.textureTile[0]->format, gSP.textureTile[1]->format, _force);
|
||||
uTextureConvert.set(0, gDP.otherMode.convert_one, _force);
|
||||
if (gDP.otherMode.bi_lerp0 == 0 || gDP.otherMode.bi_lerp1 == 0)
|
||||
uConvertParams.set(gDP.convert.k0, gDP.convert.k1, gDP.convert.k2, gDP.convert.k3, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uTextureFilterMode;
|
||||
iv2Uniform uTextureFormat;
|
||||
iv2Uniform uBiLerp;
|
||||
iv2Uniform uTextureConvert;
|
||||
i4Uniform uConvertParams;
|
||||
};
|
||||
|
||||
class UAlphaTestInfo : public UniformGroup
|
||||
|
@ -815,8 +831,8 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
|
|||
_uniforms.emplace_back(new UMipmap1(_program));
|
||||
if (config.generalEmulation.enableLOD != 0)
|
||||
_uniforms.emplace_back(new UMipmap2(_program));
|
||||
} else if (config.texture.bilinearMode == BILINEAR_3POINT) {
|
||||
_uniforms.emplace_back(new UTextureFilterMode(_program));
|
||||
} else {
|
||||
_uniforms.emplace_back(new UTextureFetchMode(_program));
|
||||
}
|
||||
|
||||
_uniforms.emplace_back(new UTexturePersp(_program));
|
||||
|
@ -826,7 +842,6 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
|
|||
|
||||
if (!_key.isRectKey())
|
||||
_uniforms.emplace_back(new UTextureParams(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
|
||||
|
||||
}
|
||||
|
||||
_uniforms.emplace_back(new UFog(_program));
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace glsl {
|
|||
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
|
||||
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
|
||||
|
||||
const u32 m_formatVersion = 0x14U;
|
||||
const u32 m_formatVersion = 0x15U;
|
||||
const u32 m_keysFormatVersion = 0x02;
|
||||
const opengl::GLInfo & m_glinfo;
|
||||
opengl::CachedUseProgram * m_useProgram;
|
||||
|
|
|
@ -209,6 +209,7 @@ void RSP_SetDefaultState()
|
|||
gSP.matrix.modelView[0][3][3] = 1.0f;
|
||||
|
||||
gDP.otherMode._u64 = 0U;
|
||||
gDP.otherMode.bi_lerp0 = gDP.otherMode.bi_lerp1 = 1;
|
||||
}
|
||||
|
||||
u32 DepthClearColor = 0xfffcfffc;
|
||||
|
|
|
@ -215,6 +215,7 @@ inline u32 GetRGBA8888_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
|
|||
return RGBA8888_RGBA4444(((u32*)src)[x^i]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
|
||||
{
|
||||
s32 r = (s32)(y + (1.370705f * (v - 128)));
|
||||
|
@ -230,11 +231,12 @@ u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
|
|||
|
||||
return (0xff << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
u16 YUV_RGBA4444(u8 y, u8 u, u8 v)
|
||||
#else
|
||||
inline u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
|
||||
{
|
||||
return RGBA8888_RGBA4444(YUV_RGBA8888(y, u, v));
|
||||
return (0xff << 24) | (y << 16) | (v << 8) | u;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x)
|
||||
{
|
||||
|
@ -249,19 +251,6 @@ inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x)
|
|||
*(dst++) = c;
|
||||
}
|
||||
|
||||
inline void GetYUV_RGBA4444(u64 * src, u16 * dst, u16 x)
|
||||
{
|
||||
const u32 t = (((u32*)src)[x]);
|
||||
u8 y1 = (u8)t & 0xFF;
|
||||
u8 v = (u8)(t >> 8) & 0xFF;
|
||||
u8 y0 = (u8)(t >> 16) & 0xFF;
|
||||
u8 u = (u8)(t >> 24) & 0xFF;
|
||||
u16 c = YUV_RGBA4444(y0, u, v);
|
||||
*(dst++) = c;
|
||||
c = YUV_RGBA4444(y1, u, v);
|
||||
*(dst++) = c;
|
||||
}
|
||||
|
||||
struct TextureLoadParameters
|
||||
{
|
||||
GetTexelFunc Get16;
|
||||
|
@ -307,7 +296,7 @@ ImageFormat::ImageFormat()
|
|||
},
|
||||
{ // 16-bit
|
||||
{ GetRGBA5551_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 2, 2048 }, // YUV
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
|
||||
{ GetIA88_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA88_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // CI as IA
|
||||
{ GetIA88_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA88_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // IA
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
|
||||
|
@ -338,7 +327,7 @@ ImageFormat::ImageFormat()
|
|||
},
|
||||
{ // 16-bit
|
||||
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 2, 2048 }, // YUV
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // CI
|
||||
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI16RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // IA as CI
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
|
||||
|
@ -369,7 +358,7 @@ ImageFormat::ImageFormat()
|
|||
},
|
||||
{ // 16-bit
|
||||
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 2, 2048 }, // YUV
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // CI
|
||||
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI16RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // IA as CI
|
||||
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
|
||||
|
@ -1076,11 +1065,7 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
|
|||
for (y = 0; y < tmptex.realHeight; ++y) {
|
||||
pSrc = &TMEM[tmptex.tMem] + *pLine * y;
|
||||
for (x = 0; x < tmptex.realWidth / 2; x++) {
|
||||
if (glInternalFormat == internalcolorFormat::RGBA8) {
|
||||
GetYUV_RGBA8888(pSrc, pDest + j, x);
|
||||
} else {
|
||||
GetYUV_RGBA4444(pSrc, (u16*)pDest + j, x);
|
||||
}
|
||||
GetYUV_RGBA8888(pSrc, pDest + j, x);
|
||||
j += 2;
|
||||
}
|
||||
}
|
||||
|
@ -1311,39 +1296,22 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture)
|
|||
const s32 texLevel = bUseLOD ? _pTexture->max_level : 0;
|
||||
params.maxMipmapLevel = Parameter(texLevel);
|
||||
|
||||
if (config.texture.bilinearMode == BILINEAR_STANDARD) {
|
||||
if (texLevel > 0) { // Apply standard bilinear to mipmap textures
|
||||
if (bUseBilinear) {
|
||||
if (texLevel > 0)
|
||||
params.minFilter = textureParameters::FILTER_LINEAR_MIPMAP_NEAREST;
|
||||
else
|
||||
params.minFilter = textureParameters::FILTER_LINEAR;
|
||||
params.minFilter = textureParameters::FILTER_LINEAR_MIPMAP_NEAREST;
|
||||
params.magFilter = textureParameters::FILTER_LINEAR;
|
||||
} else {
|
||||
if (texLevel > 0)
|
||||
params.minFilter = textureParameters::FILTER_NEAREST_MIPMAP_NEAREST;
|
||||
else
|
||||
params.minFilter = textureParameters::FILTER_NEAREST;
|
||||
params.magFilter = textureParameters::FILTER_NEAREST;
|
||||
}
|
||||
} else { // 3 point filter
|
||||
if (texLevel > 0) { // Apply standard bilinear to mipmap textures
|
||||
if (bUseBilinear) {
|
||||
params.minFilter = textureParameters::FILTER_LINEAR_MIPMAP_NEAREST;
|
||||
params.magFilter = textureParameters::FILTER_LINEAR;
|
||||
} else {
|
||||
params.minFilter = textureParameters::FILTER_NEAREST_MIPMAP_NEAREST;
|
||||
params.magFilter = textureParameters::FILTER_NEAREST;
|
||||
}
|
||||
} else if (bUseBilinear && config.generalEmulation.enableLOD != 0 && bUseLOD) { // Apply standard bilinear to first tile of mipmap texture
|
||||
params.minFilter = textureParameters::FILTER_LINEAR;
|
||||
params.magFilter = textureParameters::FILTER_LINEAR;
|
||||
} else { // Don't use texture filter. Texture will be filtered by 3 point filter shader
|
||||
params.minFilter = textureParameters::FILTER_NEAREST;
|
||||
params.minFilter = textureParameters::FILTER_NEAREST_MIPMAP_NEAREST;
|
||||
params.magFilter = textureParameters::FILTER_NEAREST;
|
||||
}
|
||||
} else if (bUseBilinear && config.generalEmulation.enableLOD != 0 && bUseLOD) { // Apply standard bilinear to first tile of mipmap texture
|
||||
params.minFilter = textureParameters::FILTER_LINEAR;
|
||||
params.magFilter = textureParameters::FILTER_LINEAR;
|
||||
} else { // Don't use texture filter. Texture will be filtered by filter shader
|
||||
params.minFilter = textureParameters::FILTER_NEAREST;
|
||||
params.magFilter = textureParameters::FILTER_NEAREST;
|
||||
}
|
||||
|
||||
|
||||
// Set clamping modes
|
||||
params.wrapS = _pTexture->clampS ? textureParameters::WRAP_CLAMP_TO_EDGE :
|
||||
_pTexture->mirrorS ? textureParameters::WRAP_MIRRORED_REPEAT
|
||||
|
|
15
src/gDP.cpp
15
src/gDP.cpp
|
@ -765,15 +765,14 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
|
|||
void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 )
|
||||
{
|
||||
// angrylion's macro
|
||||
#define SRA(exp, sa) ((signed)(exp) >> (sa))
|
||||
#define SIGN(i, b) SRA((i) << (32 - (b)), (32 - (b)))
|
||||
#define SIGN(x, numb) (((x) & ((1 << numb) - 1)) | -((x) & (1 << (numb - 1))))
|
||||
|
||||
gDP.convert.k0 = SIGN(k0, 9);
|
||||
gDP.convert.k1 = SIGN(k1, 9);
|
||||
gDP.convert.k2 = SIGN(k2, 9);
|
||||
gDP.convert.k3 = SIGN(k3, 9);
|
||||
gDP.convert.k4 = SIGN(k4, 9);
|
||||
gDP.convert.k5 = SIGN(k5, 9);
|
||||
gDP.convert.k0 = (SIGN(k0, 9) << 1) + 1;
|
||||
gDP.convert.k1 = (SIGN(k1, 9) << 1) + 1;
|
||||
gDP.convert.k2 = (SIGN(k2, 9) << 1) + 1;
|
||||
gDP.convert.k3 = (SIGN(k3, 9) << 1) + 1;
|
||||
gDP.convert.k4 = k4;
|
||||
gDP.convert.k5 = k5;
|
||||
|
||||
DebugMsg( DEBUG_NORMAL, "gDPSetConvert( %i, %i, %i, %i, %i, %i );\n", k0, k1, k2, k3, k4, k5);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user