Add GPU renderer

This commit is contained in:
Adam
2018-11-15 09:19:37 -05:00
parent 3c84d98638
commit 3f5e273349
74 changed files with 6201 additions and 22 deletions

View File

@@ -26,9 +26,13 @@ package net.runelite.mixins;
import net.runelite.api.Perspective;
import net.runelite.api.Renderable;
import net.runelite.api.SceneTileModel;
import net.runelite.api.SceneTilePaint;
import net.runelite.api.Tile;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.hooks.DrawCallbacks;
import net.runelite.api.mixins.Copy;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Replace;
import net.runelite.api.mixins.Shadow;
@@ -37,26 +41,45 @@ import net.runelite.rs.api.RSDecorativeObject;
import net.runelite.rs.api.RSGroundObject;
import net.runelite.rs.api.RSItemLayer;
import net.runelite.rs.api.RSScene;
import net.runelite.rs.api.RSSceneTileModel;
import net.runelite.rs.api.RSTile;
import net.runelite.rs.api.RSWallObject;
@Mixin(RSScene.class)
public abstract class RSSceneMixin implements RSScene
{
private static final int MAX_DISTANCE = 25;
private static final int DEFAULT_DISTANCE = 25;
private static final int MAX_DISTANCE = 90;
private static final int PITCH_LOWER_LIMIT = 128;
private static final int PITCH_UPPER_LIMIT = 383;
private static final int MAX_TARGET_DISTANCE = 45;
@Shadow("clientInstance")
private static RSClient client;
static RSClient client;
@Shadow("pitchRelaxEnabled")
private static boolean pitchRelaxEnabled;
@Inject
private static int[] tmpX = new int[6];
@Inject
private static int[] tmpY = new int[6];
@Inject
private static int rl$drawDistance;
@Replace("drawScene")
void rl$drawScene(int cameraX, int cameraY, int cameraZ, int cameraPitch, int cameraYaw, int plane)
{
final DrawCallbacks drawCallbacks = client.getDrawCallbacks();
if (drawCallbacks != null)
{
drawCallbacks.drawScene(cameraX, cameraY, cameraZ, cameraPitch, cameraYaw, plane);
}
final int maxX = getMaxX();
final int maxY = getMaxY();
final int maxZ = getMaxZ();
@@ -64,7 +87,8 @@ public abstract class RSSceneMixin implements RSScene
final int minLevel = getMinLevel();
final RSTile[][][] tiles = getTiles();
final int distance = MAX_DISTANCE;
final boolean isGpu = client.isGpu();
final int distance = isGpu ? rl$drawDistance : DEFAULT_DISTANCE;
if (cameraX < 0)
{
@@ -168,7 +192,8 @@ public abstract class RSSceneMixin implements RSScene
{
if (tile.getPhysicalLevel() <= plane
&& (renderArea[x - screenCenterX + MAX_DISTANCE][y - screenCenterZ + MAX_DISTANCE]
|| tileHeights[z][x][y] - cameraY >= 2000))
|| tileHeights[z][x][y] - cameraY >= 2000
|| isGpu))
{
tile.setDraw(true);
tile.setVisible(true);
@@ -402,13 +427,271 @@ public abstract class RSSceneMixin implements RSScene
@Replace("drawTileUnderlay")
public void rl$drawTileUnderlay(SceneTilePaint tile, int z, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y)
{
if (!client.isGpu())
{
try
{
rs$drawTileUnderlay(tile, z, pitchSin, pitchCos, yawSin, yawCos, x, y);
}
catch (Exception ex)
{
client.getLogger().warn("error during tile underlay rendering", ex);
}
return;
}
final DrawCallbacks drawCallbacks = client.getDrawCallbacks();
if (drawCallbacks == null)
{
return;
}
try
{
rs$drawTileUnderlay(tile, z, pitchSin, pitchCos, yawSin, yawCos, x, y);
final int[][][] tileHeights = getTileHeights();
final int cameraX2 = client.getCameraX2();
final int cameraY2 = client.getCameraY2();
final int cameraZ2 = client.getCameraZ2();
final int zoom = client.get3dZoom();
final int centerX = client.getCenterX();
final int centerY = client.getCenterY();
final int mouseX2 = client.getMouseX2();
final int mouseY2 = client.getMouseY2();
final boolean checkClick = client.isCheckClick();
int var9;
int var10 = var9 = (x << 7) - cameraX2;
int var11;
int var12 = var11 = (y << 7) - cameraZ2;
int var13;
int var14 = var13 = var10 + 128;
int var15;
int var16 = var15 = var12 + 128;
int var17 = tileHeights[z][x][y] - cameraY2;
int var18 = tileHeights[z][x + 1][y] - cameraY2;
int var19 = tileHeights[z][x + 1][y + 1] - cameraY2;
int var20 = tileHeights[z][x][y + 1] - cameraY2;
int var21 = var10 * yawCos + yawSin * var12 >> 16;
var12 = var12 * yawCos - yawSin * var10 >> 16;
var10 = var21;
var21 = var17 * pitchCos - pitchSin * var12 >> 16;
var12 = pitchSin * var17 + var12 * pitchCos >> 16;
var17 = var21;
if (var12 >= 50)
{
var21 = var14 * yawCos + yawSin * var11 >> 16;
var11 = var11 * yawCos - yawSin * var14 >> 16;
var14 = var21;
var21 = var18 * pitchCos - pitchSin * var11 >> 16;
var11 = pitchSin * var18 + var11 * pitchCos >> 16;
var18 = var21;
if (var11 >= 50)
{
var21 = var13 * yawCos + yawSin * var16 >> 16;
var16 = var16 * yawCos - yawSin * var13 >> 16;
var13 = var21;
var21 = var19 * pitchCos - pitchSin * var16 >> 16;
var16 = pitchSin * var19 + var16 * pitchCos >> 16;
var19 = var21;
if (var16 >= 50)
{
var21 = var9 * yawCos + yawSin * var15 >> 16;
var15 = var15 * yawCos - yawSin * var9 >> 16;
var9 = var21;
var21 = var20 * pitchCos - pitchSin * var15 >> 16;
var15 = pitchSin * var20 + var15 * pitchCos >> 16;
if (var15 >= 50)
{
int dy = var10 * zoom / var12 + centerX;
int dx = var17 * zoom / var12 + centerY;
int cy = var14 * zoom / var11 + centerX;
int cx = var18 * zoom / var11 + centerY;
int ay = var13 * zoom / var16 + centerX;
int ax = var19 * zoom / var16 + centerY;
int by = var9 * zoom / var15 + centerX;
int bx = var21 * zoom / var15 + centerY;
drawCallbacks.drawScenePaint(0, pitchSin, pitchCos, yawSin, yawCos,
-cameraX2, -cameraY2, -cameraZ2,
tile, z, x, y,
zoom, centerX, centerY);
if ((ay - by) * (cx - bx) - (ax - bx) * (cy - by) > 0)
{
if (checkClick && client.containsBounds(mouseX2, mouseY2, ax, bx, cx, ay, by, cy))
{
setTargetTile(x, y);
}
}
if ((dy - cy) * (bx - cx) - (dx - cx) * (by - cy) > 0)
{
if (checkClick && client.containsBounds(mouseX2, mouseY2, dx, cx, bx, dy, cy, by))
{
setTargetTile(x, y);
}
}
}
}
}
}
}
catch (Exception ex)
{
client.getLogger().warn("error during tile underlay rendering", ex);
client.getLogger().warn("error during underlay rendering", ex);
}
}
@Copy("drawTileOverlay")
abstract public void rs$drawTileOverlay(SceneTileModel tile, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y);
@Replace("drawTileOverlay")
public void rl$drawTileOverlay(SceneTileModel tile, int pitchSin, int pitchCos, int yawSin, int yawCos, int tileX, int tileY)
{
if (!client.isGpu())
{
rs$drawTileOverlay(tile, pitchSin, pitchCos, yawSin, yawCos, tileX, tileY);
return;
}
final DrawCallbacks drawCallbacks = client.getDrawCallbacks();
if (drawCallbacks == null)
{
return;
}
try
{
final int cameraX2 = client.getCameraX2();
final int cameraY2 = client.getCameraY2();
final int cameraZ2 = client.getCameraZ2();
final int zoom = client.get3dZoom();
final int centerX = client.getCenterX();
final int centerY = client.getCenterY();
drawCallbacks.drawSceneModel(0, pitchSin, pitchCos, yawSin, yawCos, -cameraX2, -cameraY2, -cameraZ2,
tile, client.getPlane(), tileX, tileY,
zoom, centerX, centerY);
final boolean checkClick = client.isCheckClick();
if (!checkClick)
{
return;
}
RSSceneTileModel sceneTileModel = (RSSceneTileModel) tile;
final int[] faceX = sceneTileModel.getFaceX();
final int[] faceY = sceneTileModel.getFaceY();
final int[] faceZ = sceneTileModel.getFaceZ();
final int[] vertexX = sceneTileModel.getVertexX();
final int[] vertexY = sceneTileModel.getVertexY();
final int[] vertexZ = sceneTileModel.getVertexZ();
final int vertexCount = vertexX.length;
final int faceCount = faceX.length;
final int mouseX2 = client.getMouseX2();
final int mouseY2 = client.getMouseY2();
for (int i = 0; i < vertexCount; ++i)
{
int vx = vertexX[i] - cameraX2;
int vy = vertexY[i] - cameraY2;
int vz = vertexZ[i] - cameraZ2;
int rotA = vz * yawSin + vx * yawCos >> 16;
int rotB = vz * yawCos - vx * yawSin >> 16;
int var13 = vy * pitchCos - rotB * pitchSin >> 16;
int var12 = vy * pitchSin + rotB * pitchCos >> 16;
if (var12 < 50)
{
return;
}
int ax = rotA * zoom / var12 + centerX;
int ay = var13 * zoom / var12 + centerY;
tmpX[i] = ax;
tmpY[i] = ay;
}
for (int i = 0; i < faceCount; ++i)
{
int va = faceX[i];
int vb = faceY[i];
int vc = faceZ[i];
int x1 = tmpX[va];
int x2 = tmpX[vb];
int x3 = tmpX[vc];
int y1 = tmpY[va];
int y2 = tmpY[vb];
int y3 = tmpY[vc];
if ((x1 - x2) * (y3 - y2) - (y1 - y2) * (x3 - x2) > 0)
{
if (client.containsBounds(mouseX2, mouseY2, y1, y2, y3, x1, x2, x3))
{
setTargetTile(tileX, tileY);
break;
}
}
}
}
catch (Exception ex)
{
client.getLogger().warn("error during overlay rendering", ex);
}
}
@Inject
@Override
public int getDrawDistance()
{
return rl$drawDistance;
}
@Inject
@Override
public void setDrawDistance(int drawDistance)
{
rl$drawDistance = drawDistance;
}
@Inject
static void setTargetTile(int targetX, int targetY)
{
final LocalPoint current = client.getLocalPlayer().getLocalLocation();
// Limit walk distance - https://math.stackexchange.com/a/85582
final int a = current.getSceneX();
final int b = current.getSceneY();
final int c = targetX;
final int d = targetY;
final int r = MAX_TARGET_DISTANCE;
final int t = (int) Math.hypot(a - c, b - d) - r;
int x = targetX;
int y = targetY;
if (t > 0)
{
x = (r * c + t * a) / (r + t);
y = (r * d + t * b) / (r + t);
}
client.setSelectedSceneTileX(x);
client.setSelectedSceneTileY(y);
}
}