mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Add support for LOD with GLES2
This commit is contained in:
parent
d061ca044d
commit
a48e1e37ca
|
@ -191,23 +191,29 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
|
|||
|
||||
if (bUseHWLight)
|
||||
strFragmentShader.append(fragment_shader_calc_light);
|
||||
if (bUseLod)
|
||||
strFragmentShader.append(fragment_shader_fake_mipmap);
|
||||
else if (usesTexture()) {
|
||||
|
||||
if (bUseLod) {
|
||||
if (config.generalEmulation.enableLOD != 0)
|
||||
strFragmentShader.append(fragment_shader_mipmap);
|
||||
else
|
||||
strFragmentShader.append(fragment_shader_fake_mipmap);
|
||||
} else if (usesTexture()) {
|
||||
if (config.texture.bilinearMode == BILINEAR_3POINT)
|
||||
strFragmentShader.append(fragment_shader_readtex_3point);
|
||||
else
|
||||
strFragmentShader.append(fragment_shader_readtex);
|
||||
}
|
||||
if (config.generalEmulation.enableNoise != 0)
|
||||
|
||||
if (config.generalEmulation.enableNoise != 0) {
|
||||
strFragmentShader.append(fragment_shader_noise);
|
||||
}
|
||||
|
||||
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
const GLchar * strShaderData = strFragmentShader.data();
|
||||
glShaderSource(fragmentShader, 1, &strShaderData, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
if (!checkShaderCompileStatus(fragmentShader))
|
||||
LOG(LOG_ERROR, "Error in fragment shader:\n%s\n", strFragmentShader.data());
|
||||
logErrorShader(GL_FRAGMENT_SHADER, strFragmentShader);
|
||||
|
||||
m_program = glCreateProgram();
|
||||
_locate_attributes();
|
||||
|
@ -251,6 +257,7 @@ void ShaderCombiner::_locateUniforms() {
|
|||
LocateUniform(uFbMonochrome);
|
||||
LocateUniform(uFbFixedAlpha);
|
||||
LocateUniform(uMaxTile)
|
||||
LocateUniform(uTextureDetail);
|
||||
LocateUniform(uTexturePersp);
|
||||
LocateUniform(uTextureFilterMode);
|
||||
LocateUniform(uForceBlendCycle1);
|
||||
|
@ -388,9 +395,20 @@ void ShaderCombiner::updateDitherMode(bool _bForce)
|
|||
|
||||
void ShaderCombiner::updateLOD(bool _bForce)
|
||||
{
|
||||
if (usesLOD()) {
|
||||
m_uniforms.uMinLod.set(gDP.primColor.m, _bForce);
|
||||
m_uniforms.uMaxTile.set(gSP.texture.level, _bForce);
|
||||
if (!usesLOD())
|
||||
return;
|
||||
|
||||
m_uniforms.uMinLod.set(gDP.primColor.m, _bForce);
|
||||
m_uniforms.uMaxTile.set(gSP.texture.level, _bForce);
|
||||
|
||||
if (config.generalEmulation.enableLOD != 0) {
|
||||
const int uCalcLOD = (gDP.otherMode.textureLOD == G_TL_LOD) ? 1 : 0;
|
||||
m_uniforms.uEnableLod.set(uCalcLOD, _bForce);
|
||||
if (config.frameBufferEmulation.nativeResFactor == 0)
|
||||
m_uniforms.uScreenScale.set(video().getScaleX(), video().getScaleY(), _bForce);
|
||||
else
|
||||
m_uniforms.uScreenScale.set(float(config.frameBufferEmulation.nativeResFactor), float(config.frameBufferEmulation.nativeResFactor), _bForce);
|
||||
m_uniforms.uTextureDetail.set(gDP.otherMode.textureDetail, _bForce);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#define SHADER_VERSION "#version 100 \n"
|
||||
#define SHADER_VERSION "#version 100 \n" \
|
||||
"#extension GL_EXT_shader_texture_lod : enable \n" \
|
||||
"#extension GL_OES_standard_derivatives : enable \n"
|
||||
|
||||
static const char* vertex_shader =
|
||||
SHADER_VERSION
|
||||
|
@ -281,6 +283,75 @@ static const char* fragment_shader_end =
|
|||
"} \n"
|
||||
;
|
||||
|
||||
static const char* fragment_shader_mipmap =
|
||||
"uniform lowp int uEnableLod; \n"
|
||||
"uniform mediump float uMinLod; \n"
|
||||
"uniform lowp int uMaxTile; \n"
|
||||
"uniform lowp int uTextureDetail; \n"
|
||||
" \n"
|
||||
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
" readtex1 = texture2DLodEXT(uTex1, vTexCoord1, 0.0); \n"
|
||||
" \n"
|
||||
" mediump float fMaxTile = float(uMaxTile); \n"
|
||||
#if 1
|
||||
" mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n"
|
||||
" dx *= uScreenScale; \n"
|
||||
" mediump float lod = max(dx.x, dx.y); \n"
|
||||
#else
|
||||
" mediump vec2 dx = dFdx(vLodTexCoord); \n"
|
||||
" dx *= uScreenScale; \n"
|
||||
" mediump vec2 dy = dFdy(vLodTexCoord); \n"
|
||||
" dy *= uScreenScale; \n"
|
||||
" mediump float lod = max(length(dx), length(dy)); \n"
|
||||
#endif
|
||||
" bool magnify = lod < 1.0; \n"
|
||||
" mediump float lod_tile = magnify ? 0.0 : floor(log2(floor(lod))); \n"
|
||||
" bool distant = lod > 128.0 || lod_tile >= fMaxTile; \n"
|
||||
" mediump float lod_frac = fract(lod/pow(2.0, lod_tile)); \n"
|
||||
" if (magnify) lod_frac = max(lod_frac, uMinLod); \n"
|
||||
" if (uTextureDetail == 0) { \n"
|
||||
" if (distant) lod_frac = 1.0; \n"
|
||||
" else if (magnify) lod_frac = 0.0; \n"
|
||||
" } \n"
|
||||
" if (magnify && (uTextureDetail == 1 || uTextureDetail == 3)) \n"
|
||||
" lod_frac = 1.0 - lod_frac; \n"
|
||||
" if (uMaxTile == 0) { \n"
|
||||
" if (uEnableLod != 0 && (uTextureDetail == 2 || uTextureDetail == 3)) \n"
|
||||
" readtex1 = readtex0; \n"
|
||||
" return lod_frac; \n"
|
||||
" } \n"
|
||||
" if (uEnableLod == 0) return lod_frac; \n"
|
||||
" \n"
|
||||
" lod_tile = min(lod_tile, fMaxTile); \n"
|
||||
" lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n"
|
||||
" lowp vec4 lodT = texture2DLodEXT(uTex1, vTexCoord1, lod_tile); \n"
|
||||
" lowp vec4 lodT_m1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile_m1); \n"
|
||||
" lowp vec4 lodT_p1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile + 1.0); \n"
|
||||
" if (lod_tile < 1.0) { \n"
|
||||
" if (magnify) { \n"
|
||||
// !sharpen && !detail
|
||||
" if (uTextureDetail == 0) readtex1 = readtex0; \n"
|
||||
" } else { \n"
|
||||
// detail
|
||||
" if (uTextureDetail == 2 || uTextureDetail == 3) { \n"
|
||||
" readtex0 = lodT; \n"
|
||||
" readtex1 = lodT_p1; \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" } else { \n"
|
||||
" if (uTextureDetail == 2 || uTextureDetail == 3) { \n"
|
||||
" readtex0 = lodT; \n"
|
||||
" readtex1 = lodT_p1; \n"
|
||||
" } else { \n"
|
||||
" readtex0 = lodT_m1; \n"
|
||||
" readtex1 = lodT; \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" return lod_frac; \n"
|
||||
"} \n"
|
||||
;
|
||||
|
||||
static const char* fragment_shader_fake_mipmap =
|
||||
"uniform lowp int uMaxTile; \n"
|
||||
"uniform mediump float uMinLod; \n"
|
||||
|
|
|
@ -2102,6 +2102,13 @@ void OGLRender::_initExtensions()
|
|||
} else
|
||||
config.texture.maxAnisotropyF = 0.0f;
|
||||
LOG(LOG_VERBOSE, "Max Anisotropy: %f\n", config.texture.maxAnisotropyF);
|
||||
|
||||
#ifdef GLES2
|
||||
if(!OGLVideo::isExtensionSupported("GL_EXT_shader_texture_lod") ||
|
||||
!OGLVideo::isExtensionSupported("GL_OES_standard_derivatives")) {
|
||||
config.generalEmulation.enableLOD = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OGLRender::_initStates()
|
||||
|
|
|
@ -1066,13 +1066,11 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
pDest = (u32*)malloc(_pTexture->textureBytes);
|
||||
assert(pDest != nullptr);
|
||||
|
||||
GLint mipLevel = 0, maxLevel = 0;
|
||||
#ifndef GLES2
|
||||
if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > 1)
|
||||
maxLevel = _tile == 0 ? 0 : gSP.texture.level - 1;
|
||||
#endif
|
||||
GLint mipLevel = 0;
|
||||
_pTexture->max_level = 0;
|
||||
|
||||
_pTexture->max_level = maxLevel;
|
||||
if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > 1)
|
||||
_pTexture->max_level = static_cast<u8>(_tile == 0 ? 0 : gSP.texture.level - 1);
|
||||
|
||||
CachedTexture tmptex(0);
|
||||
memcpy(&tmptex, _pTexture, sizeof(CachedTexture));
|
||||
|
@ -1099,7 +1097,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
|
||||
bool bLoaded = false;
|
||||
if ((config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 &&
|
||||
maxLevel == 0 &&
|
||||
_pTexture->max_level == 0 &&
|
||||
(config.textureFilter.txFilterIgnoreBG == 0 || (RSP.cmd != G_TEXRECT && RSP.cmd != G_TEXRECTFLIP)) &&
|
||||
TFH.isInited())
|
||||
{
|
||||
|
@ -1135,7 +1133,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
tmptex.realHeight, 0, GL_RGBA, glType, pDest);
|
||||
#endif
|
||||
}
|
||||
if (mipLevel == maxLevel)
|
||||
if (mipLevel == _pTexture->max_level)
|
||||
break;
|
||||
++mipLevel;
|
||||
const u32 tileMipLevel = gSP.texture.tile + mipLevel + 1;
|
||||
|
|
Loading…
Reference in New Issue
Block a user