gpu: add anisotropic filtering

This commit is contained in:
Toocanzs
2020-08-18 13:54:02 -04:00
committed by GitHub
parent 105046b2f5
commit 24cfac14fa
4 changed files with 62 additions and 1 deletions

View File

@@ -31,6 +31,7 @@ class GLUtil
private static final int ERR_LEN = 1024;
private static final int[] buf = new int[1];
private static final float[] fbuf = new float[1];
static int glGetInteger(GL4 gl, int pname)
{
@@ -38,6 +39,12 @@ class GLUtil
return buf[0];
}
static float glGetFloat(GL4 gl, int pname)
{
gl.glGetFloatv(pname, fbuf, 0);
return fbuf[0];
}
static int glGetShader(GL4 gl, int shader, int pname)
{
gl.glGetShaderiv(shader, pname, buf, 0);

View File

@@ -243,6 +243,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
private int lastStretchedCanvasWidth;
private int lastStretchedCanvasHeight;
private AntiAliasingMode lastAntiAliasingMode;
private int lastAnisotropicFilteringLevel = -1;
private int centerX;
private int centerY;
@@ -1106,6 +1107,15 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
int renderViewportHeight = viewportHeight;
int renderViewportWidth = viewportWidth;
// Setup anisotropic filtering
final int anisotropicFilteringLevel = config.anisotropicFilteringLevel();
if (textureArrayId != -1 && lastAnisotropicFilteringLevel != anisotropicFilteringLevel)
{
textureManager.setAnisotropicFilteringLevel(textureArrayId, anisotropicFilteringLevel, gl);
lastAnisotropicFilteringLevel = anisotropicFilteringLevel;
}
if (client.isStretchedEnabled())
{
Dimension dim = client.getStretchedDimensions();

View File

@@ -108,4 +108,19 @@ public interface GpuPluginConfig extends Config
{
return true;
}
@Range(
min = 0,
max = 16
)
@ConfigItem(
keyName = "anisotropicFilteringLevel",
name = "Anisotropic Filtering",
description = "Configures the anisotropic filtering level.",
position = 7
)
default int anisotropicFilteringLevel()
{
return 0;
}
}

View File

@@ -51,7 +51,7 @@ class TextureManager
int textureArrayId = GLUtil.glGenTexture(gl);
gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, textureArrayId);
gl.glTexStorage3D(gl.GL_TEXTURE_2D_ARRAY, 1, gl.GL_RGBA8, TEXTURE_SIZE, TEXTURE_SIZE, textures.length);
gl.glTexStorage3D(gl.GL_TEXTURE_2D_ARRAY, 8, gl.GL_RGBA8, TEXTURE_SIZE, TEXTURE_SIZE, textures.length);
gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);
@@ -68,11 +68,40 @@ class TextureManager
gl.glActiveTexture(gl.GL_TEXTURE1);
gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, textureArrayId);
gl.glGenerateMipmap(gl.GL_TEXTURE_2D_ARRAY);
gl.glActiveTexture(gl.GL_TEXTURE0);
return textureArrayId;
}
void setAnisotropicFilteringLevel(int textureArrayId, int level, GL4 gl)
{
gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, textureArrayId);
//level = 0 means no mipmaps and no anisotropic filtering
if (level == 0)
{
gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
}
//level = 1 means with mipmaps but without anisotropic filtering GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT defaults to 1.0 which is off
//level > 1 enables anisotropic filtering. It's up to the vendor what the values mean
//Even if anisotropic filtering isn't supported, mipmaps will be enabled with any level >= 1
else
{
// Set on GL_NEAREST_MIPMAP_LINEAR (bilinear filtering with mipmaps) since the pixel nature of the game means that nearest filtering
// looks best for objects up close but allows linear filtering to resolve possible aliasing and noise with mipmaps from far away objects.
gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST_MIPMAP_LINEAR);
}
if (gl.isExtensionAvailable("GL_EXT_texture_filter_anisotropic"))
{
final float maxSamples = GLUtil.glGetFloat(gl, gl.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
//Clamp from 1 to max GL says it supports.
final float anisoLevel = Math.max(1, Math.min(maxSamples, level));
gl.glTexParameterf(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoLevel);
}
}
void freeTextureArray(GL4 gl, int textureArrayId)
{
GLUtil.glDeleteTexture(gl, textureArrayId);