diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index 84ab41f167..774596073c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -194,6 +194,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks private int vaoHandle; private int interfaceTexture; + private int interfacePbo; private int vaoUiHandle; private int vboUiHandle; @@ -726,6 +727,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks private void initInterfaceTexture() { + interfacePbo = glGenBuffers(gl); + interfaceTexture = glGenTexture(gl); gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE); @@ -737,6 +740,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks private void shutdownInterfaceTexture() { + glDeleteBuffer(gl, interfacePbo); glDeleteTexture(gl, interfaceTexture); interfaceTexture = -1; } @@ -1037,15 +1041,19 @@ public class GpuPlugin extends Plugin implements DrawCallbacks invokeOnMainThread(() -> drawFrame(overlayColor)); } - private void resize(int canvasWidth, int canvasHeight, int viewportWidth, int viewportHeight) + private void prepareInterfaceTexture(int canvasWidth, int canvasHeight) { if (canvasWidth != lastCanvasWidth || canvasHeight != lastCanvasHeight) { lastCanvasWidth = canvasWidth; lastCanvasHeight = canvasHeight; + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, interfacePbo); + gl.glBufferData(gl.GL_PIXEL_UNPACK_BUFFER, canvasWidth * canvasHeight * 4L, null, gl.GL_STREAM_DRAW); + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0); + gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); - gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, canvasWidth, canvasHeight, 0, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, null); + gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, canvasWidth, canvasHeight, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, null); gl.glBindTexture(gl.GL_TEXTURE_2D, 0); if (OSType.getOSType() == OSType.MacOS && glDrawable instanceof GLFBODrawable) @@ -1058,6 +1066,21 @@ public class GpuPlugin extends Plugin implements DrawCallbacks glfboDrawable.resetSize(gl); } } + + final BufferProvider bufferProvider = client.getBufferProvider(); + final int[] pixels = bufferProvider.getPixels(); + final int width = bufferProvider.getWidth(); + final int height = bufferProvider.getHeight(); + + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, interfacePbo); + gl.glMapBuffer(gl.GL_PIXEL_UNPACK_BUFFER, gl.GL_WRITE_ONLY) + .asIntBuffer() + .put(pixels, 0, width * height); + gl.glUnmapBuffer(gl.GL_PIXEL_UNPACK_BUFFER); + gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); + gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, width, height, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, 0); + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0); + gl.glBindTexture(gl.GL_TEXTURE_2D, 0); } private void drawFrame(int overlayColor) @@ -1072,7 +1095,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks final int viewportHeight = client.getViewportHeight(); final int viewportWidth = client.getViewportWidth(); - resize(canvasWidth, canvasHeight, viewportWidth, viewportHeight); + prepareInterfaceTexture(canvasWidth, canvasHeight); // Setup anti-aliasing final AntiAliasingMode antiAliasingMode = config.antiAliasingMode(); @@ -1312,25 +1335,10 @@ public class GpuPlugin extends Plugin implements DrawCallbacks private void drawUi(final int overlayColor, final int canvasHeight, final int canvasWidth) { - final BufferProvider bufferProvider = client.getBufferProvider(); - final int[] pixels = bufferProvider.getPixels(); - final int width = bufferProvider.getWidth(); - final int height = bufferProvider.getHeight(); - gl.glEnable(gl.GL_BLEND); - - vertexBuffer.clear(); // reuse vertex buffer for interface - vertexBuffer.ensureCapacity(pixels.length); - - IntBuffer interfaceBuffer = vertexBuffer.getBuffer(); - interfaceBuffer.put(pixels); - vertexBuffer.flip(); - gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA); gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); - gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, width, height, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, interfaceBuffer); - // Use the texture bound in the first pass final UIScalingMode uiScalingMode = config.uiScalingMode(); gl.glUseProgram(glUiProgram); @@ -1626,16 +1634,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks boolean hasUv = model.getFaceTextures() != null; - int faces = Math.min(MAX_TRIANGLE, model.getTrianglesCount()); - vertexBuffer.ensureCapacity(12 * faces); - uvBuffer.ensureCapacity(12 * faces); - int len = 0; - for (int i = 0; i < faces; ++i) - { - len += sceneUploader.pushFace(model, i, false, vertexBuffer, uvBuffer, 0, 0, 0, 0); - } + int len = sceneUploader.pushModel(model, vertexBuffer, uvBuffer); - GpuIntBuffer b = bufferForTriangles(faces); + GpuIntBuffer b = bufferForTriangles(len / 3); b.ensureCapacity(8); IntBuffer buffer = b.getBuffer(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 675381053d..910f8b3147 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -147,13 +147,13 @@ class SceneUploader Renderable renderable1 = wallObject.getRenderable1(); if (renderable1 instanceof Model) { - uploadModel((Model) renderable1, vertexBuffer, uvBuffer); + uploadSceneModel((Model) renderable1, vertexBuffer, uvBuffer); } Renderable renderable2 = wallObject.getRenderable2(); if (renderable2 instanceof Model) { - uploadModel((Model) renderable2, vertexBuffer, uvBuffer); + uploadSceneModel((Model) renderable2, vertexBuffer, uvBuffer); } } @@ -163,7 +163,7 @@ class SceneUploader Renderable renderable = groundObject.getRenderable(); if (renderable instanceof Model) { - uploadModel((Model) renderable, vertexBuffer, uvBuffer); + uploadSceneModel((Model) renderable, vertexBuffer, uvBuffer); } } @@ -173,13 +173,13 @@ class SceneUploader Renderable renderable = decorativeObject.getRenderable(); if (renderable instanceof Model) { - uploadModel((Model) renderable, vertexBuffer, uvBuffer); + uploadSceneModel((Model) renderable, vertexBuffer, uvBuffer); } Renderable renderable2 = decorativeObject.getRenderable2(); if (renderable2 instanceof Model) { - uploadModel((Model) renderable2, vertexBuffer, uvBuffer); + uploadSceneModel((Model) renderable2, vertexBuffer, uvBuffer); } } @@ -194,7 +194,7 @@ class SceneUploader Renderable renderable = gameObject.getRenderable(); if (renderable instanceof Model) { - uploadModel((Model) gameObject.getRenderable(), vertexBuffer, uvBuffer); + uploadSceneModel((Model) gameObject.getRenderable(), vertexBuffer, uvBuffer); } } } @@ -350,7 +350,7 @@ class SceneUploader return cnt; } - private void uploadModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) + private void uploadSceneModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) { if (model.getSceneId() == sceneId) { @@ -368,7 +368,18 @@ class SceneUploader } model.setSceneId(sceneId); - final int triangleCount = model.getTrianglesCount(); + int len = pushModel(model, vertexBuffer, uvBuffer); + + offset += len; + if (model.getFaceTextures() != null) + { + uvoffset += len; + } + } + + public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) + { + final int triangleCount = Math.min(model.getTrianglesCount(), GpuPlugin.MAX_TRIANGLE); vertexBuffer.ensureCapacity(triangleCount * 12); uvBuffer.ensureCapacity(triangleCount * 12); @@ -437,11 +448,7 @@ class SceneUploader len += 3; } - offset += len; - if (model.getFaceTextures() != null) - { - uvoffset += len; - } + return len; } int pushFace(Model model, int face, boolean padUvs, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer,