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 int textureArrayId;
|
||||||
|
|
||||||
private final GLBuffer uniformBuffer = new GLBuffer();
|
private final GLBuffer uniformBuffer = new GLBuffer();
|
||||||
private final float[] textureOffsets = new float[256];
|
|
||||||
|
|
||||||
private GpuIntBuffer vertexBuffer;
|
private GpuIntBuffer vertexBuffer;
|
||||||
private GpuFloatBuffer uvBuffer;
|
private GpuFloatBuffer uvBuffer;
|
||||||
@@ -291,12 +290,13 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
private int uniTexTargetDimensions;
|
private int uniTexTargetDimensions;
|
||||||
private int uniUiAlphaOverlay;
|
private int uniUiAlphaOverlay;
|
||||||
private int uniTextures;
|
private int uniTextures;
|
||||||
private int uniTextureOffsets;
|
private int uniTextureAnimations;
|
||||||
private int uniBlockSmall;
|
private int uniBlockSmall;
|
||||||
private int uniBlockLarge;
|
private int uniBlockLarge;
|
||||||
private int uniBlockMain;
|
private int uniBlockMain;
|
||||||
private int uniSmoothBanding;
|
private int uniSmoothBanding;
|
||||||
private int uniTextureLightMode;
|
private int uniTextureLightMode;
|
||||||
|
private int uniTick;
|
||||||
|
|
||||||
private int needsReset;
|
private int needsReset;
|
||||||
|
|
||||||
@@ -665,6 +665,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
uniDrawDistance = gl.glGetUniformLocation(glProgram, "drawDistance");
|
uniDrawDistance = gl.glGetUniformLocation(glProgram, "drawDistance");
|
||||||
uniColorBlindMode = gl.glGetUniformLocation(glProgram, "colorBlindMode");
|
uniColorBlindMode = gl.glGetUniformLocation(glProgram, "colorBlindMode");
|
||||||
uniTextureLightMode = gl.glGetUniformLocation(glProgram, "textureLightMode");
|
uniTextureLightMode = gl.glGetUniformLocation(glProgram, "textureLightMode");
|
||||||
|
uniTick = gl.glGetUniformLocation(glProgram, "tick");
|
||||||
|
|
||||||
uniTex = gl.glGetUniformLocation(glUiProgram, "tex");
|
uniTex = gl.glGetUniformLocation(glUiProgram, "tex");
|
||||||
uniTexSamplingMode = gl.glGetUniformLocation(glUiProgram, "samplingMode");
|
uniTexSamplingMode = gl.glGetUniformLocation(glUiProgram, "samplingMode");
|
||||||
@@ -673,7 +674,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
uniUiColorBlindMode = gl.glGetUniformLocation(glUiProgram, "colorBlindMode");
|
uniUiColorBlindMode = gl.glGetUniformLocation(glUiProgram, "colorBlindMode");
|
||||||
uniUiAlphaOverlay = gl.glGetUniformLocation(glUiProgram, "alphaOverlay");
|
uniUiAlphaOverlay = gl.glGetUniformLocation(glUiProgram, "alphaOverlay");
|
||||||
uniTextures = gl.glGetUniformLocation(glProgram, "textures");
|
uniTextures = gl.glGetUniformLocation(glProgram, "textures");
|
||||||
uniTextureOffsets = gl.glGetUniformLocation(glProgram, "textureOffsets");
|
uniTextureAnimations = gl.glGetUniformLocation(glProgram, "textureAnimations");
|
||||||
|
|
||||||
uniBlockSmall = gl.glGetUniformBlockIndex(glSmallComputeProgram, "uniforms");
|
uniBlockSmall = gl.glGetUniformBlockIndex(glSmallComputeProgram, "uniforms");
|
||||||
uniBlockLarge = gl.glGetUniformBlockIndex(glComputeProgram, "uniforms");
|
uniBlockLarge = gl.glGetUniformBlockIndex(glComputeProgram, "uniforms");
|
||||||
@@ -1222,18 +1223,25 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT);
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// Draw 3d scene
|
// Draw 3d scene
|
||||||
final TextureProvider textureProvider = client.getTextureProvider();
|
|
||||||
final GameState gameState = client.getGameState();
|
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)
|
if (textureArrayId == -1)
|
||||||
{
|
{
|
||||||
// lazy init textures as they may not be loaded at plugin start.
|
// 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.
|
// this will return -1 and retry if not all textures are loaded yet, too.
|
||||||
textureArrayId = textureManager.initTextureArray(textureProvider, gl);
|
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 renderWidthOff = viewportOffsetX;
|
||||||
int renderHeightOff = viewportOffsetY;
|
int renderHeightOff = viewportOffsetY;
|
||||||
int renderCanvasHeight = canvasHeight;
|
int renderCanvasHeight = canvasHeight;
|
||||||
@@ -1285,6 +1293,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
gl.glUniform1f(uniSmoothBanding, config.smoothBanding() ? 0f : 1f);
|
gl.glUniform1f(uniSmoothBanding, config.smoothBanding() ? 0f : 1f);
|
||||||
gl.glUniform1i(uniColorBlindMode, config.colorBlindMode().ordinal());
|
gl.glUniform1i(uniColorBlindMode, config.colorBlindMode().ordinal());
|
||||||
gl.glUniform1f(uniTextureLightMode, config.brightTextures() ? 1f : 0f);
|
gl.glUniform1f(uniTextureLightMode, config.brightTextures() ? 1f : 0f);
|
||||||
|
gl.glUniform1i(uniTick, client.getGameCycle());
|
||||||
|
|
||||||
// Calculate projection matrix
|
// Calculate projection matrix
|
||||||
Matrix4 projectionMatrix = new Matrix4();
|
Matrix4 projectionMatrix = new Matrix4();
|
||||||
@@ -1295,24 +1304,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
projectionMatrix.translate(-client.getCameraX2(), -client.getCameraY2(), -client.getCameraZ2());
|
projectionMatrix.translate(-client.getCameraX2(), -client.getCameraY2(), -client.getCameraZ2());
|
||||||
gl.glUniformMatrix4fv(uniProjectionMatrix, 1, false, projectionMatrix.getMatrix(), 0);
|
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
|
// Bind uniforms
|
||||||
gl.glUniformBlockBinding(glProgram, uniBlockMain, 0);
|
gl.glUniformBlockBinding(glProgram, uniBlockMain, 0);
|
||||||
gl.glUniform1i(uniTextures, 1); // texture sampler array is bound to texture1
|
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
|
// 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.
|
// to have logic to disregard culled faces in the priority depth testing.
|
||||||
@@ -1518,7 +1512,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
@Override
|
@Override
|
||||||
public void animate(Texture texture, int diff)
|
public void animate(Texture texture, int diff)
|
||||||
{
|
{
|
||||||
textureManager.animate(texture, diff);
|
// texture animation happens on gpu
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -35,9 +35,6 @@ import net.runelite.api.TextureProvider;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
class TextureManager
|
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;
|
private static final int TEXTURE_SIZE = 128;
|
||||||
|
|
||||||
int initTextureArray(TextureProvider textureProvider, GL4 gl)
|
int initTextureArray(TextureProvider textureProvider, GL4 gl)
|
||||||
@@ -207,64 +204,40 @@ class TextureManager
|
|||||||
return pixels;
|
return pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
float[] computeTextureAnimations(TextureProvider textureProvider)
|
||||||
* Animate the given texture
|
|
||||||
*
|
|
||||||
* @param texture
|
|
||||||
* @param diff Number of elapsed client ticks since last animation
|
|
||||||
*/
|
|
||||||
void animate(Texture texture, int diff)
|
|
||||||
{
|
{
|
||||||
final int[] pixels = texture.getPixels();
|
Texture[] textures = textureProvider.getTextures();
|
||||||
if (pixels == null)
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return anims;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
uniform sampler2DArray textures;
|
uniform sampler2DArray textures;
|
||||||
uniform vec2 textureOffsets[128];
|
|
||||||
uniform float brightness;
|
uniform float brightness;
|
||||||
uniform float smoothBanding;
|
uniform float smoothBanding;
|
||||||
uniform vec4 fogColor;
|
uniform vec4 fogColor;
|
||||||
@@ -49,9 +48,7 @@ void main() {
|
|||||||
if (textureId > 0) {
|
if (textureId > 0) {
|
||||||
int textureIdx = textureId - 1;
|
int textureIdx = textureId - 1;
|
||||||
|
|
||||||
vec2 animatedUv = fUv + textureOffsets[textureIdx];
|
vec4 textureColor = texture(textures, vec3(fUv, float(textureIdx)));
|
||||||
|
|
||||||
vec4 textureColor = texture(textures, vec3(animatedUv, float(textureIdx)));
|
|
||||||
vec4 textureColorBrightness = pow(textureColor, vec4(brightness, brightness, brightness, 1.0f));
|
vec4 textureColorBrightness = pow(textureColor, vec4(brightness, brightness, brightness, 1.0f));
|
||||||
|
|
||||||
// textured triangles hsl is a 7 bit lightness 2-126
|
// textured triangles hsl is a 7 bit lightness 2-126
|
||||||
|
|||||||
@@ -27,6 +27,10 @@
|
|||||||
|
|
||||||
#define TILE_SIZE 128
|
#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_MIN TILE_SIZE
|
||||||
#define FOG_SCENE_EDGE_MAX (103 * TILE_SIZE)
|
#define FOG_SCENE_EDGE_MAX (103 * TILE_SIZE)
|
||||||
#define FOG_CORNER_ROUNDING 1.5
|
#define FOG_CORNER_ROUNDING 1.5
|
||||||
@@ -52,6 +56,8 @@ uniform int useFog;
|
|||||||
uniform int fogDepth;
|
uniform int fogDepth;
|
||||||
uniform int drawDistance;
|
uniform int drawDistance;
|
||||||
uniform mat4 projectionMatrix;
|
uniform mat4 projectionMatrix;
|
||||||
|
uniform vec2 textureAnimations[128];
|
||||||
|
uniform int tick;
|
||||||
|
|
||||||
out vec4 Color;
|
out vec4 Color;
|
||||||
noperspective centroid out float fHsl;
|
noperspective centroid out float fHsl;
|
||||||
@@ -77,8 +83,17 @@ void main()
|
|||||||
gl_Position = projectionMatrix * vec4(vertex, 1.f);
|
gl_Position = projectionMatrix * vec4(vertex, 1.f);
|
||||||
Color = vec4(rgb, 1.f - a);
|
Color = vec4(rgb, 1.f - a);
|
||||||
fHsl = float(hsl);
|
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 fogWest = max(FOG_SCENE_EDGE_MIN, cameraX - drawDistance);
|
||||||
int fogEast = min(FOG_SCENE_EDGE_MAX, cameraX + drawDistance - TILE_SIZE);
|
int fogEast = min(FOG_SCENE_EDGE_MAX, cameraX + drawDistance - TILE_SIZE);
|
||||||
|
|||||||
Reference in New Issue
Block a user