gpu: move texture animation to gpu
This commit is contained in:
@@ -223,7 +223,6 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
private int textureArrayId;
|
||||
|
||||
private final GLBuffer uniformBuffer = new GLBuffer();
|
||||
private final float[] textureOffsets = new float[256];
|
||||
|
||||
private GpuIntBuffer vertexBuffer;
|
||||
private GpuFloatBuffer uvBuffer;
|
||||
@@ -291,12 +290,13 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
private int uniTexTargetDimensions;
|
||||
private int uniUiAlphaOverlay;
|
||||
private int uniTextures;
|
||||
private int uniTextureOffsets;
|
||||
private int uniTextureAnimations;
|
||||
private int uniBlockSmall;
|
||||
private int uniBlockLarge;
|
||||
private int uniBlockMain;
|
||||
private int uniSmoothBanding;
|
||||
private int uniTextureLightMode;
|
||||
private int uniTick;
|
||||
|
||||
private int needsReset;
|
||||
|
||||
@@ -665,6 +665,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
uniDrawDistance = gl.glGetUniformLocation(glProgram, "drawDistance");
|
||||
uniColorBlindMode = gl.glGetUniformLocation(glProgram, "colorBlindMode");
|
||||
uniTextureLightMode = gl.glGetUniformLocation(glProgram, "textureLightMode");
|
||||
uniTick = gl.glGetUniformLocation(glProgram, "tick");
|
||||
|
||||
uniTex = gl.glGetUniformLocation(glUiProgram, "tex");
|
||||
uniTexSamplingMode = gl.glGetUniformLocation(glUiProgram, "samplingMode");
|
||||
@@ -673,7 +674,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
uniUiColorBlindMode = gl.glGetUniformLocation(glUiProgram, "colorBlindMode");
|
||||
uniUiAlphaOverlay = gl.glGetUniformLocation(glUiProgram, "alphaOverlay");
|
||||
uniTextures = gl.glGetUniformLocation(glProgram, "textures");
|
||||
uniTextureOffsets = gl.glGetUniformLocation(glProgram, "textureOffsets");
|
||||
uniTextureAnimations = gl.glGetUniformLocation(glProgram, "textureAnimations");
|
||||
|
||||
uniBlockSmall = gl.glGetUniformBlockIndex(glSmallComputeProgram, "uniforms");
|
||||
uniBlockLarge = gl.glGetUniformBlockIndex(glComputeProgram, "uniforms");
|
||||
@@ -1222,18 +1223,25 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw 3d scene
|
||||
final TextureProvider textureProvider = client.getTextureProvider();
|
||||
final GameState gameState = client.getGameState();
|
||||
if (textureProvider != null && gameState.getState() >= GameState.LOADING.getState())
|
||||
if (gameState.getState() >= GameState.LOADING.getState())
|
||||
{
|
||||
final TextureProvider textureProvider = client.getTextureProvider();
|
||||
if (textureArrayId == -1)
|
||||
{
|
||||
// lazy init textures as they may not be loaded at plugin start.
|
||||
// this will return -1 and retry if not all textures are loaded yet, too.
|
||||
textureArrayId = textureManager.initTextureArray(textureProvider, gl);
|
||||
if (textureArrayId > -1)
|
||||
{
|
||||
// if texture upload is successful, compute and set texture animations
|
||||
float[] texAnims = textureManager.computeTextureAnimations(textureProvider);
|
||||
gl.glUseProgram(glProgram);
|
||||
gl.glUniform2fv(uniTextureAnimations, texAnims.length, texAnims, 0);
|
||||
gl.glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
||||
final Texture[] textures = textureProvider.getTextures();
|
||||
int renderWidthOff = viewportOffsetX;
|
||||
int renderHeightOff = viewportOffsetY;
|
||||
int renderCanvasHeight = canvasHeight;
|
||||
@@ -1285,6 +1293,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
gl.glUniform1f(uniSmoothBanding, config.smoothBanding() ? 0f : 1f);
|
||||
gl.glUniform1i(uniColorBlindMode, config.colorBlindMode().ordinal());
|
||||
gl.glUniform1f(uniTextureLightMode, config.brightTextures() ? 1f : 0f);
|
||||
gl.glUniform1i(uniTick, client.getGameCycle());
|
||||
|
||||
// Calculate projection matrix
|
||||
Matrix4 projectionMatrix = new Matrix4();
|
||||
@@ -1295,24 +1304,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
projectionMatrix.translate(-client.getCameraX2(), -client.getCameraY2(), -client.getCameraZ2());
|
||||
gl.glUniformMatrix4fv(uniProjectionMatrix, 1, false, projectionMatrix.getMatrix(), 0);
|
||||
|
||||
for (int id = 0; id < textures.length; ++id)
|
||||
{
|
||||
Texture texture = textures[id];
|
||||
if (texture == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
textureProvider.load(id); // trips the texture load flag which lets textures animate
|
||||
|
||||
textureOffsets[id * 2] = texture.getU();
|
||||
textureOffsets[id * 2 + 1] = texture.getV();
|
||||
}
|
||||
|
||||
// Bind uniforms
|
||||
gl.glUniformBlockBinding(glProgram, uniBlockMain, 0);
|
||||
gl.glUniform1i(uniTextures, 1); // texture sampler array is bound to texture1
|
||||
gl.glUniform2fv(uniTextureOffsets, textureOffsets.length, textureOffsets, 0);
|
||||
|
||||
// We just allow the GL to do face culling. Note this requires the priority renderer
|
||||
// to have logic to disregard culled faces in the priority depth testing.
|
||||
@@ -1518,7 +1512,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
@Override
|
||||
public void animate(Texture texture, int diff)
|
||||
{
|
||||
textureManager.animate(texture, diff);
|
||||
// texture animation happens on gpu
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -35,9 +35,6 @@ import net.runelite.api.TextureProvider;
|
||||
@Slf4j
|
||||
class TextureManager
|
||||
{
|
||||
private static final float PERC_64 = 1f / 64f;
|
||||
private static final float PERC_128 = 1f / 128f;
|
||||
|
||||
private static final int TEXTURE_SIZE = 128;
|
||||
|
||||
int initTextureArray(TextureProvider textureProvider, GL4 gl)
|
||||
@@ -207,64 +204,40 @@ class TextureManager
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the given texture
|
||||
*
|
||||
* @param texture
|
||||
* @param diff Number of elapsed client ticks since last animation
|
||||
*/
|
||||
void animate(Texture texture, int diff)
|
||||
float[] computeTextureAnimations(TextureProvider textureProvider)
|
||||
{
|
||||
final int[] pixels = texture.getPixels();
|
||||
if (pixels == null)
|
||||
Texture[] textures = textureProvider.getTextures();
|
||||
float[] anims = new float[TEXTURE_SIZE * 2];
|
||||
int idx = 0;
|
||||
for (Texture texture : textures)
|
||||
{
|
||||
return;
|
||||
if (texture != null)
|
||||
{
|
||||
float u = 0f, v = 0f;
|
||||
switch (texture.getAnimationDirection())
|
||||
{
|
||||
case 1:
|
||||
v = -1f;
|
||||
break;
|
||||
case 3:
|
||||
v = 1f;
|
||||
break;
|
||||
case 2:
|
||||
u = -1f;
|
||||
break;
|
||||
case 4:
|
||||
u = 1f;
|
||||
break;
|
||||
}
|
||||
|
||||
int speed = texture.getAnimationSpeed();
|
||||
u *= speed;
|
||||
v *= speed;
|
||||
|
||||
anims[idx++] = u;
|
||||
anims[idx++] = v;
|
||||
}
|
||||
}
|
||||
|
||||
final int animationSpeed = texture.getAnimationSpeed();
|
||||
final float uvdiff = pixels.length == 4096 ? PERC_64 : PERC_128;
|
||||
|
||||
float u = texture.getU();
|
||||
float v = texture.getV();
|
||||
|
||||
int offset = animationSpeed * diff;
|
||||
float d = (float) offset * uvdiff;
|
||||
|
||||
switch (texture.getAnimationDirection())
|
||||
{
|
||||
case 1:
|
||||
v -= d;
|
||||
if (v < 0f)
|
||||
{
|
||||
v += 1f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
v += d;
|
||||
if (v > 1f)
|
||||
{
|
||||
v -= 1f;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
u -= d;
|
||||
if (u < 0f)
|
||||
{
|
||||
u += 1f;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
u += d;
|
||||
if (u > 1f)
|
||||
{
|
||||
u -= 1f;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
texture.setU(u);
|
||||
texture.setV(v);
|
||||
return anims;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#version 330
|
||||
|
||||
uniform sampler2DArray textures;
|
||||
uniform vec2 textureOffsets[128];
|
||||
uniform float brightness;
|
||||
uniform float smoothBanding;
|
||||
uniform vec4 fogColor;
|
||||
@@ -49,9 +48,7 @@ void main() {
|
||||
if (textureId > 0) {
|
||||
int textureIdx = textureId - 1;
|
||||
|
||||
vec2 animatedUv = fUv + textureOffsets[textureIdx];
|
||||
|
||||
vec4 textureColor = texture(textures, vec3(animatedUv, float(textureIdx)));
|
||||
vec4 textureColor = texture(textures, vec3(fUv, float(textureIdx)));
|
||||
vec4 textureColorBrightness = pow(textureColor, vec4(brightness, brightness, brightness, 1.0f));
|
||||
|
||||
// textured triangles hsl is a 7 bit lightness 2-126
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
#define TILE_SIZE 128
|
||||
|
||||
// smallest unit of the texture which can be moved per tick. textures are all
|
||||
// 128x128px - so this is equivalent to +1px
|
||||
#define TEXTURE_ANIM_UNIT (1.0f / 128.0f)
|
||||
|
||||
#define FOG_SCENE_EDGE_MIN TILE_SIZE
|
||||
#define FOG_SCENE_EDGE_MAX (103 * TILE_SIZE)
|
||||
#define FOG_CORNER_ROUNDING 1.5
|
||||
@@ -52,6 +56,8 @@ uniform int useFog;
|
||||
uniform int fogDepth;
|
||||
uniform int drawDistance;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform vec2 textureAnimations[128];
|
||||
uniform int tick;
|
||||
|
||||
out vec4 Color;
|
||||
noperspective centroid out float fHsl;
|
||||
@@ -77,8 +83,17 @@ void main()
|
||||
gl_Position = projectionMatrix * vec4(vertex, 1.f);
|
||||
Color = vec4(rgb, 1.f - a);
|
||||
fHsl = float(hsl);
|
||||
textureId = int(uv.x);
|
||||
fUv = uv.yz;
|
||||
|
||||
int textureIdx = int(uv.x); // the texture id + 1
|
||||
vec2 textureUv = uv.yz;
|
||||
|
||||
vec2 textureAnim = vec2(0);
|
||||
if (textureIdx > 0) {
|
||||
textureAnim = textureAnimations[textureIdx - 1];
|
||||
}
|
||||
|
||||
textureId = textureIdx;
|
||||
fUv = textureUv + tick * textureAnim * TEXTURE_ANIM_UNIT;
|
||||
|
||||
int fogWest = max(FOG_SCENE_EDGE_MIN, cameraX - drawDistance);
|
||||
int fogEast = min(FOG_SCENE_EDGE_MAX, cameraX + drawDistance - TILE_SIZE);
|
||||
|
||||
Reference in New Issue
Block a user