mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Mip-mapping!
This commit is contained in:
parent
a8021084f2
commit
e4fa0b5717
|
@ -15,7 +15,7 @@
|
|||
|
||||
static GLuint g_vertex_shader_object;
|
||||
static GLuint g_calc_light_shader_object;
|
||||
static GLuint g_calc_lod_shader_object;
|
||||
static GLuint g_calc_mipmap_shader_object;
|
||||
static GLuint g_calc_noise_shader_object;
|
||||
static GLuint g_calc_depth_shader_object;
|
||||
static GLuint g_test_alpha_shader_object;
|
||||
|
@ -179,10 +179,10 @@ void InitShaderCombiner()
|
|||
glCompileShader(g_calc_light_shader_object);
|
||||
assert(check_shader_compile_status(g_calc_light_shader_object));
|
||||
|
||||
g_calc_lod_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(g_calc_lod_shader_object, 1, &fragment_shader_calc_lod, NULL);
|
||||
glCompileShader(g_calc_lod_shader_object);
|
||||
assert(check_shader_compile_status(g_calc_lod_shader_object));
|
||||
g_calc_mipmap_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(g_calc_mipmap_shader_object, 1, &fragment_shader_mipmap, NULL);
|
||||
glCompileShader(g_calc_mipmap_shader_object);
|
||||
assert(check_shader_compile_status(g_calc_mipmap_shader_object));
|
||||
|
||||
g_calc_noise_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(g_calc_noise_shader_object, 1, &noise_fragment_shader, NULL);
|
||||
|
@ -215,8 +215,8 @@ void DestroyShaderCombiner() {
|
|||
#ifndef GLES2
|
||||
glDeleteShader(g_calc_light_shader_object);
|
||||
g_calc_light_shader_object = 0;
|
||||
glDeleteShader(g_calc_lod_shader_object);
|
||||
g_calc_lod_shader_object = 0;
|
||||
glDeleteShader(g_calc_mipmap_shader_object);
|
||||
g_calc_mipmap_shader_object = 0;
|
||||
glDeleteShader(g_calc_noise_shader_object);
|
||||
g_calc_noise_shader_object = 0;
|
||||
glDeleteShader(g_test_alpha_shader_object);
|
||||
|
@ -385,21 +385,32 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
|
|||
strFragmentShader.append(fragment_shader_header_common_functions);
|
||||
strFragmentShader.append(fragment_shader_header_main);
|
||||
const bool bUseLod = (m_nInputs & (1<<LOD_FRACTION)) > 0;
|
||||
if (bUseLod)
|
||||
if (bUseLod) {
|
||||
#ifdef GLES2
|
||||
strBuffer.append(" lowp float lod_frac = calc_lod(uPrimLod, vLodTexCoord); \n");
|
||||
strFragmentShader.append(" lowp vec4 readtex0, readtex1; \n");
|
||||
strFragmentShader.append(" lowp float lod_frac = mipmap(readtex0, readtex1); \n");
|
||||
#else
|
||||
strFragmentShader.append(" float lod_frac = calc_lod(uPrimLod, vLodTexCoord); \n");
|
||||
strFragmentShader.append(" vec4 readtex0, readtex1; \n");
|
||||
strFragmentShader.append(" float lod_frac = mipmap(readtex0, readtex1); \n");
|
||||
#endif
|
||||
} else {
|
||||
if (_alpha.numStages == 1 && _color.numStages == 1) {
|
||||
if ((m_nInputs & ((1 << TEXEL0) | (1 << TEXEL0_ALPHA))) > 0)
|
||||
strFragmentShader.append(fragment_shader_readtex0color);
|
||||
if ((m_nInputs & ((1 << TEXEL1) | (1 << TEXEL1_ALPHA))) > 0)
|
||||
strFragmentShader.append(fragment_shader_readtex1color);
|
||||
} else {
|
||||
if ((m_nInputs & ((1 << TEXEL0) | (1 << TEXEL1) | (1 << TEXEL0_ALPHA) | (1 << TEXEL1_ALPHA))) > 0) {
|
||||
strFragmentShader.append(fragment_shader_readtex0color);
|
||||
strFragmentShader.append(fragment_shader_readtex1color);
|
||||
} else {
|
||||
assert(strstr(strCombiner, "readtex") == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.enableHWLighting)
|
||||
#ifdef GLES2
|
||||
strBuffer.append(" lowp float intensity = calc_light(int(vNumLights), vShadeColor.rgb, input_color); \n");
|
||||
strFragmentShader.append(" lowp float intensity = calc_light(int(vNumLights), vShadeColor.rgb, input_color); \n");
|
||||
#else
|
||||
strFragmentShader.append(" float intensity = calc_light(int(vNumLights), vShadeColor.rgb, input_color); \n");
|
||||
#endif
|
||||
|
@ -421,7 +432,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
|
|||
}
|
||||
|
||||
#ifdef USE_TOONIFY
|
||||
strBuffer.append(" toonify(intensity); \n");
|
||||
strFragmentShader.append(" toonify(intensity); \n");
|
||||
#endif
|
||||
strFragmentShader.append(" if (uEnableFog != 0) \n");
|
||||
strFragmentShader.append(" gl_FragColor = vec4(mix(gl_FragColor.rgb, uFogColor.rgb, vFogFragCoord), gl_FragColor.a); \n");
|
||||
|
@ -433,12 +444,12 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
|
|||
#endif
|
||||
|
||||
#ifdef GLES2
|
||||
strBuffer.append(alpha_test_fragment_shader);
|
||||
strBuffer.append(noise_fragment_shader);
|
||||
strFragmentShader.append(alpha_test_fragment_shader);
|
||||
strFragmentShader.append(noise_fragment_shader);
|
||||
if (bUseLod)
|
||||
strBuffer.append(fragment_shader_calc_lod);
|
||||
strFragmentShader.append(fragment_shader_mipmap);
|
||||
if (config.enableHWLighting)
|
||||
strBuffer.append(fragment_shader_calc_light);
|
||||
strFragmentShader.append(fragment_shader_calc_light);
|
||||
#endif
|
||||
|
||||
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
@ -456,7 +467,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
|
|||
if (config.enableHWLighting)
|
||||
glAttachShader(m_program, g_calc_light_shader_object);
|
||||
if (bUseLod)
|
||||
glAttachShader(m_program, g_calc_lod_shader_object);
|
||||
glAttachShader(m_program, g_calc_mipmap_shader_object);
|
||||
glAttachShader(m_program, g_test_alpha_shader_object);
|
||||
if (video().getRender().isImageTexturesSupported())
|
||||
glAttachShader(m_program, g_calc_depth_shader_object);
|
||||
|
|
206
Shaders.h
206
Shaders.h
|
@ -162,14 +162,14 @@ static const char* fragment_shader_header_common_functions =
|
|||
" \n"
|
||||
"lowp float snoise(in mediump vec2 v); \n"
|
||||
"lowp float calc_light(in lowp int nLights, in lowp vec3 input_color, out lowp vec3 output_color);\n"
|
||||
"lowp float calc_lod(in lowp float primLod, in mediump vec2 texCoord); \n"
|
||||
"lowp float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1); \n"
|
||||
"lowp bool depth_compare(); \n"
|
||||
"lowp bool alpha_test(in lowp float alphaValue); \n"
|
||||
#else
|
||||
" \n"
|
||||
"float snoise(in vec2 v); \n"
|
||||
"float calc_light(in int nLights, in vec3 input_color, out vec3 output_color);\n"
|
||||
"float calc_lod(in float primLod, in vec2 texCoord); \n"
|
||||
"float mipmap(out vec4 readtex0, out vec4 readtex1); \n"
|
||||
"bool depth_compare(); \n"
|
||||
"bool alpha_test(in float alphaValue); \n"
|
||||
#endif
|
||||
|
@ -224,70 +224,6 @@ static const char* fragment_shader_calc_light =
|
|||
#endif
|
||||
;
|
||||
|
||||
static const char* fragment_shader_calc_lod =
|
||||
#ifdef GLES2
|
||||
"uniform lowp int uEnableLod; \n"
|
||||
"uniform lowp float uLodXScale; \n"
|
||||
"uniform lowp float uLodYScale; \n"
|
||||
"uniform lowp float uMinLod; \n"
|
||||
"uniform lowp int uMaxTile; \n"
|
||||
"uniform lowp int uTextureDetail; \n"
|
||||
" \n"
|
||||
"lowp float calc_lod(in lowp float primLod, in mediump vec2 texCoord) { \n"
|
||||
//" if (uEnableLod == 0) \n"
|
||||
" return primLod; \n"
|
||||
/*
|
||||
" mediump vec2 dx = dFdx(texCoord); \n"
|
||||
" dx.x *= uLodXScale; \n"
|
||||
" dx.y *= uLodYScale; \n"
|
||||
" mediump vec2 dy = dFdy(texCoord); \n"
|
||||
" dy.x *= uLodXScale; \n"
|
||||
" dy.y *= uLodYScale; \n"
|
||||
" mediump float lod = max(length(dx), length(dy)); \n"
|
||||
" lowp float lod_frac; \n"
|
||||
" if (lod < 1.0) { \n"
|
||||
" lod_frac = max(lod, uMinLod); \n"
|
||||
" if (uTextureDetail == 1) \n"
|
||||
" lod_frac = 1.0 - lod_frac; \n"
|
||||
" } else { \n"
|
||||
" lowp float tile = min(float(uMaxTile), floor(log2(floor(lod)))); \n"
|
||||
" lod_frac = max(uMinLod, fract(lod/pow(2.0, tile)));\n"
|
||||
" } \n"
|
||||
" return lod_frac; \n"
|
||||
*/
|
||||
"} \n"
|
||||
#else
|
||||
"uniform int uEnableLod; \n"
|
||||
"uniform float uLodXScale; \n"
|
||||
"uniform float uLodYScale; \n"
|
||||
"uniform float uMinLod; \n"
|
||||
"uniform int uMaxTile; \n"
|
||||
"uniform int uTextureDetail; \n"
|
||||
" \n"
|
||||
"float calc_lod(in float primLod, in vec2 texCoord) { \n"
|
||||
" if (uEnableLod == 0) \n"
|
||||
" return primLod; \n"
|
||||
" vec2 dx = dFdx(texCoord); \n"
|
||||
" dx.x *= uLodXScale; \n"
|
||||
" dx.y *= uLodYScale; \n"
|
||||
" vec2 dy = dFdy(texCoord); \n"
|
||||
" dy.x *= uLodXScale; \n"
|
||||
" dy.y *= uLodYScale; \n"
|
||||
" float lod = max(length(dx), length(dy)); \n"
|
||||
" float lod_frac; \n"
|
||||
" if (lod < 1.0) { \n"
|
||||
" lod_frac = max(lod, uMinLod); \n"
|
||||
" if (uTextureDetail == 1) \n"
|
||||
" lod_frac = 1.0 - lod_frac; \n"
|
||||
" } else { \n"
|
||||
" float tile = min(float(uMaxTile), floor(log2(floor(lod)))); \n"
|
||||
" lod_frac = max(uMinLod, fract(lod/pow(2.0, tile)));\n"
|
||||
" } \n"
|
||||
" return lod_frac; \n"
|
||||
"} \n"
|
||||
#endif
|
||||
;
|
||||
|
||||
static const char* alpha_test_fragment_shader =
|
||||
#ifdef GLES2
|
||||
"uniform lowp int uEnableAlphaTest; \n"
|
||||
|
@ -393,6 +329,144 @@ static const char* fragment_shader_readtex1color =
|
|||
" if (uFbFixedAlpha == 2 || uFbFixedAlpha == 3) readtex1.a = 0.825; \n"
|
||||
;
|
||||
|
||||
static const char* fragment_shader_mipmap =
|
||||
#ifdef GLES2
|
||||
"uniform lowp int uEnableLod; \n"
|
||||
"uniform lowp float uLodXScale; \n"
|
||||
"uniform lowp float uLodYScale; \n"
|
||||
"uniform lowp float uMinLod; \n"
|
||||
"uniform lowp int uMaxTile; \n"
|
||||
"uniform lowp int uTextureDetail; \n"
|
||||
" \n"
|
||||
"lowp float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
|
||||
" if (uEnableLod == 0) { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
" readtex1 = texture2D(uTex1, vTexCoord1); \n"
|
||||
" return uPrimLod; \n"
|
||||
" } \n"
|
||||
" mediump vec2 dx = dFdx(vLodTexCoord); \n"
|
||||
" dx.x *= uLodXScale; \n"
|
||||
" dx.y *= uLodYScale; \n"
|
||||
" mediump vec2 dy = dFdy(vLodTexCoord); \n"
|
||||
" dy.x *= uLodXScale; \n"
|
||||
" dy.y *= uLodYScale; \n"
|
||||
" mediump float lod = max(length(dx), length(dy)); \n"
|
||||
" lowp float lod_tile, lod_frac; \n"
|
||||
" lowp bool magnifying; \n"
|
||||
" if (lod < 1.0) { \n"
|
||||
" magnifying = true; \n"
|
||||
" lod_tile = 0.0; \n"
|
||||
" lod_frac = lod; \n"
|
||||
" if (uTextureDetail != 0) \n"
|
||||
" lod_frac = max(lod, uMinLod); \n"
|
||||
" if (uTextureDetail == 1) \n"
|
||||
" lod_frac = 1.0 - lod_frac; \n"
|
||||
" } else { \n"
|
||||
" magnifying = false; \n"
|
||||
" lod_tile = min(float(uMaxTile), floor(log2(floor(lod)))); \n"
|
||||
" lod_frac = fract(lod/pow(2.0, lod_tile)); \n"
|
||||
" } \n"
|
||||
" if (lod_tile < 1.0) { \n"
|
||||
" if (magnifying) { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
// !sharpen && !detail
|
||||
" if (uTextureDetail == 0) readtex1 = readtex0; \n"
|
||||
" else readtex1 = texture2D(uTex1, vTexCoord1); \n"
|
||||
" } else { \n"
|
||||
// detail
|
||||
" if (uTextureDetail == 2) { \n"
|
||||
" readtex0 = texture2DLod(uTex1, vTexCoord1, 0.0);\n"
|
||||
" readtex1 = texture2DLod(uTex1, vTexCoord1, 1.0);\n"
|
||||
" } else { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
" readtex1 = texture2D(uTex1, vTexCoord1); \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" } else { \n"
|
||||
" if (uTextureDetail == 2) { \n"
|
||||
" readtex0 = texture2DLod(uTex1, vTexCoord1, lod_tile); \n"
|
||||
" readtex1 = texture2DLod(uTex1, vTexCoord1, lod_tile + 1.0); \n"
|
||||
" } else { \n"
|
||||
" readtex0 = texture2DLod(uTex1, vTexCoord1, lod_tile - 1.0); \n"
|
||||
" readtex1 = texture2DLod(uTex1, vTexCoord1, lod_tile); \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" return lod_frac; \n"
|
||||
"} \n"
|
||||
"} \n"
|
||||
#else
|
||||
"varying vec2 vTexCoord0; \n"
|
||||
"varying vec2 vTexCoord1; \n"
|
||||
"varying vec2 vLodTexCoord; \n"
|
||||
"uniform sampler2D uTex0; \n"
|
||||
"uniform sampler2D uTex1; \n"
|
||||
"uniform float uPrimLod; \n"
|
||||
"uniform int uEnableLod; \n"
|
||||
"uniform float uLodXScale; \n"
|
||||
"uniform float uLodYScale; \n"
|
||||
"uniform float uMinLod; \n"
|
||||
"uniform int uMaxTile; \n"
|
||||
"uniform int uTextureDetail; \n"
|
||||
" \n"
|
||||
"float mipmap(out vec4 readtex0, out vec4 readtex1) { \n"
|
||||
" if (uEnableLod == 0) { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
" readtex1 = texture2D(uTex1, vTexCoord1); \n"
|
||||
" return uPrimLod; \n"
|
||||
" } \n"
|
||||
" vec2 dx = dFdx(vLodTexCoord); \n"
|
||||
" dx.x *= uLodXScale; \n"
|
||||
" dx.y *= uLodYScale; \n"
|
||||
" vec2 dy = dFdy(vLodTexCoord); \n"
|
||||
" dy.x *= uLodXScale; \n"
|
||||
" dy.y *= uLodYScale; \n"
|
||||
" float lod = max(length(dx), length(dy)); \n"
|
||||
//" float lod = max(length(dx), length(dy)) * max(uLodXScale, uLodYScale);\n"
|
||||
" float lod_tile, lod_frac; \n"
|
||||
" bool magnifying; \n"
|
||||
" if (lod < 1.0) { \n"
|
||||
" magnifying = true; \n"
|
||||
" lod_tile = 0.0; \n"
|
||||
" lod_frac = lod; \n"
|
||||
" if (uTextureDetail != 0) \n"
|
||||
" lod_frac = max(lod, uMinLod); \n"
|
||||
" if (uTextureDetail == 1) \n"
|
||||
" lod_frac = 1.0 - lod_frac; \n"
|
||||
" } else { \n"
|
||||
" magnifying = false; \n"
|
||||
" lod_tile = min(float(uMaxTile), floor(log2(floor(lod)))); \n"
|
||||
" lod_frac = fract(lod/pow(2.0, lod_tile)); \n"
|
||||
" } \n"
|
||||
" if (lod_tile < 1.0) { \n"
|
||||
" if (magnifying) { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
// !sharpen && !detail
|
||||
" if (uTextureDetail == 0) readtex1 = readtex0; \n"
|
||||
" else readtex1 = texture2D(uTex1, vTexCoord1); \n"
|
||||
" } else { \n"
|
||||
// detail
|
||||
" if (uTextureDetail == 2) { \n"
|
||||
" readtex0 = texture2DLod(uTex1, vTexCoord1, 0.0);\n"
|
||||
" readtex1 = texture2DLod(uTex1, vTexCoord1, 1.0);\n"
|
||||
" } else { \n"
|
||||
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
|
||||
" readtex1 = texture2D(uTex1, vTexCoord1); \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" } else { \n"
|
||||
" if (uTextureDetail == 2) { \n"
|
||||
" readtex0 = texture2DLod(uTex1, vTexCoord1, lod_tile); \n"
|
||||
" readtex1 = texture2DLod(uTex1, vTexCoord1, lod_tile + 1.0); \n"
|
||||
" } else { \n"
|
||||
" readtex0 = texture2DLod(uTex1, vTexCoord1, lod_tile - 1.0); \n"
|
||||
" readtex1 = texture2DLod(uTex1, vTexCoord1, lod_tile); \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" return lod_frac; \n"
|
||||
"} \n"
|
||||
#endif
|
||||
;
|
||||
|
||||
static const char* fragment_shader_end =
|
||||
"} \n"
|
||||
#endif
|
||||
|
|
124
Textures.cpp
124
Textures.cpp
|
@ -389,7 +389,7 @@ void TextureCache::_loadBackground( CachedTexture *pTexture )
|
|||
free(pDest);
|
||||
}
|
||||
|
||||
void TextureCache::_load(CachedTexture *pTexture)
|
||||
void TextureCache::_load(u32 _tile , CachedTexture *_pTexture)
|
||||
{
|
||||
u32 *pDest;
|
||||
|
||||
|
@ -400,13 +400,15 @@ void TextureCache::_load(CachedTexture *pTexture)
|
|||
GetTexelFunc GetTexel;
|
||||
GLuint glInternalFormat;
|
||||
GLenum glType;
|
||||
u32 sizeShift;
|
||||
|
||||
if (((imageFormat[pTexture->size][pTexture->format].autoFormat == GL_RGBA) ||
|
||||
((pTexture->format == G_IM_FMT_CI) && (gDP.otherMode.textureLUT == G_TT_IA16)) || (m_bitDepth == 2)) && (m_bitDepth != 0))
|
||||
if (((imageFormat[_pTexture->size][_pTexture->format].autoFormat == GL_RGBA) ||
|
||||
((_pTexture->format == G_IM_FMT_CI) && (gDP.otherMode.textureLUT == G_TT_IA16)) || (m_bitDepth == 2)) && (m_bitDepth != 0))
|
||||
{
|
||||
pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 2;
|
||||
if ((pTexture->format == G_IM_FMT_CI) && (gDP.otherMode.textureLUT == G_TT_IA16)) {
|
||||
if (pTexture->size == G_IM_SIZ_4b)
|
||||
sizeShift = 2;
|
||||
_pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift;
|
||||
if ((_pTexture->format == G_IM_FMT_CI) && (gDP.otherMode.textureLUT == G_TT_IA16)) {
|
||||
if (_pTexture->size == G_IM_SIZ_4b)
|
||||
GetTexel = GetCI4IA_RGBA8888;
|
||||
else
|
||||
GetTexel = GetCI8IA_RGBA8888;
|
||||
|
@ -414,14 +416,15 @@ void TextureCache::_load(CachedTexture *pTexture)
|
|||
glInternalFormat = GL_RGBA;
|
||||
glType = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
GetTexel = imageFormat[pTexture->size][pTexture->format].Get32;
|
||||
glInternalFormat = imageFormat[pTexture->size][pTexture->format].glInternalFormat32;
|
||||
glType = imageFormat[pTexture->size][pTexture->format].glType32;
|
||||
GetTexel = imageFormat[_pTexture->size][_pTexture->format].Get32;
|
||||
glInternalFormat = imageFormat[_pTexture->size][_pTexture->format].glInternalFormat32;
|
||||
glType = imageFormat[_pTexture->size][_pTexture->format].glType32;
|
||||
}
|
||||
} else {
|
||||
pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 1;
|
||||
if ((pTexture->format == G_IM_FMT_CI) && (gDP.otherMode.textureLUT == G_TT_IA16)) {
|
||||
if (pTexture->size == G_IM_SIZ_4b)
|
||||
sizeShift = 1;
|
||||
_pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift;
|
||||
if ((_pTexture->format == G_IM_FMT_CI) && (gDP.otherMode.textureLUT == G_TT_IA16)) {
|
||||
if (_pTexture->size == G_IM_SIZ_4b)
|
||||
GetTexel = GetCI4IA_RGBA4444;
|
||||
else
|
||||
GetTexel = GetCI8IA_RGBA4444;
|
||||
|
@ -429,67 +432,101 @@ void TextureCache::_load(CachedTexture *pTexture)
|
|||
glInternalFormat = GL_RGBA4;
|
||||
glType = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
} else {
|
||||
GetTexel = imageFormat[pTexture->size][pTexture->format].Get16;
|
||||
glInternalFormat = imageFormat[pTexture->size][pTexture->format].glInternalFormat16;
|
||||
glType = imageFormat[pTexture->size][pTexture->format].glType16;
|
||||
GetTexel = imageFormat[_pTexture->size][_pTexture->format].Get16;
|
||||
glInternalFormat = imageFormat[_pTexture->size][_pTexture->format].glInternalFormat16;
|
||||
glType = imageFormat[_pTexture->size][_pTexture->format].glType16;
|
||||
}
|
||||
}
|
||||
|
||||
pDest = (u32*)malloc( pTexture->textureBytes );
|
||||
pDest = (u32*)malloc( _pTexture->textureBytes );
|
||||
|
||||
line = pTexture->line;
|
||||
GLint mipLevel = 0, maxLevel = 0;
|
||||
if (gSP.texture.level > 1)
|
||||
maxLevel = _tile == 0 ? 0 : gSP.texture.level - 1;
|
||||
|
||||
if (pTexture->size == G_IM_SIZ_32b)
|
||||
_pTexture->max_level = maxLevel;
|
||||
|
||||
CachedTexture tmptex(0);
|
||||
memcpy(&tmptex, _pTexture, sizeof(CachedTexture));
|
||||
|
||||
line = tmptex.line;
|
||||
if (tmptex.size == G_IM_SIZ_32b)
|
||||
line <<= 1;
|
||||
|
||||
if (pTexture->maskS) {
|
||||
clampSClamp = pTexture->clampS ? pTexture->clampWidth - 1 : (pTexture->mirrorS ? (pTexture->width << 1) - 1 : pTexture->width - 1);
|
||||
maskSMask = (1 << pTexture->maskS) - 1;
|
||||
mirrorSBit = pTexture->mirrorS ? 1 << pTexture->maskS : 0;
|
||||
while (true) {
|
||||
if (tmptex.maskS > 0) {
|
||||
clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : (tmptex.mirrorS ? (tmptex.width << 1) - 1 : tmptex.width - 1);
|
||||
maskSMask = (1 << tmptex.maskS) - 1;
|
||||
mirrorSBit = tmptex.mirrorS ? 1 << tmptex.maskS : 0;
|
||||
} else {
|
||||
clampSClamp = min( pTexture->clampWidth, pTexture->width ) - 1;
|
||||
clampSClamp = min(tmptex.clampWidth, tmptex.width) - 1;
|
||||
maskSMask = 0xFFFF;
|
||||
mirrorSBit = 0x0000;
|
||||
}
|
||||
|
||||
if (pTexture->maskT) {
|
||||
clampTClamp = pTexture->clampT ? pTexture->clampHeight - 1 : (pTexture->mirrorT ? (pTexture->height << 1) - 1: pTexture->height - 1);
|
||||
maskTMask = (1 << pTexture->maskT) - 1;
|
||||
mirrorTBit = pTexture->mirrorT ? 1 << pTexture->maskT : 0;
|
||||
if (tmptex.maskT > 0) {
|
||||
clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : (tmptex.mirrorT ? (tmptex.height << 1) - 1: tmptex.height - 1);
|
||||
maskTMask = (1 << tmptex.maskT) - 1;
|
||||
mirrorTBit = tmptex.mirrorT ? 1 << tmptex.maskT : 0;
|
||||
} else {
|
||||
clampTClamp = min( pTexture->clampHeight, pTexture->height ) - 1;
|
||||
clampTClamp = min( tmptex.clampHeight, tmptex.height ) - 1;
|
||||
maskTMask = 0xFFFF;
|
||||
mirrorTBit = 0x0000;
|
||||
}
|
||||
|
||||
// Hack for Zelda warp texture
|
||||
if (((pTexture->tMem << 3) + (pTexture->width * pTexture->height << pTexture->size >> 1)) > 4096)
|
||||
pTexture->tMem = 0;
|
||||
if (((tmptex.tMem << 3) + (tmptex.width * tmptex.height << tmptex.size >> 1)) > 4096)
|
||||
tmptex.tMem = 0;
|
||||
|
||||
j = 0;
|
||||
for (y = 0; y < pTexture->realHeight; y++) {
|
||||
for (y = 0; y < tmptex.realHeight; y++) {
|
||||
ty = min(y, clampTClamp) & maskTMask;
|
||||
|
||||
if (y & mirrorTBit)
|
||||
ty ^= maskTMask;
|
||||
|
||||
pSrc = &TMEM[pTexture->tMem] + line * ty;
|
||||
pSrc = &TMEM[tmptex.tMem] + line * ty;
|
||||
|
||||
i = (ty & 1) << 1;
|
||||
for (x = 0; x < pTexture->realWidth; x++) {
|
||||
for (x = 0; x < tmptex.realWidth; x++) {
|
||||
tx = min(x, clampSClamp) & maskSMask;
|
||||
|
||||
if (x & mirrorSBit)
|
||||
tx ^= maskSMask;
|
||||
|
||||
if (glInternalFormat == GL_RGBA)
|
||||
((u32*)pDest)[j++] = GetTexel( pSrc, tx, i, pTexture->palette );
|
||||
((u32*)pDest)[j++] = GetTexel( pSrc, tx, i, tmptex.palette );
|
||||
else
|
||||
((u16*)pDest)[j++] = GetTexel( pSrc, tx, i, pTexture->palette );
|
||||
((u16*)pDest)[j++] = GetTexel( pSrc, tx, i, tmptex.palette );
|
||||
}
|
||||
}
|
||||
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, glInternalFormat, pTexture->realWidth, pTexture->realHeight, 0, GL_RGBA, glType, pDest );
|
||||
glTexImage2D(GL_TEXTURE_2D, mipLevel, glInternalFormat, tmptex.realWidth, tmptex.realHeight, 0, GL_RGBA, glType, pDest);
|
||||
if (mipLevel == maxLevel)
|
||||
break;
|
||||
++mipLevel;
|
||||
if (line > 1)
|
||||
line >>= 1;
|
||||
if (tmptex.maskS > 0)
|
||||
--tmptex.maskS;
|
||||
if (tmptex.clampWidth > 1)
|
||||
tmptex.clampWidth >>= 1;
|
||||
if (tmptex.width > 1)
|
||||
tmptex.width >>= 1;
|
||||
if (tmptex.realWidth > 1)
|
||||
tmptex.realWidth >>= 1;
|
||||
if (tmptex.maskT > 0)
|
||||
--tmptex.maskT;
|
||||
if (tmptex.clampHeight > 1)
|
||||
tmptex.clampHeight >>= 1;
|
||||
if (tmptex.height > 1)
|
||||
tmptex.height >>= 1;
|
||||
if (tmptex.realHeight > 1)
|
||||
tmptex.realHeight >>= 1;
|
||||
tmptex.tMem = gDP.tiles[gSP.texture.tile + mipLevel + 1].tmem;
|
||||
tmptex.palette = gDP.tiles[gSP.texture.tile + mipLevel + 1].palette;
|
||||
_pTexture->textureBytes += (tmptex.realWidth * tmptex.realHeight) << sizeShift;
|
||||
};
|
||||
free(pDest);
|
||||
}
|
||||
|
||||
|
@ -550,18 +587,23 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture)
|
|||
// Bind the cached texture
|
||||
glBindTexture( GL_TEXTURE_2D, _pTexture->glName );
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, _pTexture->max_level);
|
||||
// Set filter mode. Almost always bilinear, but check anyways
|
||||
if ((gDP.otherMode.textureFilter == G_TF_BILERP) || (gDP.otherMode.textureFilter == G_TF_AVERAGE) || (config.texture.forceBilinear))
|
||||
{
|
||||
if ((gDP.otherMode.textureFilter == G_TF_BILERP) || (gDP.otherMode.textureFilter == G_TF_AVERAGE) || (config.texture.forceBilinear)) {
|
||||
if (_pTexture->max_level > 0)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
else
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
} else {
|
||||
if (_pTexture->max_level > 0)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
|
||||
// Set clamping modes
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _pTexture->clampS ? GL_CLAMP_TO_EDGE : GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _pTexture->clampT ? GL_CLAMP_TO_EDGE : GL_REPEAT );
|
||||
|
@ -920,7 +962,7 @@ void TextureCache::update(u32 _t)
|
|||
else if (gSP.textureTile[_t]->shiftt > 0)
|
||||
pCurrent->shiftScaleT /= (f32)(1 << gSP.textureTile[_t]->shiftt);
|
||||
|
||||
_load( pCurrent );
|
||||
_load( _t, pCurrent );
|
||||
activateTexture( _t, pCurrent );
|
||||
|
||||
m_cachedBytes += pCurrent->textureBytes;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
struct CachedTexture
|
||||
{
|
||||
CachedTexture(GLuint _glName) : glName(_glName) {}
|
||||
CachedTexture(GLuint _glName) : glName(_glName), max_level(0) {}
|
||||
|
||||
GLuint glName;
|
||||
u32 crc;
|
||||
|
@ -39,6 +39,7 @@ struct CachedTexture
|
|||
|
||||
u32 lastDList;
|
||||
u32 address;
|
||||
u32 max_level;
|
||||
};
|
||||
|
||||
|
||||
|
@ -71,7 +72,7 @@ private:
|
|||
|
||||
void _checkCacheSize();
|
||||
CachedTexture * _addTexture(u32 _crc32);
|
||||
void _load(CachedTexture *pTexture);
|
||||
void _load(u32 _tile, CachedTexture *_pTexture);
|
||||
void _loadBackground(CachedTexture *pTexture);
|
||||
void _updateBackground();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user