Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions schemas/materials.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
"type": "boolean",
"description": "Whether 117 HD should skip lighting the material, largely preserving the vanilla look."
},
"isCanopy": {
"type": "boolean",
"description": "Is part of the canopy and will be faded if the face occludes the player."
},
"brightness": {
"type": "number",
"description": "A brightness multiplier for the material's color."
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/rs117/hd/HdPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ public ShaderIncludes getShaderIncludes() {
.define("MAX_LIGHT_COUNT", configTiledLighting ? UBOLights.MAX_LIGHTS : configDynamicLights.getMaxSceneLights())
.define("NORMAL_MAPPING", config.normalMapping())
.define("PARALLAX_OCCLUSION_MAPPING", config.parallaxOcclusionMapping())
.define("PLAYER_CANOPY_FADE", config.playerCanopy())
.define("SHADOW_MODE", configShadowMode)
.define("SHADOW_TRANSPARENCY", config.shadowTransparency())
.define("SHADOW_FILTERING", config.shadowFiltering())
Expand Down Expand Up @@ -1314,8 +1315,8 @@ public void updateSceneFbo() {
// Create depth render buffer
rboSceneDepth = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rboSceneDepth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_DEPTH_COMPONENT32F, sceneResolution[0], sceneResolution[1]);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboSceneDepth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_DEPTH24_STENCIL8, sceneResolution[0], sceneResolution[1]);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboSceneDepth);
checkGLErrors();

// If necessary, create an FBO for resolving multisampling
Expand All @@ -1329,6 +1330,11 @@ public void updateSceneFbo() {
checkGLErrors();
}

int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
log.error("FBO incomplete: {}\n", status);
}

// Reset
glBindFramebuffer(GL_FRAMEBUFFER, awtContext.getFramebuffer(false));
glBindRenderbuffer(GL_RENDERBUFFER, 0);
Expand Down Expand Up @@ -1781,6 +1787,7 @@ public void processPendingConfigChanges() {
case KEY_WIREFRAME:
case KEY_SHADOW_FILTERING:
case KEY_WINDOWS_HDR_CORRECTION:
case KEY_PLAYER_CANOPY:
recompilePrograms = true;
break;
case KEY_ANTI_ALIASING_MODE:
Expand Down
103 changes: 99 additions & 4 deletions src/main/java/rs117/hd/HdPluginConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
*/
package rs117.hd;

import java.awt.Color;
import net.runelite.client.config.Alpha;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
Expand All @@ -40,6 +42,8 @@
import rs117.hd.config.DynamicLights;
import rs117.hd.config.FogDepthMode;
import rs117.hd.config.InfernalCape;
import rs117.hd.config.NPCSilhouetteMode;
import rs117.hd.config.PlayerSilhouetteMode;
import rs117.hd.config.Saturation;
import rs117.hd.config.SceneScalingMode;
import rs117.hd.config.SeasonalHemisphere;
Expand Down Expand Up @@ -784,7 +788,7 @@ default boolean characterDisplacement() {
section = environmentSettings
)
default boolean hideVanillaWaterEffects() { return true; }

String KEY_POH_THEME_ENVIRONMENTS = "pohThemeEnvironments";
@ConfigItem(
keyName = KEY_POH_THEME_ENVIRONMENTS,
Expand All @@ -796,12 +800,103 @@ default boolean characterDisplacement() {
default boolean pohThemeEnvironments() { return true; }


/*====== Silhouette & Canopy settings ======*/

@ConfigSection(
name = "Silhouette & Canopy",
description = "Silhouette settings",
position = 4,
closedByDefault = true
)
String playerSilhouetteSettings = "playerSilhouetteSettings";

String KEY_PLAYER_CANOPY = "playerCanopy";
@ConfigItem(
keyName = KEY_PLAYER_CANOPY,
position = 0,
name = "Canopy Fade Enabled",
description = "Fades Canopy when it is occluding the player",
section = playerSilhouetteSettings
)
default boolean playerCanopy() {
return true;
}

String KEY_SILHOUETTE_THRESHOLD = "silhouetteThreshold";
@Units(Units.PERCENT)
@Range(min = 1, max = 100)
@ConfigItem(
keyName = KEY_SILHOUETTE_THRESHOLD,
position = 1,
name = "Silhouette Threshold",
description = "Threshold of how much of the actor is occluded, at which the silhouette should begin being drawn at (Default 50%)",
section = playerSilhouetteSettings
)
default int silhouetteThreshold() {
return 50;
}

String KEY_PLAYER_SILHOUETTE = "playerSilhouette";
@ConfigItem(
keyName = KEY_PLAYER_SILHOUETTE,
position = 2,
name = "Player Silhouette",
description = "Draws the players silhouette whilst they are occluded by scene geometry",
section = playerSilhouetteSettings
)
default PlayerSilhouetteMode playerSilhouette() { return PlayerSilhouetteMode.Player; }

String KEY_NPC_SILHOUETTE = "npcSilhouette";
@ConfigItem(
keyName = KEY_NPC_SILHOUETTE,
position = 3,
name = "NPC Silhouette",
description = "Draws the npcs silhouette whilst they are occluded by scene geometry",
section = playerSilhouetteSettings
)
default NPCSilhouetteMode npcSilhouette() { return NPCSilhouetteMode.Interacting; }

String KEY_PLAYER_SILHOUETTE_COLOR = "playerSilhouetteColor";
@Alpha
@ConfigItem(
keyName = KEY_PLAYER_SILHOUETTE_COLOR,
position = 4,
name = "Player Color",
description = "Controls the colour of the players silhouette",
section = playerSilhouetteSettings
)
default Color playerSilhouetteColor() { return new Color(20, 20, 20, 128); }

String KEY_FRIENDLY_PLAYER_SILHOUETTE_COLOR = "friendlyNpcSilhouetteColor";
@Alpha
@ConfigItem(
keyName = KEY_FRIENDLY_PLAYER_SILHOUETTE_COLOR,
position = 5,
name = "Friendly NPC Color",
description = "Controls the colour of the players silhouette",
section = playerSilhouetteSettings
)
default Color friendlyNpcSilhouetteColor() { return new Color(16, 44, 58, 128); }

String KEY_HOSTILE_NPC_SILHOUETTE_COLOR = "hostileNpcSilhouetteColor";
@Alpha
@ConfigItem(
keyName = KEY_HOSTILE_NPC_SILHOUETTE_COLOR,
position = 6,
name = "Hostile NPC Color",
description = "Controls the colour of the npcs silhouette",
section = playerSilhouetteSettings
)
default Color hostileNpcSilhouetteColor() {
return new Color(39, 5, 5, 128);
}

/*====== Miscellaneous settings ======*/

@ConfigSection(
name = "Miscellaneous",
description = "Miscellaneous settings",
position = 4,
position = 5,
closedByDefault = true
)
String miscellaneousSettings = "miscellaneousSettings";
Expand Down Expand Up @@ -955,7 +1050,7 @@ default boolean windowsHdrCorrection() {
@ConfigSection(
name = "Legacy",
description = "Legacy options. If you dislike a change, you might find an option to change it back here.",
position = 5,
position = 6,
closedByDefault = true
)
String legacySettings = "legacySettings";
Expand Down Expand Up @@ -1108,7 +1203,7 @@ default boolean legacyTzHaarReskin() {
@ConfigSection(
name = "Experimental",
description = "Experimental features - if you're experiencing issues you should consider disabling these.",
position = 6,
position = 7,
closedByDefault = true
)
String experimentalSettings = "experimentalSettings";
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/rs117/hd/config/NPCSilhouetteMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package rs117.hd.config;

public enum NPCSilhouetteMode {
Disabled,
Interacting,
Hostile,
All
}
8 changes: 8 additions & 0 deletions src/main/java/rs117/hd/config/PlayerSilhouetteMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package rs117.hd.config;

public enum PlayerSilhouetteMode {
Disabled,
Player,
Player_Follower,
Everyone
}
142 changes: 142 additions & 0 deletions src/main/java/rs117/hd/opengl/GLOcclusionQueries.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package rs117.hd.opengl;

import rs117.hd.utils.Destructible;

import static org.lwjgl.opengl.GL15.GL_QUERY_RESULT;
import static org.lwjgl.opengl.GL15.GL_QUERY_RESULT_AVAILABLE;
import static org.lwjgl.opengl.GL15.GL_SAMPLES_PASSED;
import static org.lwjgl.opengl.GL15.glBeginQuery;
import static org.lwjgl.opengl.GL15.glDeleteQueries;
import static org.lwjgl.opengl.GL15.glEndQuery;
import static org.lwjgl.opengl.GL15.glGenQueries;
import static org.lwjgl.opengl.GL15.glGetQueryObjecti;
import static org.lwjgl.opengl.GL33.GL_ANY_SAMPLES_PASSED;
import static org.lwjgl.opengl.GL33.GL_QUERY_NO_WAIT;
import static org.lwjgl.opengl.GL33.GL_QUERY_WAIT;
import static org.lwjgl.opengl.GL33.glBeginConditionalRender;
import static org.lwjgl.opengl.GL33.glEndConditionalRender;
import static rs117.hd.utils.MathUtils.*;

public final class GLOcclusionQueries implements Destructible {

private static final long ID_SHIFT = 32;
private static final long ISSUED_BIT = 1L << 31;
private static final long RESULT_MASK = 0x7FFFFFFFL;

private long query0, query1, query2;

private int currentQuery;
private int currentTarget;

private static long packId(int id) { return ((long) id) << ID_SHIFT; }

private static int getId(long packed) { return (int) (packed >>> ID_SHIFT); }

private static boolean isIssued(long packed) { return (packed & ISSUED_BIT) != 0; }

private static long setIssued(long packed) { return packed | ISSUED_BIT; }

private static long setResult(long packed, int result) { return (packed & ~RESULT_MASK) | (result & RESULT_MASK); }

private static int getResult(long packed) { return (int) (packed & RESULT_MASK); }

public void initialize() {
query0 = packId(glGenQueries());
query1 = packId(glGenQueries());
query2 = packId(glGenQueries());
}

private long getSlot(int idx) {
return idx == 0 ? query0 : idx == 1 ? query1 : query2;
}

private void setSlot(int idx, long value) {
if (idx == 0) query0 = value;
else if (idx == 1) query1 = value;
else query2 = value;
}

private int readbackIndex() { return (currentQuery + 1) % 3; }

public void beginQuery(boolean exactSamples) {
currentTarget = exactSamples ? GL_SAMPLES_PASSED : GL_ANY_SAMPLES_PASSED;
glBeginQuery(currentTarget, getId(getSlot(currentQuery)));
}

public void endQuery() {
glEndQuery(currentTarget);

long slot = setIssued(getSlot(currentQuery));
setSlot(currentQuery, slot);

currentQuery = (currentQuery + 1) % 3;
}

private void readBackResult() {
int idx = readbackIndex();
long slot = getSlot(idx);

if (!isIssued(slot))
return;

int id = getId(slot);

if (glGetQueryObjecti(id, GL_QUERY_RESULT_AVAILABLE) != 0) {
slot = setResult(slot, glGetQueryObjecti(id, GL_QUERY_RESULT));
setSlot(idx, slot);
}
}

public int getResult() {
readBackResult();
return getResult(getSlot(readbackIndex()));
}

public boolean isVisible() { return getResult() > 0; }

public int getVisiblePixels(int msaaSamples) {
int result = getResult();
return msaaSamples > 0 ? result / msaaSamples : result;
}

public float getVisibilityRatio(int proxyPixelArea, int msaaSamples) {
if (proxyPixelArea <= 0)
return 0f;

float samples = getResult();
if(samples == 0)
return 0f;

float denom = msaaSamples > 0
? proxyPixelArea * (float) msaaSamples
: proxyPixelArea;
float ratio = samples / denom;
return ratio < 0f ? 0f : min(ratio, 1f);
}

public void beginConditionalRender(boolean wait) {
int idx = readbackIndex();
long slot = getSlot(idx);

if (!isIssued(slot))
return;

glBeginConditionalRender(
getId(slot),
wait ? GL_QUERY_WAIT : GL_QUERY_NO_WAIT
);
}

public void endConditionalRender() { glEndConditionalRender(); }

public int getCurrentQuery() { return getId(getSlot(currentQuery)); }

@Override
public void destroy() {
if (query0 != 0) glDeleteQueries(getId(query0));
if (query1 != 0) glDeleteQueries(getId(query1));
if (query2 != 0) glDeleteQueries(getId(query2));

query0 = query1 = query2 = 0;
}
}
13 changes: 13 additions & 0 deletions src/main/java/rs117/hd/opengl/shader/BasicSceneProgram.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package rs117.hd.opengl.shader;

import static org.lwjgl.opengl.GL33C.*;

public class BasicSceneProgram extends ShaderProgram {
public Uniform4f uniColor = addUniform4f("color");

public BasicSceneProgram() {
super(t -> t
.add(GL_VERTEX_SHADER, "basic_scene_vert.glsl")
.add(GL_FRAGMENT_SHADER, "basic_scene_frag.glsl"));
}
}
11 changes: 11 additions & 0 deletions src/main/java/rs117/hd/opengl/shader/DepthSceneShaderProgram.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package rs117.hd.opengl.shader;

import static org.lwjgl.opengl.GL33C.*;

public class DepthSceneShaderProgram extends ShaderProgram {
public DepthSceneShaderProgram() {
super(t -> t
.add(GL_VERTEX_SHADER, "depth_scene_vert.glsl")
.add(GL_FRAGMENT_SHADER, "depth_scene_frag.glsl"));
}
}
Loading