Add GPU renderer
This commit is contained in:
@@ -41,12 +41,15 @@ import java.awt.image.VolatileImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.BufferProvider;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MainBufferProvider;
|
||||
import net.runelite.api.RenderOverview;
|
||||
import net.runelite.api.Renderable;
|
||||
import net.runelite.api.WorldMapManager;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.hooks.Callbacks;
|
||||
import net.runelite.api.hooks.DrawCallbacks;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_VIEW;
|
||||
import net.runelite.client.Notifier;
|
||||
@@ -300,6 +303,15 @@ public class Hooks implements Callbacks
|
||||
// Draw clientUI overlays
|
||||
clientUi.paintOverlays(graphics2d);
|
||||
|
||||
graphics2d.dispose();
|
||||
|
||||
if (client.isGpu())
|
||||
{
|
||||
// processDrawComplete gets called on GPU by the gpu plugin at the end of its
|
||||
// drawing cycle, which is later on.
|
||||
return;
|
||||
}
|
||||
|
||||
// Stretch the game image if the user has that enabled
|
||||
if (client.isStretchedEnabled())
|
||||
{
|
||||
@@ -418,4 +430,36 @@ public class Hooks implements Callbacks
|
||||
// have been processed is typically more useful.
|
||||
shouldProcessGameTick = true;
|
||||
}
|
||||
|
||||
public static void renderDraw(Renderable renderable, int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y, int z, long hash)
|
||||
{
|
||||
DrawCallbacks drawCallbacks = client.getDrawCallbacks();
|
||||
if (drawCallbacks != null)
|
||||
{
|
||||
drawCallbacks.draw(renderable, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderable.draw(orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash);
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearColorBuffer(int x, int y, int width, int height, int color)
|
||||
{
|
||||
BufferProvider bp = client.getBufferProvider();
|
||||
int canvasWidth = bp.getWidth();
|
||||
int[] pixels = bp.getPixels();
|
||||
|
||||
int pixelPos = y * canvasWidth + x;
|
||||
int pixelJump = canvasWidth - width;
|
||||
|
||||
for (int cy = y; cy < y + height; cy++)
|
||||
{
|
||||
for (int cx = x; cx < x + width; cx++)
|
||||
{
|
||||
pixels[pixelPos++] = 0;
|
||||
}
|
||||
pixelPos += pixelJump;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import com.jogamp.opengl.GL4;
|
||||
import java.io.InputStream;
|
||||
import java.util.Scanner;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
class GLUtil
|
||||
{
|
||||
private static final int ERR_LEN = 1024;
|
||||
|
||||
private static final int[] buf = new int[1];
|
||||
|
||||
static int glGetInteger(GL4 gl, int pname)
|
||||
{
|
||||
gl.glGetIntegerv(pname, buf, 0);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static int glGetShader(GL4 gl, int shader, int pname)
|
||||
{
|
||||
gl.glGetShaderiv(shader, pname, buf, 0);
|
||||
assert buf[0] > -1;
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static int glGetProgram(GL4 gl, int program, int pname)
|
||||
{
|
||||
gl.glGetProgramiv(program, pname, buf, 0);
|
||||
assert buf[0] > -1;
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static String glGetShaderInfoLog(GL4 gl, int shader)
|
||||
{
|
||||
byte[] err = new byte[ERR_LEN];
|
||||
gl.glGetShaderInfoLog(shader, ERR_LEN, buf, 0, err, 0);
|
||||
return new String(err);
|
||||
}
|
||||
|
||||
static String glGetProgramInfoLog(GL4 gl, int program)
|
||||
{
|
||||
byte[] err = new byte[ERR_LEN];
|
||||
gl.glGetProgramInfoLog(program, ERR_LEN, buf, 0, err, 0);
|
||||
return new String(err);
|
||||
}
|
||||
|
||||
static int glGenVertexArrays(GL4 gl)
|
||||
{
|
||||
gl.glGenVertexArrays(1, buf, 0);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static void glDeleteVertexArrays(GL4 gl, int vertexArray)
|
||||
{
|
||||
buf[0] = vertexArray;
|
||||
gl.glDeleteVertexArrays(1, buf, 0);
|
||||
}
|
||||
|
||||
static int glGenBuffers(GL4 gl)
|
||||
{
|
||||
gl.glGenBuffers(1, buf, 0);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static void glDeleteBuffer(GL4 gl, int buffer)
|
||||
{
|
||||
buf[0] = buffer;
|
||||
gl.glDeleteBuffers(1, buf, 0);
|
||||
}
|
||||
|
||||
static int glGenTexture(GL4 gl)
|
||||
{
|
||||
gl.glGenTextures(1, buf, 0);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static void glDeleteTexture(GL4 gl, int texture)
|
||||
{
|
||||
buf[0] = texture;
|
||||
gl.glDeleteTextures(1, buf, 0);
|
||||
}
|
||||
|
||||
static void loadShaders(GL4 gl, int glProgram, int glVertexShader, int glGeometryShader, int glFragmentShader,
|
||||
String vertexShaderStr, String geomShaderStr, String fragShaderStr) throws ShaderException
|
||||
{
|
||||
compileAndAttach(gl, glProgram, glVertexShader, vertexShaderStr);
|
||||
|
||||
if (glGeometryShader != -1)
|
||||
{
|
||||
compileAndAttach(gl, glProgram, glGeometryShader, geomShaderStr);
|
||||
}
|
||||
|
||||
compileAndAttach(gl, glProgram, glFragmentShader, fragShaderStr);
|
||||
|
||||
gl.glLinkProgram(glProgram);
|
||||
|
||||
if (glGetProgram(gl, glProgram, gl.GL_LINK_STATUS) == gl.GL_FALSE)
|
||||
{
|
||||
String err = glGetProgramInfoLog(gl, glProgram);
|
||||
throw new ShaderException(err);
|
||||
}
|
||||
|
||||
gl.glValidateProgram(glProgram);
|
||||
|
||||
if (glGetProgram(gl, glProgram, gl.GL_VALIDATE_STATUS) == gl.GL_FALSE)
|
||||
{
|
||||
String err = glGetProgramInfoLog(gl, glProgram);
|
||||
throw new ShaderException(err);
|
||||
}
|
||||
}
|
||||
|
||||
static void loadComputeShader(GL4 gl, int glProgram, int glComputeShader, String str) throws ShaderException
|
||||
{
|
||||
compileAndAttach(gl, glProgram, glComputeShader, str);
|
||||
|
||||
gl.glLinkProgram(glProgram);
|
||||
|
||||
if (glGetProgram(gl, glProgram, gl.GL_LINK_STATUS) == gl.GL_FALSE)
|
||||
{
|
||||
String err = glGetProgramInfoLog(gl, glProgram);
|
||||
throw new ShaderException(err);
|
||||
}
|
||||
|
||||
gl.glValidateProgram(glProgram);
|
||||
|
||||
if (glGetProgram(gl, glProgram, gl.GL_VALIDATE_STATUS) == gl.GL_FALSE)
|
||||
{
|
||||
String err = glGetProgramInfoLog(gl, glProgram);
|
||||
throw new ShaderException(err);
|
||||
}
|
||||
}
|
||||
|
||||
private static void compileAndAttach(GL4 gl, int program, int shader, String source) throws ShaderException
|
||||
{
|
||||
gl.glShaderSource(shader, 1, new String[]{source}, null);
|
||||
gl.glCompileShader(shader);
|
||||
|
||||
if (glGetShader(gl, shader, gl.GL_COMPILE_STATUS) == gl.GL_TRUE)
|
||||
{
|
||||
gl.glAttachShader(program, shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
String err = glGetShaderInfoLog(gl, shader);
|
||||
throw new ShaderException(err);
|
||||
}
|
||||
}
|
||||
|
||||
static String inputStreamToString(InputStream in)
|
||||
{
|
||||
Scanner scanner = new Scanner(in).useDelimiter("\\A");
|
||||
return scanner.next();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
class GpuFloatBuffer
|
||||
{
|
||||
private FloatBuffer buffer = allocateDirect(65536);
|
||||
|
||||
void put(float texture, float u, float v, float pad)
|
||||
{
|
||||
buffer.put(texture).put(u).put(v).put(pad);
|
||||
}
|
||||
|
||||
void flip()
|
||||
{
|
||||
buffer.flip();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
void ensureCapacity(int size)
|
||||
{
|
||||
while (buffer.remaining() < size)
|
||||
{
|
||||
FloatBuffer newB = allocateDirect(buffer.capacity() * 2);
|
||||
buffer.flip();
|
||||
newB.put(buffer);
|
||||
buffer = newB;
|
||||
}
|
||||
}
|
||||
|
||||
FloatBuffer getBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static FloatBuffer allocateDirect(int size)
|
||||
{
|
||||
return ByteBuffer.allocateDirect(size * Float.BYTES)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asFloatBuffer();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
class GpuIntBuffer
|
||||
{
|
||||
private IntBuffer buffer = allocateDirect(65536);
|
||||
|
||||
void put(int x, int y, int z)
|
||||
{
|
||||
buffer.put(x).put(y).put(z);
|
||||
}
|
||||
|
||||
void put(int x, int y, int z, int c)
|
||||
{
|
||||
buffer.put(x).put(y).put(z).put(c);
|
||||
}
|
||||
|
||||
void flip()
|
||||
{
|
||||
buffer.flip();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
void ensureCapacity(int size)
|
||||
{
|
||||
while (buffer.remaining() < size)
|
||||
{
|
||||
IntBuffer newB = allocateDirect(buffer.capacity() * 2);
|
||||
buffer.flip();
|
||||
newB.put(buffer);
|
||||
buffer = newB;
|
||||
}
|
||||
}
|
||||
|
||||
IntBuffer getBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static IntBuffer allocateDirect(int size)
|
||||
{
|
||||
return ByteBuffer.allocateDirect(size * Integer.BYTES)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asIntBuffer();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("gpu")
|
||||
public interface GpuPluginConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "drawDistance",
|
||||
name = "Draw Distance",
|
||||
description = "Draw distance"
|
||||
)
|
||||
default int drawDistance()
|
||||
{
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.DecorativeObject;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GroundObject;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Renderable;
|
||||
import net.runelite.api.Scene;
|
||||
import net.runelite.api.SceneTileModel;
|
||||
import net.runelite.api.SceneTilePaint;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.WallObject;
|
||||
|
||||
@Singleton
|
||||
class SceneUploader
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
int sceneId = (int) (System.currentTimeMillis() / 1000L);
|
||||
private int offset;
|
||||
private int uvoffset;
|
||||
|
||||
void upload(Scene scene, GpuIntBuffer vertexbuffer, GpuFloatBuffer uvBuffer)
|
||||
{
|
||||
++sceneId;
|
||||
offset = 0;
|
||||
uvoffset = 0;
|
||||
vertexbuffer.clear();
|
||||
uvBuffer.clear();
|
||||
|
||||
for (int z = 0; z < Constants.MAX_Z; ++z)
|
||||
{
|
||||
for (int x = 0; x < Constants.SCENE_SIZE; ++x)
|
||||
{
|
||||
for (int y = 0; y < Constants.SCENE_SIZE; ++y)
|
||||
{
|
||||
Tile tile = scene.getTiles()[z][x][y];
|
||||
if (tile != null)
|
||||
{
|
||||
reset(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int z = 0; z < Constants.MAX_Z; ++z)
|
||||
{
|
||||
for (int x = 0; x < Constants.SCENE_SIZE; ++x)
|
||||
{
|
||||
for (int y = 0; y < Constants.SCENE_SIZE; ++y)
|
||||
{
|
||||
Tile tile = scene.getTiles()[z][x][y];
|
||||
if (tile != null)
|
||||
{
|
||||
upload(tile, vertexbuffer, uvBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void reset(Tile tile)
|
||||
{
|
||||
Tile bridge = tile.getBridge();
|
||||
if (bridge != null)
|
||||
{
|
||||
reset(bridge);
|
||||
}
|
||||
|
||||
SceneTilePaint sceneTilePaint = tile.getSceneTilePaint();
|
||||
if (sceneTilePaint != null)
|
||||
{
|
||||
sceneTilePaint.setBufferOffset(-1);
|
||||
}
|
||||
|
||||
SceneTileModel sceneTileModel = tile.getSceneTileModel();
|
||||
if (sceneTileModel != null)
|
||||
{
|
||||
sceneTileModel.setBufferOffset(-1);
|
||||
}
|
||||
|
||||
WallObject wallObject = tile.getWallObject();
|
||||
if (wallObject != null)
|
||||
{
|
||||
if (wallObject.getRenderable1() instanceof Model)
|
||||
{
|
||||
((Model) wallObject.getRenderable1()).setBufferOffset(-1);
|
||||
}
|
||||
if (wallObject.getRenderable2() instanceof Model)
|
||||
{
|
||||
((Model) wallObject.getRenderable2()).setBufferOffset(-1);
|
||||
}
|
||||
}
|
||||
|
||||
GroundObject groundObject = tile.getGroundObject();
|
||||
if (groundObject != null)
|
||||
{
|
||||
if (groundObject.getRenderable() instanceof Model)
|
||||
{
|
||||
((Model) groundObject.getRenderable()).setBufferOffset(-1);
|
||||
}
|
||||
}
|
||||
|
||||
DecorativeObject decorativeObject = tile.getDecorativeObject();
|
||||
if (decorativeObject != null)
|
||||
{
|
||||
if (decorativeObject.getRenderable() instanceof Model)
|
||||
{
|
||||
((Model) decorativeObject.getRenderable()).setBufferOffset(-1);
|
||||
}
|
||||
}
|
||||
|
||||
GameObject[] gameObjects = tile.getGameObjects();
|
||||
for (GameObject gameObject : gameObjects)
|
||||
{
|
||||
if (gameObject == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (gameObject.getRenderable() instanceof Model)
|
||||
{
|
||||
((Model) gameObject.getRenderable()).setBufferOffset(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void upload(Tile tile, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer)
|
||||
{
|
||||
Tile bridge = tile.getBridge();
|
||||
if (bridge != null)
|
||||
{
|
||||
upload(bridge, vertexBuffer, uvBuffer);
|
||||
}
|
||||
|
||||
SceneTilePaint sceneTilePaint = tile.getSceneTilePaint();
|
||||
if (sceneTilePaint != null)
|
||||
{
|
||||
sceneTilePaint.setBufferOffset(offset);
|
||||
if (sceneTilePaint.getTexture() != -1)
|
||||
{
|
||||
sceneTilePaint.setUvBufferOffset(uvoffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneTilePaint.setUvBufferOffset(-1);
|
||||
}
|
||||
Point tilePoint = tile.getSceneLocation();
|
||||
int len = upload(sceneTilePaint, tile.getRenderLevel(), tilePoint.getX(), tilePoint.getY(), vertexBuffer, uvBuffer);
|
||||
sceneTilePaint.setBufferLen(len);
|
||||
offset += len;
|
||||
if (sceneTilePaint.getTexture() != -1)
|
||||
{
|
||||
uvoffset += len;
|
||||
}
|
||||
}
|
||||
|
||||
SceneTileModel sceneTileModel = tile.getSceneTileModel();
|
||||
if (sceneTileModel != null)
|
||||
{
|
||||
sceneTileModel.setBufferOffset(offset);
|
||||
if (sceneTileModel.getTriangleTextureId() != null)
|
||||
{
|
||||
sceneTileModel.setUvBufferOffset(uvoffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneTileModel.setUvBufferOffset(-1);
|
||||
}
|
||||
Point tilePoint = tile.getSceneLocation();
|
||||
int len = upload(sceneTileModel, tilePoint.getX(), tilePoint.getY(), vertexBuffer, uvBuffer);
|
||||
sceneTileModel.setBufferLen(len);
|
||||
offset += len;
|
||||
if (sceneTileModel.getTriangleTextureId() != null)
|
||||
{
|
||||
uvoffset += len;
|
||||
}
|
||||
}
|
||||
|
||||
WallObject wallObject = tile.getWallObject();
|
||||
if (wallObject != null)
|
||||
{
|
||||
Renderable renderable1 = wallObject.getRenderable1();
|
||||
if (renderable1 instanceof Model)
|
||||
{
|
||||
uploadModel((Model) renderable1, vertexBuffer, uvBuffer);
|
||||
}
|
||||
|
||||
Renderable renderable2 = wallObject.getRenderable2();
|
||||
if (renderable2 instanceof Model)
|
||||
{
|
||||
uploadModel((Model) renderable2, vertexBuffer, uvBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
GroundObject groundObject = tile.getGroundObject();
|
||||
if (groundObject != null)
|
||||
{
|
||||
Renderable renderable = groundObject.getRenderable();
|
||||
if (renderable instanceof Model)
|
||||
{
|
||||
uploadModel((Model) renderable, vertexBuffer, uvBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
DecorativeObject decorativeObject = tile.getDecorativeObject();
|
||||
if (decorativeObject != null)
|
||||
{
|
||||
Renderable renderable = decorativeObject.getRenderable();
|
||||
if (renderable instanceof Model)
|
||||
{
|
||||
uploadModel((Model) renderable, vertexBuffer, uvBuffer);
|
||||
}
|
||||
|
||||
Renderable renderable2 = decorativeObject.getRenderable2();
|
||||
if (renderable2 instanceof Model)
|
||||
{
|
||||
uploadModel((Model) renderable2, vertexBuffer, uvBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
GameObject[] gameObjects = tile.getGameObjects();
|
||||
for (GameObject gameObject : gameObjects)
|
||||
{
|
||||
if (gameObject == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Renderable renderable = gameObject.getRenderable();
|
||||
if (renderable instanceof Model)
|
||||
{
|
||||
uploadModel((Model) gameObject.getRenderable(), vertexBuffer, uvBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int upload(SceneTilePaint tile, int tileZ, int tileX, int tileY, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer)
|
||||
{
|
||||
final int[][][] tileHeights = client.getTileHeights();
|
||||
|
||||
final int localX = 0;
|
||||
final int localY = 0;
|
||||
|
||||
int swHeight = tileHeights[tileZ][tileX][tileY];
|
||||
int seHeight = tileHeights[tileZ][tileX + 1][tileY];
|
||||
int neHeight = tileHeights[tileZ][tileX + 1][tileY + 1];
|
||||
int nwHeight = tileHeights[tileZ][tileX][tileY + 1];
|
||||
|
||||
final int neColor = tile.getNeColor();
|
||||
final int nwColor = tile.getNwColor();
|
||||
final int seColor = tile.getSeColor();
|
||||
final int swColor = tile.getSwColor();
|
||||
|
||||
if (neColor == 12345678)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vertexBuffer.ensureCapacity(24);
|
||||
uvBuffer.ensureCapacity(24);
|
||||
|
||||
// 0,0
|
||||
int vertexDx = localX;
|
||||
int vertexDy = localY;
|
||||
int vertexDz = swHeight;
|
||||
final int c1 = swColor;
|
||||
|
||||
// 1,0
|
||||
int vertexCx = localX + Perspective.LOCAL_TILE_SIZE;
|
||||
int vertexCy = localY;
|
||||
int vertexCz = seHeight;
|
||||
final int c2 = nwColor;
|
||||
|
||||
// 1,1
|
||||
int vertexAx = localX + Perspective.LOCAL_TILE_SIZE;
|
||||
int vertexAy = localY + Perspective.LOCAL_TILE_SIZE;
|
||||
int vertexAz = neHeight;
|
||||
final int c3 = neColor;
|
||||
|
||||
// 0,1
|
||||
int vertexBx = localX;
|
||||
int vertexBy = localY + Perspective.LOCAL_TILE_SIZE;
|
||||
int vertexBz = nwHeight;
|
||||
final int c4 = seColor;
|
||||
|
||||
vertexBuffer.put(vertexAx, vertexAz, vertexAy, c3);
|
||||
vertexBuffer.put(vertexBx, vertexBz, vertexBy, c4);
|
||||
vertexBuffer.put(vertexCx, vertexCz, vertexCy, c2);
|
||||
|
||||
vertexBuffer.put(vertexDx, vertexDz, vertexDy, c1);
|
||||
vertexBuffer.put(vertexCx, vertexCz, vertexCy, c2);
|
||||
vertexBuffer.put(vertexBx, vertexBz, vertexBy, c4);
|
||||
|
||||
if (tile.getTexture() != -1)
|
||||
{
|
||||
float tex = tile.getTexture();
|
||||
uvBuffer.put(tex, 1.0f + 1f, 1.0f + 1f, 0f);
|
||||
uvBuffer.put(tex, 0.0f + 1f, 1.0f + 1f, 0f);
|
||||
uvBuffer.put(tex, 1.0f + 1f, 0.0f + 1f, 0f);
|
||||
|
||||
uvBuffer.put(tex, 0.0f + 1f, 0.0f + 1f, 0f);
|
||||
uvBuffer.put(tex, 1.0f + 1f, 0.0f + 1f, 0f);
|
||||
uvBuffer.put(tex, 0.0f + 1f, 1.0f + 1f, 0f);
|
||||
}
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
||||
private int upload(SceneTileModel sceneTileModel, int tileX, int tileY, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer)
|
||||
{
|
||||
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[] triangleColorA = sceneTileModel.getTriangleColorA();
|
||||
final int[] triangleColorB = sceneTileModel.getTriangleColorB();
|
||||
final int[] triangleColorC = sceneTileModel.getTriangleColorC();
|
||||
|
||||
final int[] triangleTextures = sceneTileModel.getTriangleTextureId();
|
||||
|
||||
final int faceCount = faceX.length;
|
||||
|
||||
vertexBuffer.ensureCapacity(faceCount * 12);
|
||||
uvBuffer.ensureCapacity(faceCount * 12);
|
||||
|
||||
int baseX = Perspective.LOCAL_TILE_SIZE * tileX;
|
||||
int baseY = Perspective.LOCAL_TILE_SIZE * tileY;
|
||||
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < faceCount; ++i)
|
||||
{
|
||||
final int triangleA = faceX[i];
|
||||
final int triangleB = faceY[i];
|
||||
final int triangleC = faceZ[i];
|
||||
|
||||
final int colorA = triangleColorA[i];
|
||||
final int colorB = triangleColorB[i];
|
||||
final int colorC = triangleColorC[i];
|
||||
|
||||
if (colorA == 12345678)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cnt += 3;
|
||||
|
||||
int vertexXA = vertexX[triangleA] - baseX;
|
||||
int vertexZA = vertexZ[triangleA] - baseY;
|
||||
|
||||
int vertexXB = vertexX[triangleB] - baseX;
|
||||
int vertexZB = vertexZ[triangleB] - baseY;
|
||||
|
||||
int vertexXC = vertexX[triangleC] - baseX;
|
||||
int vertexZC = vertexZ[triangleC] - baseY;
|
||||
|
||||
vertexBuffer.put(vertexXA, vertexY[triangleA], vertexZA, colorA);
|
||||
vertexBuffer.put(vertexXB, vertexY[triangleB], vertexZB, colorB);
|
||||
vertexBuffer.put(vertexXC, vertexY[triangleC], vertexZC, colorC);
|
||||
|
||||
if (triangleTextures != null)
|
||||
{
|
||||
if (triangleTextures[i] != -1)
|
||||
{
|
||||
float tex = triangleTextures[i];
|
||||
uvBuffer.put(tex, vertexXA / 128f + 1f, vertexZA / 128f + 1f, 0f);
|
||||
uvBuffer.put(tex, vertexXB / 128f + 1f, vertexZB / 128f + 1f, 0f);
|
||||
uvBuffer.put(tex, vertexXC / 128f + 1f, vertexZC / 128f + 1f, 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
uvBuffer.put(0, 0, 0, 0f);
|
||||
uvBuffer.put(0, 0, 0, 0f);
|
||||
uvBuffer.put(0, 0, 0, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
private void uploadModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer)
|
||||
{
|
||||
if (model.getBufferOffset() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
model.setBufferOffset(offset);
|
||||
if (model.getFaceTextures() != null)
|
||||
{
|
||||
model.setUvBufferOffset(uvoffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
model.setUvBufferOffset(-1);
|
||||
}
|
||||
model.setSceneId(sceneId);
|
||||
|
||||
vertexBuffer.ensureCapacity(model.getTrianglesCount() * 12);
|
||||
uvBuffer.ensureCapacity(model.getTrianglesCount() * 12);
|
||||
|
||||
final int triangleCount = model.getTrianglesCount();
|
||||
int len = 0;
|
||||
for (int i = 0; i < triangleCount; ++i)
|
||||
{
|
||||
len += pushFace(model, i, vertexBuffer, uvBuffer);
|
||||
}
|
||||
|
||||
offset += len;
|
||||
if (model.getFaceTextures() != null)
|
||||
{
|
||||
uvoffset += len;
|
||||
}
|
||||
}
|
||||
|
||||
int pushFace(Model model, int face, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer)
|
||||
{
|
||||
final int[] vertexX = model.getVerticesX();
|
||||
final int[] vertexY = model.getVerticesY();
|
||||
final int[] vertexZ = model.getVerticesZ();
|
||||
|
||||
final int[] trianglesX = model.getTrianglesX();
|
||||
final int[] trianglesY = model.getTrianglesY();
|
||||
final int[] trianglesZ = model.getTrianglesZ();
|
||||
|
||||
final int[] color1s = model.getFaceColors1();
|
||||
final int[] color2s = model.getFaceColors2();
|
||||
final int[] color3s = model.getFaceColors3();
|
||||
|
||||
final byte[] transparencies = model.getTriangleTransparencies();
|
||||
final short[] faceTextures = model.getFaceTextures();
|
||||
final byte[] facePriorities = model.getFaceRenderPriorities();
|
||||
|
||||
int triangleA = trianglesX[face];
|
||||
int triangleB = trianglesY[face];
|
||||
int triangleC = trianglesZ[face];
|
||||
|
||||
int color1 = color1s[face];
|
||||
int color2 = color2s[face];
|
||||
int color3 = color3s[face];
|
||||
|
||||
int alpha = 0;
|
||||
if (transparencies != null)
|
||||
{
|
||||
alpha = (transparencies[face] & 0xFF) << 24;
|
||||
}
|
||||
int priority = 0;
|
||||
if (facePriorities != null)
|
||||
{
|
||||
priority = (facePriorities[face] & 0xff) << 16;
|
||||
}
|
||||
|
||||
if (color3 == -1)
|
||||
{
|
||||
color2 = color3 = color1;
|
||||
}
|
||||
else if (color3 == -2)
|
||||
{
|
||||
vertexBuffer.put(0, 0, 0, 0);
|
||||
vertexBuffer.put(0, 0, 0, 0);
|
||||
vertexBuffer.put(0, 0, 0, 0);
|
||||
|
||||
if (faceTextures != null)
|
||||
{
|
||||
uvBuffer.put(0, 0, 0, 0f);
|
||||
uvBuffer.put(0, 0, 0, 0f);
|
||||
uvBuffer.put(0, 0, 0, 0f);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
int a, b, c;
|
||||
|
||||
a = vertexX[triangleA];
|
||||
b = vertexY[triangleA];
|
||||
c = vertexZ[triangleA];
|
||||
|
||||
vertexBuffer.put(a, b, c, alpha | priority | color1);
|
||||
|
||||
a = vertexX[triangleB];
|
||||
b = vertexY[triangleB];
|
||||
c = vertexZ[triangleB];
|
||||
|
||||
vertexBuffer.put(a, b, c, alpha | priority | color2);
|
||||
|
||||
a = vertexX[triangleC];
|
||||
b = vertexY[triangleC];
|
||||
c = vertexZ[triangleC];
|
||||
|
||||
vertexBuffer.put(a, b, c, alpha | priority | color3);
|
||||
|
||||
float[][] u = model.getFaceTextureUCoordinates();
|
||||
float[][] v = model.getFaceTextureVCoordinates();
|
||||
float[] uf, vf;
|
||||
if (faceTextures != null)
|
||||
{
|
||||
if (u != null && v != null && (uf = u[face]) != null && (vf = v[face]) != null)
|
||||
{
|
||||
final short texture = faceTextures[face];
|
||||
uvBuffer.put(texture, 1f + uf[0], 1f + vf[0], 0f);
|
||||
uvBuffer.put(texture, 1f + uf[1], 1f + vf[1], 0f);
|
||||
uvBuffer.put(texture, 1f + uf[2], 1f + vf[2], 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
uvBuffer.put(0f, 0f, 0f, 0f);
|
||||
uvBuffer.put(0f, 0f, 0f, 0f);
|
||||
uvBuffer.put(0f, 0f, 0f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
class ShaderException extends Exception
|
||||
{
|
||||
ShaderException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import com.jogamp.opengl.GL4;
|
||||
import java.nio.ByteBuffer;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Texture;
|
||||
import net.runelite.api.TextureProvider;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
class TextureManager
|
||||
{
|
||||
private static final float PERC_64 = 1f / 64f;
|
||||
private static final float PERC_128 = 1f / 128f;
|
||||
|
||||
private static final int SMALL_TEXTURE_SIZE = 64;
|
||||
private static final int TEXTURE_SIZE = 128;
|
||||
|
||||
int initTextureArray(TextureProvider textureProvider, GL4 gl)
|
||||
{
|
||||
if (!allTexturesLoaded(textureProvider))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Texture[] textures = textureProvider.getTextures();
|
||||
|
||||
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.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);
|
||||
|
||||
gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Set brightness to 1.0d to upload unmodified textures to GPU
|
||||
double save = textureProvider.getBrightness();
|
||||
textureProvider.setBrightness(1.0d);
|
||||
|
||||
updateTextures(textureProvider, gl, textureArrayId);
|
||||
|
||||
textureProvider.setBrightness(save);
|
||||
|
||||
gl.glActiveTexture(gl.GL_TEXTURE1);
|
||||
gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, textureArrayId);
|
||||
gl.glActiveTexture(gl.GL_TEXTURE0);
|
||||
|
||||
return textureArrayId;
|
||||
}
|
||||
|
||||
void freeTextureArray(GL4 gl, int textureArrayId)
|
||||
{
|
||||
GLUtil.glDeleteTexture(gl, textureArrayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all textures have been loaded and cached yet.
|
||||
*
|
||||
* @param textureProvider
|
||||
* @return
|
||||
*/
|
||||
private boolean allTexturesLoaded(TextureProvider textureProvider)
|
||||
{
|
||||
Texture[] textures = textureProvider.getTextures();
|
||||
if (textures == null || textures.length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int textureId = 0; textureId < textures.length; textureId++)
|
||||
{
|
||||
Texture texture = textures[textureId];
|
||||
if (texture != null)
|
||||
{
|
||||
int[] pixels = textureProvider.load(textureId);
|
||||
if (pixels == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateTextures(TextureProvider textureProvider, GL4 gl, int textureArrayId)
|
||||
{
|
||||
Texture[] textures = textureProvider.getTextures();
|
||||
|
||||
gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, textureArrayId);
|
||||
|
||||
int cnt = 0;
|
||||
for (int textureId = 0; textureId < textures.length; textureId++)
|
||||
{
|
||||
Texture texture = textures[textureId];
|
||||
if (texture != null)
|
||||
{
|
||||
int[] srcPixels = textureProvider.load(textureId);
|
||||
if (srcPixels == null)
|
||||
{
|
||||
log.warn("No pixels for texture {}!", textureId);
|
||||
continue; // this can't happen
|
||||
}
|
||||
|
||||
++cnt;
|
||||
|
||||
int srcSize = srcPixels.length == 4096 ? SMALL_TEXTURE_SIZE : TEXTURE_SIZE;
|
||||
byte[] pixels = convertPixels(srcPixels, srcSize, srcSize, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
ByteBuffer pixelBuffer = ByteBuffer.wrap(pixels);
|
||||
gl.glTexSubImage3D(gl.GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureId, TEXTURE_SIZE, TEXTURE_SIZE,
|
||||
1, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, pixelBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Uploaded textures {}", cnt);
|
||||
}
|
||||
|
||||
private static byte[] convertPixels(int[] srcPixels, int width, int height, int textureWidth, int textureHeight)
|
||||
{
|
||||
byte[] pixels = new byte[textureWidth * textureHeight * 4];
|
||||
|
||||
int pixelIdx = 0;
|
||||
int srcPixelIdx = 0;
|
||||
|
||||
int offset = (textureWidth - width) * 4;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
int rgb = srcPixels[srcPixelIdx++];
|
||||
if (rgb != 0)
|
||||
{
|
||||
pixels[pixelIdx++] = (byte) (rgb >> 16);
|
||||
pixels[pixelIdx++] = (byte) (rgb >> 8);
|
||||
pixels[pixelIdx++] = (byte) rgb;
|
||||
pixels[pixelIdx++] = (byte) -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixelIdx += 4;
|
||||
}
|
||||
}
|
||||
pixelIdx += offset;
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
if (pixels == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu.template;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Template
|
||||
{
|
||||
private final Function<String, String> resourceLoader;
|
||||
|
||||
public Template(Function<String, String> resourceLoader)
|
||||
{
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
public String process(String str)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String line : str.split("\r?\n"))
|
||||
{
|
||||
if (line.startsWith("#include "))
|
||||
{
|
||||
String resource = line.substring(9);
|
||||
String resourceStr = resourceLoader.apply(resource);
|
||||
sb.append(process(resourceStr));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append(line).append('\n');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include to_screen.glsl
|
||||
|
||||
/*
|
||||
* Rotate a vertex by a given orientation in JAU
|
||||
*/
|
||||
ivec4 rotate(ivec4 vertex, int orientation) {
|
||||
int s = int(65536.0f * sin(orientation * UNIT));
|
||||
int c = int(65536.0f * cos(orientation * UNIT));
|
||||
int x = vertex.z * s + vertex.x * c >> 16;
|
||||
int z = vertex.z * c - vertex.x * s >> 16;
|
||||
return ivec4(x, vertex.y, z, vertex.w);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the distance to a vertex given the camera angle
|
||||
*/
|
||||
int distance(ivec4 vertex, int cameraYaw, int cameraPitch) {
|
||||
int yawSin = int(65536.0f * sin(cameraYaw * UNIT));
|
||||
int yawCos = int(65536.0f * cos(cameraYaw * UNIT));
|
||||
|
||||
int pitchSin = int(65536.0f * sin(cameraPitch * UNIT));
|
||||
int pitchCos = int(65536.0f * cos(cameraPitch * UNIT));
|
||||
|
||||
int j = vertex.z * yawCos - vertex.x * yawSin >> 16;
|
||||
int l = vertex.y * pitchSin + j * pitchCos >> 16;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the distance to a face
|
||||
*/
|
||||
int face_distance(ivec4 vA, ivec4 vB, ivec4 vC, int cameraYaw, int cameraPitch) {
|
||||
int dvA = distance(vA, cameraYaw, cameraPitch);
|
||||
int dvB = distance(vB, cameraYaw, cameraPitch);
|
||||
int dvC = distance(vC, cameraYaw, cameraPitch);
|
||||
int faceDistance = (dvA + dvB + dvC) / 3;
|
||||
return faceDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if a face is visible (not backward facing)
|
||||
*/
|
||||
bool face_visible(ivec4 vA, ivec4 vB, ivec4 vC, ivec4 position, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) {
|
||||
vA += position;
|
||||
vB += position;
|
||||
vC += position;
|
||||
|
||||
ivec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||
ivec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||
ivec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||
|
||||
return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0;
|
||||
}
|
||||
|
||||
// Calculate adjusted priority for a face with a given priority, distance, and
|
||||
// model global min10 and face distance averages. This allows positioning faces
|
||||
// with priorities 10/11 into the correct 'slots' resulting in 18 possible
|
||||
// adjusted priorities
|
||||
int priority_map(int p, int distance, int _min10, int avg1, int avg2, int avg3) {
|
||||
// (10, 11) 0 1 2 (10, 11) 3 4 (10, 11) 5 6 7 8 9 (10, 11)
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||
switch (p) {
|
||||
case 0: return 2;
|
||||
case 1: return 3;
|
||||
case 2: return 4;
|
||||
case 3: return 7;
|
||||
case 4: return 8;
|
||||
case 5: return 11;
|
||||
case 6: return 12;
|
||||
case 7: return 13;
|
||||
case 8: return 14;
|
||||
case 9: return 15;
|
||||
case 10:
|
||||
if (distance > avg1) {
|
||||
return 0;
|
||||
} else if (distance > avg2) {
|
||||
return 5;
|
||||
} else if (distance > avg3) {
|
||||
return 9;
|
||||
} else {
|
||||
return 16;
|
||||
}
|
||||
case 11:
|
||||
if (distance > avg1 && _min10 > avg1) {
|
||||
return 1;
|
||||
} else if (distance > avg2 && (_min10 > avg1 || _min10 > avg2)) {
|
||||
return 6;
|
||||
} else if (distance > avg3 && (_min10 > avg1 || _min10 > avg2 || _min10 > avg3)) {
|
||||
return 10;
|
||||
} else {
|
||||
return 17;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate the number of faces with a lower adjusted priority than
|
||||
// the given adjusted priority
|
||||
int count_prio_offset(int priority) {
|
||||
int total = 0;
|
||||
switch (priority) {
|
||||
case 17:
|
||||
total += totalMappedNum[16];
|
||||
case 16:
|
||||
total += totalMappedNum[15];
|
||||
case 15:
|
||||
total += totalMappedNum[14];
|
||||
case 14:
|
||||
total += totalMappedNum[13];
|
||||
case 13:
|
||||
total += totalMappedNum[12];
|
||||
case 12:
|
||||
total += totalMappedNum[11];
|
||||
case 11:
|
||||
total += totalMappedNum[10];
|
||||
case 10:
|
||||
total += totalMappedNum[9];
|
||||
case 9:
|
||||
total += totalMappedNum[8];
|
||||
case 8:
|
||||
total += totalMappedNum[7];
|
||||
case 7:
|
||||
total += totalMappedNum[6];
|
||||
case 6:
|
||||
total += totalMappedNum[5];
|
||||
case 5:
|
||||
total += totalMappedNum[4];
|
||||
case 4:
|
||||
total += totalMappedNum[3];
|
||||
case 3:
|
||||
total += totalMappedNum[2];
|
||||
case 2:
|
||||
total += totalMappedNum[1];
|
||||
case 1:
|
||||
total += totalMappedNum[0];
|
||||
case 0:
|
||||
return total;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#version 430 core
|
||||
|
||||
#define PI 3.1415926535897932384626433832795f
|
||||
#define UNIT PI / 1024.0f
|
||||
|
||||
layout(std140) uniform uniforms {
|
||||
int cameraYaw;
|
||||
int cameraPitch;
|
||||
int centerX;
|
||||
int centerY;
|
||||
int zoom;
|
||||
};
|
||||
|
||||
shared int totalNum[12]; // number of faces with a given priority
|
||||
shared int totalDistance[12]; // sum of distances to faces of a given priority
|
||||
|
||||
shared int totalMappedNum[18]; // number of faces with a given adjusted priority
|
||||
|
||||
shared int min10; // minimum distance to a face of priority 10
|
||||
shared int dfs[4096]; // packed face id and distance
|
||||
|
||||
struct modelinfo {
|
||||
int offset; // offset into buffer
|
||||
int uvOffset; // offset into uv buffer
|
||||
int length; // length in faces
|
||||
int idx; // write idx in target buffer
|
||||
int flags; // radius, orientation
|
||||
int x; // scene position x
|
||||
int y; // scene position y
|
||||
int z; // scene position z
|
||||
};
|
||||
|
||||
layout(std430, binding = 0) readonly buffer modelbuffer_in {
|
||||
modelinfo ol[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) readonly buffer vertexbuffer_in {
|
||||
ivec4 vb[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) readonly buffer tempvertexbuffer_in {
|
||||
ivec4 tempvb[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 3) writeonly buffer vertex_out {
|
||||
ivec4 vout[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 4) writeonly buffer uv_out {
|
||||
vec4 uvout[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 5) readonly buffer uvbuffer_in {
|
||||
vec4 uv[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 6) readonly buffer tempuvbuffer_in {
|
||||
vec4 tempuv[];
|
||||
};
|
||||
|
||||
layout(local_size_x = 1024) in;
|
||||
|
||||
#include common.glsl
|
||||
#include priority_render.glsl
|
||||
|
||||
void main() {
|
||||
uint groupId = gl_WorkGroupID.x;
|
||||
uint localId = gl_LocalInvocationID.x * 4;
|
||||
modelinfo minfo = ol[groupId];
|
||||
int length = minfo.length;
|
||||
|
||||
if (localId == 0) {
|
||||
min10 = 1600;
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
totalNum[i] = 0;
|
||||
totalDistance[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 18; ++i) {
|
||||
totalMappedNum[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int prio1, dis1, prio1Adj;
|
||||
ivec4 vA1, vA2, vA3;
|
||||
|
||||
int prio2, dis2, prio2Adj;
|
||||
ivec4 vB1, vB2, vB3;
|
||||
|
||||
int prio3, dis3, prio3Adj;
|
||||
ivec4 vC1, vC2, vC3;
|
||||
|
||||
int prio4, dis4, prio4Adj;
|
||||
ivec4 vD1, vD2, vD3;
|
||||
|
||||
get_face(localId, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio1, dis1, vA1, vA2, vA3);
|
||||
get_face(localId + 1, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio2, dis2, vB1, vB2, vB3);
|
||||
get_face(localId + 2, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio3, dis3, vC1, vC2, vC3);
|
||||
get_face(localId + 3, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio4, dis4, vD1, vD2, vD3);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int idx1 = map_face_priority(localId, minfo, prio1, dis1, prio1Adj);
|
||||
int idx2 = map_face_priority(localId + 1, minfo, prio2, dis2, prio2Adj);
|
||||
int idx3 = map_face_priority(localId + 2, minfo, prio3, dis3, prio3Adj);
|
||||
int idx4 = map_face_priority(localId + 3, minfo, prio4, dis4, prio4Adj);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
insert_dfs(localId , minfo, prio1Adj, dis1, idx1);
|
||||
insert_dfs(localId + 1, minfo, prio2Adj, dis2, idx2);
|
||||
insert_dfs(localId + 2, minfo, prio3Adj, dis3, idx3);
|
||||
insert_dfs(localId + 3, minfo, prio4Adj, dis4, idx4);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
sort_and_insert(localId , minfo, prio1Adj, dis1, vA1, vA2, vA3);
|
||||
sort_and_insert(localId + 1, minfo, prio2Adj, dis2, vB1, vB2, vB3);
|
||||
sort_and_insert(localId + 2, minfo, prio3Adj, dis3, vC1, vC2, vC3);
|
||||
sort_and_insert(localId + 3, minfo, prio4Adj, dis4, vD1, vD2, vD3);
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#version 430 core
|
||||
|
||||
#define PI 3.1415926535897932384626433832795f
|
||||
#define UNIT PI / 1024.0f
|
||||
|
||||
layout(std140) uniform uniforms {
|
||||
int cameraYaw;
|
||||
int cameraPitch;
|
||||
int centerX;
|
||||
int centerY;
|
||||
int zoom;
|
||||
};
|
||||
|
||||
shared int totalNum[12]; // number of faces with a given priority
|
||||
shared int totalDistance[12]; // sum of distances to faces of a given priority
|
||||
|
||||
shared int totalMappedNum[18]; // number of faces with a given adjusted priority
|
||||
|
||||
shared int min10; // minimum distance to a face of priority 10
|
||||
shared int dfs[512]; // packed face id and distance
|
||||
|
||||
struct modelinfo {
|
||||
int offset; // offset into buffer
|
||||
int uvOffset; // offset into uv buffer
|
||||
int length; // length in faces
|
||||
int idx; // write idx in target buffer
|
||||
int flags; // radius, orientation
|
||||
int x; // scene position x
|
||||
int y; // scene position y
|
||||
int z; // scene position z
|
||||
};
|
||||
|
||||
layout(std430, binding = 0) readonly buffer modelbuffer_in {
|
||||
modelinfo ol[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) readonly buffer vertexbuffer_in {
|
||||
ivec4 vb[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) readonly buffer tempvertexbuffer_in {
|
||||
ivec4 tempvb[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 3) writeonly buffer vertex_out {
|
||||
ivec4 vout[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 4) writeonly buffer uv_out {
|
||||
vec4 uvout[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 5) readonly buffer uvbuffer_in {
|
||||
vec4 uv[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 6) readonly buffer tempuvbuffer_in {
|
||||
vec4 tempuv[];
|
||||
};
|
||||
|
||||
layout(local_size_x = 512) in;
|
||||
|
||||
#include common.glsl
|
||||
#include priority_render.glsl
|
||||
|
||||
void main() {
|
||||
uint groupId = gl_WorkGroupID.x;
|
||||
uint localId = gl_LocalInvocationID.x;
|
||||
modelinfo minfo = ol[groupId];
|
||||
|
||||
if (localId == 0) {
|
||||
min10 = 1600;
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
totalNum[i] = 0;
|
||||
totalDistance[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 18; ++i) {
|
||||
totalMappedNum[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int prio1, dis1, prio1Adj;
|
||||
ivec4 vA1, vA2, vA3;
|
||||
|
||||
get_face(localId, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio1, dis1, vA1, vA2, vA3);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int idx1 = map_face_priority(localId, minfo, prio1, dis1, prio1Adj);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
insert_dfs(localId, minfo, prio1Adj, dis1, idx1);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
sort_and_insert(localId, minfo, prio1Adj, dis1, vA1, vA2, vA3);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#version 400
|
||||
|
||||
uniform sampler2DArray textures;
|
||||
uniform vec2 textureOffsets[64];
|
||||
uniform float brightness;
|
||||
|
||||
in vec4 Color;
|
||||
in vec4 fUv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
float n = fUv.x;
|
||||
float u = fUv.y;
|
||||
float v = fUv.z;
|
||||
|
||||
if (u > 0.0f && v > 0.0f) {
|
||||
int textureIdx = int(n);
|
||||
|
||||
vec2 uv = vec2(u - 1, v - 1);
|
||||
vec2 animatedUv = uv + textureOffsets[textureIdx];
|
||||
|
||||
vec4 textureColor = texture(textures, vec3(animatedUv, n));
|
||||
vec4 textureColorBrightness = pow(textureColor, vec4(brightness, brightness, brightness, 1.0f));
|
||||
|
||||
FragColor = textureColorBrightness * Color;
|
||||
} else {
|
||||
FragColor = Color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#version 330
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec4 c = texture(tex, TexCoord);
|
||||
FragColor = c;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#version 400
|
||||
|
||||
#define PI 3.1415926535897932384626433832795f
|
||||
#define UNIT PI / 1024.0f
|
||||
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
|
||||
layout(std140) uniform Uniforms {
|
||||
int cameraYaw;
|
||||
int cameraPitch;
|
||||
int centerX;
|
||||
int centerY;
|
||||
int zoom;
|
||||
};
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
in ivec3 vPosition[];
|
||||
in vec4 vColor[];
|
||||
in vec4 vUv[];
|
||||
|
||||
out vec4 Color;
|
||||
out vec4 fUv;
|
||||
|
||||
#include to_screen.glsl
|
||||
|
||||
void main() {
|
||||
ivec3 screenA = toScreen(vPosition[0], cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||
ivec3 screenB = toScreen(vPosition[1], cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||
ivec3 screenC = toScreen(vPosition[2], cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||
|
||||
if (-screenA.z < 50 || -screenB.z < 50 || -screenC.z < 50) {
|
||||
// the client does not draw a triangle if any vertex distance is <50
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 tmp = vec4(screenA.xyz, 1.0);
|
||||
Color = vColor[0];
|
||||
fUv = vUv[0];
|
||||
gl_Position = projectionMatrix * tmp;
|
||||
EmitVertex();
|
||||
|
||||
tmp = vec4(screenB.xyz, 1.0);
|
||||
Color = vColor[1];
|
||||
fUv = vUv[1];
|
||||
gl_Position = projectionMatrix * tmp;
|
||||
EmitVertex();
|
||||
|
||||
tmp = vec4(screenC.xyz, 1.0);
|
||||
Color = vColor[2];
|
||||
fUv = vUv[2];
|
||||
gl_Position = projectionMatrix * tmp;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
void get_face(uint localId, modelinfo minfo, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom,
|
||||
out int prio, out int dis, out ivec4 o1, out ivec4 o2, out ivec4 o3) {
|
||||
int offset = minfo.offset;
|
||||
int length = minfo.length;
|
||||
int flags = minfo.flags;
|
||||
int radius = (flags & 0x7fffffff) >> 12;
|
||||
int orientation = flags & 0x7ff;
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
uint ssboOffset;
|
||||
|
||||
if (localId < length) {
|
||||
ssboOffset = localId;
|
||||
} else {
|
||||
ssboOffset = 0;
|
||||
}
|
||||
|
||||
ivec4 thisA;
|
||||
ivec4 thisB;
|
||||
ivec4 thisC;
|
||||
|
||||
// Grab triangle vertices from the correct buffer
|
||||
if (flags < 0) {
|
||||
thisA = vb[offset + ssboOffset * 3 ];
|
||||
thisB = vb[offset + ssboOffset * 3 + 1];
|
||||
thisC = vb[offset + ssboOffset * 3 + 2];
|
||||
} else {
|
||||
thisA = tempvb[offset + ssboOffset * 3 ];
|
||||
thisB = tempvb[offset + ssboOffset * 3 + 1];
|
||||
thisC = tempvb[offset + ssboOffset * 3 + 2];
|
||||
}
|
||||
|
||||
ivec4 thisrvA;
|
||||
ivec4 thisrvB;
|
||||
ivec4 thisrvC;
|
||||
|
||||
int thisPriority, thisDistance;
|
||||
|
||||
if (localId < length) {
|
||||
// rotate for model orientation
|
||||
thisrvA = rotate(thisA, orientation);
|
||||
thisrvB = rotate(thisB, orientation);
|
||||
thisrvC = rotate(thisC, orientation);
|
||||
|
||||
// calculate distance to face
|
||||
thisPriority = (thisA.w >> 16) & 0xff; // all vertices on the face have the same priority
|
||||
if (radius == 0) {
|
||||
thisDistance = 0;
|
||||
} else {
|
||||
thisDistance = face_distance(thisrvA, thisrvB, thisrvC, cameraYaw, cameraPitch) + radius;
|
||||
}
|
||||
|
||||
// if the face is not culled, it is calculated into priority distance averages
|
||||
if (face_visible(thisrvA, thisrvB, thisrvC, pos, cameraYaw, cameraPitch, centerX, centerY, zoom)) {
|
||||
atomicAdd(totalNum[thisPriority], 1);
|
||||
atomicAdd(totalDistance[thisPriority], thisDistance);
|
||||
|
||||
// calculate minimum distance to any face of priority 10 for positioning the 11 faces later
|
||||
if (thisPriority == 10) {
|
||||
atomicMin(min10, thisDistance);
|
||||
}
|
||||
}
|
||||
|
||||
o1 = thisrvA;
|
||||
o2 = thisrvB;
|
||||
o3 = thisrvC;
|
||||
|
||||
prio = thisPriority;
|
||||
dis = thisDistance;
|
||||
} else {
|
||||
prio = 0;
|
||||
dis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int map_face_priority(uint localId, modelinfo minfo, int thisPriority, int thisDistance, out int prio) {
|
||||
int length = minfo.length;
|
||||
|
||||
// Compute average distances for 0/2, 3/4, and 6/8
|
||||
|
||||
int adjPrio;
|
||||
int prioIdx;
|
||||
|
||||
if (localId < length) {
|
||||
int avg1 = 0;
|
||||
int avg2 = 0;
|
||||
int avg3 = 0;
|
||||
|
||||
if (totalNum[1] > 0 || totalNum[2] > 0) {
|
||||
avg1 = (totalDistance[1] + totalDistance[2]) / (totalNum[1] + totalNum[2]);
|
||||
}
|
||||
|
||||
if (totalNum[3] > 0 || totalNum[4] > 0) {
|
||||
avg2 = (totalDistance[3] + totalDistance[4]) / (totalNum[3] + totalNum[4]);
|
||||
}
|
||||
|
||||
if (totalNum[6] > 0 || totalNum[8] > 0) {
|
||||
avg3 = (totalDistance[6] + totalDistance[8]) / (totalNum[6] + totalNum[8]);
|
||||
}
|
||||
|
||||
int _min10 = min10;
|
||||
adjPrio = priority_map(thisPriority, thisDistance, _min10, avg1, avg2, avg3);
|
||||
|
||||
int prioIdx = atomicAdd(totalMappedNum[adjPrio], 1);
|
||||
|
||||
prio = adjPrio;
|
||||
|
||||
return prioIdx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void insert_dfs(uint localId, modelinfo minfo, int adjPrio, int distance, int prioIdx) {
|
||||
int length = minfo.length;
|
||||
|
||||
if (localId < length) {
|
||||
// calculate base offset into dfs based on number of faces with a lower priority
|
||||
int baseOff = count_prio_offset(adjPrio);
|
||||
// store into face array offset array by unique index
|
||||
dfs[baseOff + prioIdx] = (int(localId) << 16) | distance;
|
||||
}
|
||||
}
|
||||
|
||||
void sort_and_insert(uint localId, modelinfo minfo, int thisPriority, int thisDistance, ivec4 thisrvA, ivec4 thisrvB, ivec4 thisrvC) {
|
||||
/* compute face distance */
|
||||
int length = minfo.length;
|
||||
int outOffset = minfo.idx;
|
||||
int uvOffset = minfo.uvOffset;
|
||||
int flags = minfo.flags;
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
int start, end, myOffset;
|
||||
if (localId < length) {
|
||||
const int priorityOffset = count_prio_offset(thisPriority);
|
||||
const int numOfPriority = totalMappedNum[thisPriority];
|
||||
start = priorityOffset; // index of first face with this priority
|
||||
end = priorityOffset + numOfPriority; // index of last face with this priority
|
||||
myOffset = priorityOffset;
|
||||
} else {
|
||||
start = end = myOffset = 0;
|
||||
}
|
||||
|
||||
if (localId < length) {
|
||||
// we only have to order faces against others of the same priority
|
||||
// calculate position this face will be in
|
||||
for (int i = start; i < end; ++i) {
|
||||
int d1 = dfs[i];
|
||||
int theirId = d1 >> 16;
|
||||
int theirDistance = d1 & 0xffff;
|
||||
|
||||
// the closest faces draw last, so have the highest index
|
||||
// if two faces have the same distance, the one with the
|
||||
// higher id draws last
|
||||
if ((theirDistance > thisDistance)
|
||||
|| (theirDistance == thisDistance && theirId < localId)) {
|
||||
++myOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// position vertices in scene and write to out buffer
|
||||
vout[outOffset + myOffset * 3] = pos + thisrvA;
|
||||
vout[outOffset + myOffset * 3 + 1] = pos + thisrvB;
|
||||
vout[outOffset + myOffset * 3 + 2] = pos + thisrvC;
|
||||
|
||||
if (uvOffset < 0) {
|
||||
uvout[outOffset + myOffset * 3] = vec4(0, 0, 0, 0);
|
||||
uvout[outOffset + myOffset * 3 + 1] = vec4(0, 0, 0, 0);
|
||||
uvout[outOffset + myOffset * 3 + 2] = vec4(0, 0, 0, 0);
|
||||
} else if (flags >= 0) {
|
||||
uvout[outOffset + myOffset * 3] = tempuv[uvOffset + localId * 3];
|
||||
uvout[outOffset + myOffset * 3 + 1] = tempuv[uvOffset + localId * 3 + 1];
|
||||
uvout[outOffset + myOffset * 3 + 2] = tempuv[uvOffset + localId * 3 + 2];
|
||||
} else {
|
||||
uvout[outOffset + myOffset * 3] = uv[uvOffset + localId * 3];
|
||||
uvout[outOffset + myOffset * 3 + 1] = uv[uvOffset + localId * 3 + 1];
|
||||
uvout[outOffset + myOffset * 3 + 2] = uv[uvOffset + localId * 3 + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convert a vertex to screen space
|
||||
*/
|
||||
ivec3 toScreen(ivec3 vertex, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) {
|
||||
int yawSin = int(65536.0f * sin(cameraYaw * UNIT));
|
||||
int yawCos = int(65536.0f * cos(cameraYaw * UNIT));
|
||||
|
||||
int pitchSin = int(65536.0f * sin(cameraPitch * UNIT));
|
||||
int pitchCos = int(65536.0f * cos(cameraPitch * UNIT));
|
||||
|
||||
int rotatedX = ((vertex.z * yawSin) + (vertex.x * yawCos)) >> 16;
|
||||
int rotatedZ = ((vertex.z * yawCos) - (vertex.x * yawSin)) >> 16;
|
||||
|
||||
int var13 = ((vertex.y * pitchCos) - (rotatedZ * pitchSin)) >> 16;
|
||||
int var12 = ((vertex.y * pitchSin) + (rotatedZ * pitchCos)) >> 16;
|
||||
|
||||
int x = rotatedX * zoom / var12 + centerX;
|
||||
int y = var13 * zoom / var12 + centerY;
|
||||
int z = -var12; // in OpenGL depth is negative
|
||||
|
||||
return ivec3(x, y, z);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#version 400
|
||||
|
||||
layout (location = 0) in ivec4 VertexPosition;
|
||||
layout (location = 1) in vec4 uv;
|
||||
|
||||
uniform float brightness;
|
||||
|
||||
out ivec3 vPosition;
|
||||
out vec4 vColor;
|
||||
out vec4 vUv;
|
||||
|
||||
vec3 hslToRgb(int hsl) {
|
||||
int var5 = hsl/128;
|
||||
float var6 = float(var5 >> 3) / 64.0f + 0.0078125f;
|
||||
float var8 = float(var5 & 7) / 8.0f + 0.0625f;
|
||||
|
||||
int var10 = hsl % 128;
|
||||
|
||||
float var11 = float(var10) / 128.0f;
|
||||
float var13 = var11;
|
||||
float var15 = var11;
|
||||
float var17 = var11;
|
||||
|
||||
if(var8 != 0.0f) {
|
||||
float var19;
|
||||
if(var11 < 0.5f) {
|
||||
var19 = var11 * (1.0f + var8);
|
||||
} else {
|
||||
var19 = var11 + var8 - var11 * var8;
|
||||
}
|
||||
|
||||
float var21 = 2.0f * var11 - var19;
|
||||
float var23 = var6 + 0.3333333333333333f;
|
||||
if(var23 > 1.0f) {
|
||||
var23 -= 1.f;
|
||||
}
|
||||
|
||||
float var27 = var6 - 0.3333333333333333f;
|
||||
if(var27 < 0.0f) {
|
||||
var27 += 1.f;
|
||||
}
|
||||
|
||||
if(6.0f * var23 < 1.0f) {
|
||||
var13 = var21 + (var19 - var21) * 6.0f * var23;
|
||||
} else if(2.0f * var23 < 1.0f) {
|
||||
var13 = var19;
|
||||
} else if(3.0f * var23 < 2.0f) {
|
||||
var13 = var21 + (var19 - var21) * (0.6666666666666666f - var23) * 6.0f;
|
||||
} else {
|
||||
var13 = var21;
|
||||
}
|
||||
|
||||
if(6.0f * var6 < 1.0f) {
|
||||
var15 = var21 + (var19 - var21) * 6.0f * var6;
|
||||
} else if(2.0f * var6 < 1.0f) {
|
||||
var15 = var19;
|
||||
} else if(3.0f * var6 < 2.0f) {
|
||||
var15 = var21 + (var19 - var21) * (0.6666666666666666f - var6) * 6.0f;
|
||||
} else {
|
||||
var15 = var21;
|
||||
}
|
||||
|
||||
if(6.0f * var27 < 1.0f) {
|
||||
var17 = var21 + (var19 - var21) * 6.0f * var27;
|
||||
} else if(2.0f * var27 < 1.0f) {
|
||||
var17 = var19;
|
||||
} else if(3.0f * var27 < 2.0f) {
|
||||
var17 = var21 + (var19 - var21) * (0.6666666666666666f - var27) * 6.0f;
|
||||
} else {
|
||||
var17 = var21;
|
||||
}
|
||||
}
|
||||
|
||||
vec3 rgb = vec3(
|
||||
pow(var13, brightness),
|
||||
pow(var15, brightness),
|
||||
pow(var17, brightness)
|
||||
);
|
||||
|
||||
// I don't think we actually need this
|
||||
if (rgb == vec3(0, 0, 0)) {
|
||||
rgb = vec3(0, 0, 1/255.f);
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec3 vertex = VertexPosition.xyz;
|
||||
int ahsl = VertexPosition.w;
|
||||
int hsl = ahsl & 0xffff;
|
||||
float a = float(ahsl >> 24 & 0xff) / 255.f;
|
||||
|
||||
vec3 rgb = hslToRgb(hsl);
|
||||
|
||||
vPosition = vertex;
|
||||
vColor = vec4(rgb, 1.f - a);
|
||||
vUv = uv;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#version 330
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(aPos, 1.0);
|
||||
TexCoord = aTexCoord;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
|
||||
import com.jogamp.nativewindow.NativeWindowFactory;
|
||||
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
|
||||
import com.jogamp.nativewindow.awt.JAWTWindow;
|
||||
import com.jogamp.opengl.GL4;
|
||||
import com.jogamp.opengl.GLCapabilities;
|
||||
import com.jogamp.opengl.GLContext;
|
||||
import com.jogamp.opengl.GLDrawable;
|
||||
import com.jogamp.opengl.GLDrawableFactory;
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import java.awt.Canvas;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.JFrame;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.inputStreamToString;
|
||||
import net.runelite.client.plugins.gpu.template.Template;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ShaderTest
|
||||
{
|
||||
private static final String VERTEX_SHADER = "" +
|
||||
"void main() {" +
|
||||
" gl_Position = vec4(1.0, 1.0, 1.0, 1.0);" +
|
||||
"}";
|
||||
private GL4 gl;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Canvas canvas = new Canvas();
|
||||
JFrame frame = new JFrame();
|
||||
frame.setSize(100, 100);
|
||||
frame.add(canvas);
|
||||
frame.setVisible(true);
|
||||
|
||||
GLProfile glProfile = GLProfile.getMaxFixedFunc(true);
|
||||
|
||||
GLCapabilities glCaps = new GLCapabilities(glProfile);
|
||||
AbstractGraphicsConfiguration config = AWTGraphicsConfiguration.create(canvas.getGraphicsConfiguration(),
|
||||
glCaps, glCaps);
|
||||
|
||||
JAWTWindow jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(canvas, config);
|
||||
|
||||
GLDrawableFactory glDrawableFactory = GLDrawableFactory.getFactory(glProfile);
|
||||
|
||||
GLDrawable glDrawable = glDrawableFactory.createGLDrawable(jawtWindow);
|
||||
glDrawable.setRealized(true);
|
||||
|
||||
|
||||
GLContext glContext = glDrawable.createContext(null);
|
||||
int res = glContext.makeCurrent();
|
||||
if (res == GLContext.CONTEXT_NOT_CURRENT)
|
||||
{
|
||||
fail("error making context current");
|
||||
}
|
||||
|
||||
gl = glContext.getGL().getGL4();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testSmall() throws ShaderException
|
||||
{
|
||||
int glComputeProgram = gl.glCreateProgram();
|
||||
int glComputeShader = gl.glCreateShader(gl.GL_COMPUTE_SHADER);
|
||||
try
|
||||
{
|
||||
Function<String, String> func = (s) -> inputStreamToString(getClass().getResourceAsStream(s));
|
||||
Template template = new Template(func);
|
||||
String source = template.process(func.apply("comp_small.glsl"));
|
||||
|
||||
int line = 0;
|
||||
for (String str : source.split("\\n"))
|
||||
{
|
||||
System.out.println(++line + " " + str);
|
||||
}
|
||||
|
||||
GLUtil.loadComputeShader(gl, glComputeProgram, glComputeShader, source);
|
||||
}
|
||||
finally
|
||||
{
|
||||
gl.glDeleteShader(glComputeShader);
|
||||
gl.glDeleteProgram(glComputeProgram);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testComp() throws ShaderException
|
||||
{
|
||||
int glComputeProgram = gl.glCreateProgram();
|
||||
int glComputeShader = gl.glCreateShader(gl.GL_COMPUTE_SHADER);
|
||||
try
|
||||
{
|
||||
Function<String, String> func = (s) -> inputStreamToString(getClass().getResourceAsStream(s));
|
||||
Template template = new Template(func);
|
||||
String source = template.process(func.apply("comp.glsl"));
|
||||
|
||||
int line = 0;
|
||||
for (String str : source.split("\\n"))
|
||||
{
|
||||
System.out.println(++line + " " + str);
|
||||
}
|
||||
|
||||
GLUtil.loadComputeShader(gl, glComputeProgram, glComputeShader, source);
|
||||
}
|
||||
finally
|
||||
{
|
||||
gl.glDeleteShader(glComputeShader);
|
||||
gl.glDeleteProgram(glComputeProgram);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testGeom() throws ShaderException
|
||||
{
|
||||
int glComputeProgram = gl.glCreateProgram();
|
||||
int glVertexShader = gl.glCreateShader(gl.GL_VERTEX_SHADER);
|
||||
int glGeometryShader = gl.glCreateShader(gl.GL_GEOMETRY_SHADER);
|
||||
int glFragmentShader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER);
|
||||
try
|
||||
{
|
||||
Function<String, String> func = (s) -> inputStreamToString(getClass().getResourceAsStream(s));
|
||||
Template template = new Template(func);
|
||||
String source = template.process(func.apply("geom.glsl"));
|
||||
|
||||
int line = 0;
|
||||
for (String str : source.split("\\n"))
|
||||
{
|
||||
System.out.println(++line + " " + str);
|
||||
}
|
||||
|
||||
GLUtil.loadShaders(gl, glComputeProgram, glVertexShader, glGeometryShader, glFragmentShader, VERTEX_SHADER, source, "");
|
||||
}
|
||||
finally
|
||||
{
|
||||
gl.glDeleteShader(glVertexShader);
|
||||
gl.glDeleteShader(glGeometryShader);
|
||||
gl.glDeleteShader(glFragmentShader);
|
||||
gl.glDeleteProgram(glComputeProgram);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu.template;
|
||||
|
||||
import java.util.function.Function;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TemplateTest
|
||||
{
|
||||
private static final String FILE1 = "" +
|
||||
"test1\n" +
|
||||
"#include file2\n" +
|
||||
"test3\n";
|
||||
|
||||
private static final String FILE2 = "" +
|
||||
"test4\n" +
|
||||
"test5\n";
|
||||
|
||||
private static final String RESULT = "" +
|
||||
"test1\n" +
|
||||
"test4\n" +
|
||||
"test5\n" +
|
||||
"test3\n";
|
||||
|
||||
@Test
|
||||
public void testProcess()
|
||||
{
|
||||
Function<String, String> func = (String resource) ->
|
||||
{
|
||||
switch (resource)
|
||||
{
|
||||
case "file2":
|
||||
return FILE2;
|
||||
default:
|
||||
throw new RuntimeException("unknown resource");
|
||||
}
|
||||
};
|
||||
String out = new Template(func).process(FILE1);
|
||||
assertEquals(RESULT, out);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user