Compare commits

..
17 Commits
Author SHA1 Message Date
Eclipse-Sol b27834cbd9 Narrow and make damage overlay a config option (#1886) 2026-06-27 10:12:39 -07:00
sisyphussyandJason Mitchell eb0ecb0483 Fix deps (#1888)
Co-authored-by: Jason Mitchell <[email protected]>
2026-06-27 10:11:30 -07:00
Caedis 9acb0e67a7 feat: add smooth zoom option (#1890) 2026-06-27 09:57:21 -07:00
Jason Mitchell f4f9b56b17 End portal fix (#1891) 2026-06-27 09:56:21 -07:00
Midnight145 2196439e6c ClientEvent framework (primarily written for LiteloaderLoader) (#1843) 2026-06-25 20:13:18 -07:00
RedNicStone dd68c64239 Fix map rendering issue in xaero's map mods (#1880) 2026-06-21 14:13:11 -07:00
Jason Mitchell 0decc515e4 Fix universium shader (#1877) 2026-06-18 23:42:21 -07:00
tiffit b3e1e89c88 Add new CTM mode "compact_expanded" to generate textures on runtime (#1840)
* Rewrite compact CTM to generate the textures ahead of time

* fix animated textures not working

* only interpolate if notfine is enabled

* some bugfixes

* bring back old compact ctm and make a new compact_expanded

* bug fixes
2026-06-18 12:04:45 +03:00
Jason Mitchell 32bff85526 Handle glDrawArraysInstanced and variants, as well as dynamic TE bounds. (#1874) 2026-06-17 20:18:07 -07:00
Auynonymous 02fc95f239 Make Glass CTM Compact, Add Stained Glass Compact CTM (#1873) 2026-06-17 16:00:58 -07:00
MalTeeez 07fd6d78a0 Separate out entity overlay render mixins (#1872) 2026-06-17 19:55:12 +00:00
Jason Mitchell 87aa853f81 Attempt to fix deferred particle batching (#1871) 2026-06-16 22:16:26 -07:00
Jason Mitchell ab69eea654 Announce releases (#1867) 2026-06-15 14:50:47 -07:00
Jason Mitchell edccf63b66 Bump glsl-transformation-lib and buildscript (#1865) 2026-06-14 18:09:05 -07:00
MalTeeez 80413fb3de Add policy for AI contributions & a PR template (#1864) 2026-06-15 01:40:03 +02:00
Jason Mitchell f3ed9aa82b Force invalidate dh depth tex when reconnecting DH Textures (#1862) 2026-06-14 14:59:01 -07:00
Jason Mitchell 307c563b6d Rework DH matrix handling (#1861) 2026-06-14 14:20:19 -07:00
218 changed files with 1303 additions and 247 deletions

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
# Description or your *PR* and other info
<!-- Please include a summary of the change -->
<!-- Any details that you think are important to review this PR? -->
<!-- Are there any Issues / PRs related to this one? -->
<!-- Add a screenshot or a video demonstration for new features -->
<details open><summary>Template</summary> <!-- OPEN is intentional -->
### Before submitting a *pull request* make sure you have:
- [ ] Read the [AI Contribution Policy](https://github.com/GTNewHorizons/Angelica/blob/master/AI_POLICY.md)
- [ ] At least [skimmed](https://github.com/GTNewHorizons/Angelica/search?q=is%3Apr&type=Issues) the tracker for similar pull requests
</details>
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
: "${REPO:?REPO required}"
: "${TAG:?TAG required}"
if [ -z "${DISCORD_WEBHOOK_URL:-}" ]; then
echo "DISCORD_WEBHOOK_URL not set, skipping"
exit 0
fi
if ! release_json=$(gh release view "$TAG" --repo "$REPO" --json body,url,publishedAt 2>&1); then
echo "Could not read release $TAG in $REPO; skipping:"
printf '%s\n' "$release_json"
exit 0
fi
body=$(jq -r '.body // ""' <<<"$release_json")
url=$(jq -r '.url' <<<"$release_json")
ts=$(jq -r '.publishedAt // ""' <<<"$release_json")
[ -n "$ts" ] || ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
payload=$(jq -n \
--arg title "$TAG" \
--arg url "$url" \
--arg desc "$body" \
--arg ts "$ts" \
'{
embeds: [{
title: ("Angelica " + $title + " released"),
url: $url,
description: (if ($desc | length) > 3900
then $desc[0:3900] + "\n\n...[full changelog](" + $url + ")"
else $desc end),
color: 3066993,
footer: { text: "GitHub Releases" },
timestamp: $ts
}]
}')
curl -fsS -X POST -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK_URL"
+19
View File
@@ -12,3 +12,22 @@ jobs:
release-tags:
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master
secrets: inherit
notify-discord:
needs: [release-tags]
runs-on: ubuntu-24.04
if: >-
${{ !endsWith(github.ref_name, '-snapshot')
&& !contains(github.event.head_commit.message, '[snapshot]')
&& !endsWith(github.ref_name, '-pre') }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Announce release to Discord
shell: bash
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
run: bash .github/scripts/announce-release.sh
+55
View File
@@ -0,0 +1,55 @@
# AI Usage Policy
This project has strict rules for AI usage:
* **The human-in-the-loop must fully understand all code.** If you
can't explain what your changes do and how they interact with the
greater system without the aid of AI tools, do not contribute
those changes.
* **Issues and discussions can use AI assistance but must have a full
human-in-the-loop.** This means that any content generated with AI
must have been reviewed *and edited* by a human before submission.
The author must do their research and trim this down.
* **No AI-generated media is allowed (textures, videos, audio, etc.).**
Text and code are the only acceptable AI-generated content, per the
other rules in this policy.
* **Commit messages, PR descriptions must read in your own voice.**
No AI-authored or AI co-authored commits, including Co-authored-by AI tags.
* **Only contribute fixes for bugs you have personally hit in-game.**
If you haven’t experienced or reproduced a bug firsthand, and don’t
already know the relevant code well, don’t throw AI at it and forward it to us.
Patches written for problems the author never actually experienced themselves
tend to fix the wrong thing and/or produce another.
* **The voice and intent of written content must be yours.**
For documentation and especially quests, the tone and the point you're trying to make
has to come from you, not an AI. Use AI to help with phrasing or cleanup if you like,
but if the substance and voice aren't yours, don't contribute it.
* **Bad AI use may be blocked.** People who produce bad contributions
that are clearly AI (slop) may be blocked from making future contributions.
We love to help junior developers learn and grow, but if you're interested
in that, don't use AI and we'll help you. We're sorry that bad AI
users have ruined this for you.
## There are Humans Here
Please remember that this project is maintained by humans.
Every discussion, issue, and pull request is read and reviewed by
humans (and sometimes machines, too). It is a boundary point at which
people interact with each other and work is done. It is rude and
disrespectful to approach this boundary with low-effort, unqualified
work, since it puts the burden of validation on the maintainer.
In a perfect world, AI would produce high-quality, accurate work
every time. But today, that reality depends on the user of the AI.
And today, many users of AI do not use it well. So, until that
changes, we need to have strict rules to protect maintainers.
Based on https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md
+5 -2
View File
@@ -76,14 +76,14 @@ dependencies {
// Iris Shaders
compileOnly('org.jetbrains:annotations:26.0.2')
api("com.github.GTNewHorizons:GTNHLib:0.11.4:dev")
api("com.github.GTNewHorizons:GTNHLib:0.11.19:dev")
shadowImplementation(project(":glsm")) { transitive = false }
shadowImplementation(project(":lwjgl3-backend")) { transitive = false }
shadowImplementation("net.minecraftforge:eventbus:7.0-beta.15")
shadowImplementation("org.anarres:jcpp:1.4.14") // Apache 2.0
shadowImplementation("org.taumc:glsl-transformation-lib:0.2.0-32.g7dd88a4-GTNH") {
shadowImplementation("org.taumc:glsl-transformation-lib:0.2.0-33.g3ec381e") {
exclude module: "antlr4" // we only want to shadow the runtime module
}
shadowImplementation("org.antlr:antlr4-runtime:4.13.2")
@@ -173,6 +173,9 @@ dependencies {
testImplementation('org.junit.platform:junit-platform-launcher')
testImplementation('com.tngtech.archunit:archunit-junit5:1.4.1')
testRuntimeOnly("it.unimi.dsi:fastutil:8.5.18")
testRuntimeOnly("org.joml:joml:1.10.8")
}
}
+2
View File
@@ -96,6 +96,8 @@ dependencies {
// Deps (normally from MC) - compile only, but needed at test runtime
compileOnly("com.google.guava:guava:${property("guavaVersion")}")
testRuntimeOnly("com.google.guava:guava:${property("guavaVersion")}")
testRuntimeOnly("it.unimi.dsi:fastutil:${property("fastutilVersion")}")
testRuntimeOnly("org.joml:joml:${property("jomlVersion")}") { isTransitive = false }
// Test
testImplementation(sourceSets["stubs"].output)
+3 -1
View File
@@ -4,7 +4,9 @@ celeritasVersion = 2.5.3-GTNH
lombokVersion = 1.18.42
log4jVersion = 2.0-beta9
guavaVersion = 18.0
gtnhlibVersion = 0.10.0
gtnhlibVersion = 0.11.19
fastutilVersion = 8.5.18
jomlVersion = 1.10.8
glslTransformLibVersion = 0.2.0-26.g5ee7d96-GTNH
antlr4RuntimeVersion = 4.13.2
jcppVersion = 1.4.14
@@ -59,7 +59,10 @@ public class CompatUniformManager {
static final int MAT_FIELDS = 5;
static final int LOC_MAT_BASE = LOC_LIGHT_BASE + 2 * LIGHT_FIELDS; // 43
static final int LOC_COUNT = LOC_MAT_BASE + MAT_FIELDS; // 48
static final int LOC_IRIS_MODELVIEW_INVERSE = LOC_MAT_BASE + MAT_FIELDS; // 48
static final int LOC_IRIS_PROJECTION_INVERSE = LOC_IRIS_MODELVIEW_INVERSE + 1; // 49
static final int LOC_COUNT = LOC_IRIS_PROJECTION_INVERSE + 1; // 50
private static final String[] LIGHT_FIELD_NAMES = {
"ambient", "diffuse", "specular", "position", "halfVector",
@@ -89,6 +92,8 @@ public class CompatUniformManager {
UNIFORM_NAMES[LOC_IRIS_NORMAL] = "iris_NormalMatrix";
UNIFORM_NAMES[LOC_IRIS_LIGHTMAP_TEXTURE_MATRIX] = "iris_LightmapTextureMatrix";
UNIFORM_NAMES[LOC_IRIS_TEXTURE_MATRIX] = "iris_TextureMatrix";
UNIFORM_NAMES[LOC_IRIS_MODELVIEW_INVERSE] = "iris_ModelViewMatrixInverse";
UNIFORM_NAMES[LOC_IRIS_PROJECTION_INVERSE] = "iris_ProjectionMatrixInverse";
UNIFORM_NAMES[LOC_ALPHA_TEST_REF] = "angelica_currentAlphaTest";
UNIFORM_NAMES[LOC_SCENE_COLOR] = "angelica_SceneColor";
UNIFORM_NAMES[LOC_CLIP_PLANES] = "angelica_ClipPlane[0]";
@@ -229,10 +234,15 @@ public class CompatUniformManager {
}
// ModelView Inverse
if (locs[LOC_MODELVIEW_INVERSE] != -1) {
if (locs[LOC_MODELVIEW_INVERSE] != -1 || locs[LOC_IRIS_MODELVIEW_INVERSE] != -1) {
mv.invert(scratchMatrix);
scratchMatrix.get(mat4Buf);
RENDER_BACKEND.uniformMatrix4(locs[LOC_MODELVIEW_INVERSE], false, mat4Buf);
if (locs[LOC_MODELVIEW_INVERSE] != -1) {
RENDER_BACKEND.uniformMatrix4(locs[LOC_MODELVIEW_INVERSE], false, mat4Buf);
}
if (locs[LOC_IRIS_MODELVIEW_INVERSE] != -1) {
RENDER_BACKEND.uniformMatrix4(locs[LOC_IRIS_MODELVIEW_INVERSE], false, mat4Buf);
}
}
}
@@ -266,10 +276,15 @@ public class CompatUniformManager {
}
// Projection Inverse
if (locs[LOC_PROJECTION_INVERSE] != -1) {
if (locs[LOC_PROJECTION_INVERSE] != -1 || locs[LOC_IRIS_PROJECTION_INVERSE] != -1) {
proj.invert(scratchMatrix);
scratchMatrix.get(mat4Buf);
RENDER_BACKEND.uniformMatrix4(locs[LOC_PROJECTION_INVERSE], false, mat4Buf);
if (locs[LOC_PROJECTION_INVERSE] != -1) {
RENDER_BACKEND.uniformMatrix4(locs[LOC_PROJECTION_INVERSE], false, mat4Buf);
}
if (locs[LOC_IRIS_PROJECTION_INVERSE] != -1) {
RENDER_BACKEND.uniformMatrix4(locs[LOC_IRIS_PROJECTION_INVERSE], false, mat4Buf);
}
}
}
@@ -56,6 +56,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Matrix4fStack;
import org.joml.Vector3d;
import org.joml.Vector3f;
@@ -186,6 +187,14 @@ public class GLStateManager {
private static boolean dirtyTexCoordAttrib;
private static boolean dirtyLightmapAttrib = true;
private static boolean unit23TexCoordSetDuringDraw = false;
public static boolean consumeUnit23TexCoordSetDuringDraw() {
boolean v = unit23TexCoordSetDuringDraw;
unit23TexCoordSetDuringDraw = false;
return v;
}
// vertexFlags bits mark attribs the VBO already supplies; FFP supplies the rest via u_Current* uniforms.
// Skip the backend vertexAttrib call in either case.
public static void flushDeferredVertexAttribs(boolean hasColor, boolean hasNormal, boolean hasTexCoord, boolean hasLightmap) {
@@ -637,6 +646,9 @@ public class GLStateManager {
RENDER_BACKEND.bindVertexArray(defaultVAO);
boundVAO = defaultVAO;
VAOManager.init(defaultVAO);
if (defaultVAO != 0) {
RENDER_BACKEND.provokingVertex(GL32.GL_LAST_VERTEX_CONVENTION);
}
if (initCallback != null) {
initCallback.run();
}
@@ -2154,6 +2166,7 @@ public class GLStateManager {
}
public static void glBegin(int mode) {
unit23TexCoordSetDuringDraw = false;
if (DisplayListManager.isRecording()) {
ImmediateModeRecorder.begin(mode);
return;
@@ -2236,6 +2249,10 @@ public class GLStateManager {
FeedbackManager.processDrawElements(mode, indices);
return;
}
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTriangles(indices.remaining(), GL11.GL_UNSIGNED_BYTE, indices);
return;
}
preDraw(mode);
RENDER_BACKEND.drawElements(mode, indices);
}
@@ -2349,10 +2366,29 @@ public class GLStateManager {
}
public static void glDrawElementsInstanced(int mode, int count, int type, long indices, int primcount) {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTrianglesInstanced(count, type, indices, primcount);
return;
}
preDraw(mode);
RENDER_BACKEND.drawElementsInstanced(mode, count, type, indices, primcount);
}
public static void glDrawArraysInstanced(int mode, int first, int count, int primcount) {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadsAsTrianglesInstanced(first, count, primcount);
} else if (mode == GL11.GL_QUAD_STRIP) {
preDraw();
RENDER_BACKEND.drawArraysInstanced(GL11.GL_TRIANGLE_STRIP, first, count & ~1, primcount);
} else if (mode == GL11.GL_POLYGON) {
preDraw();
RENDER_BACKEND.drawArraysInstanced(GL11.GL_TRIANGLE_FAN, first, count, primcount);
} else {
preDraw(mode);
RENDER_BACKEND.drawArraysInstanced(mode, first, count, primcount);
}
}
private static void prepareClientArrays() {
if (VAOManager.hasAnyClientSideEnabledAttrib()) {
VAOManager.uploadClientArraysToVBO();
@@ -3437,6 +3473,21 @@ public class GLStateManager {
}
}
public static void setModelViewMatrix(Matrix4fc m) {
if (isCachingEnabled()) {
modelViewMatrix.set(m);
mvGeneration++;
mvLinearGeneration++;
}
}
public static void setProjectionMatrix(Matrix4fc m) {
if (isCachingEnabled()) {
projectionMatrix.set(m);
projGeneration++;
}
}
public static Matrix4fStack getMatrixStack() {
switch (matrixMode.getMode()) {
case GL11.GL_MODELVIEW -> {
@@ -5283,6 +5334,9 @@ public class GLStateManager {
} else {
final int unit = target - GL13.GL_TEXTURE0;
if (unit >= 2 && unit < 4) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
unit23TexCoordSetDuringDraw = true;
}
ShaderManager.setCurrentTexCoord(unit, s, t, 0.0f, 1.0f);
}
}
@@ -5988,15 +6042,15 @@ public class GLStateManager {
}
public static void glUniform1(int location, IntBuffer values) {
if (values.remaining() >= 1) RENDER_BACKEND.uniform1i(location, values.get(values.position()));
RENDER_BACKEND.uniform1iv(location, values);
}
public static void glUniform2(int location, FloatBuffer values) {
if (values.remaining() >= 2) RENDER_BACKEND.uniform2f(location, values.get(values.position()), values.get(values.position() + 1));
RENDER_BACKEND.uniform2(location, values);
}
public static void glUniform2(int location, IntBuffer values) {
if (values.remaining() >= 2) RENDER_BACKEND.uniform2i(location, values.get(values.position()), values.get(values.position() + 1));
RENDER_BACKEND.uniform2iv(location, values);
}
public static void glUniform3(int location, FloatBuffer values) {
@@ -6004,7 +6058,7 @@ public class GLStateManager {
}
public static void glUniform3(int location, IntBuffer values) {
if (values.remaining() >= 3) RENDER_BACKEND.uniform3i(location, values.get(values.position()), values.get(values.position() + 1), values.get(values.position() + 2));
RENDER_BACKEND.uniform3iv(location, values);
}
public static void glUniform4(int location, FloatBuffer values) {
@@ -6012,7 +6066,7 @@ public class GLStateManager {
}
public static void glUniform4(int location, IntBuffer values) {
if (values.remaining() >= 4) RENDER_BACKEND.uniform4i(location, values.get(values.position()), values.get(values.position() + 1), values.get(values.position() + 2), values.get(values.position() + 3));
RENDER_BACKEND.uniform4iv(location, values);
}
public static void glUniformMatrix2(int location, boolean transpose, FloatBuffer matrices) {
@@ -83,6 +83,14 @@ public final class QuadConverter {
* @param vertexCount number of vertices (must be multiple of 4)
*/
public static void drawQuadsAsTriangles(int first, int vertexCount) {
drawSharedQuadEbo(first, vertexCount, 1, false);
}
public static void drawQuadsAsTrianglesInstanced(int first, int vertexCount, int primcount) {
drawSharedQuadEbo(first, vertexCount, primcount, true);
}
private static void drawSharedQuadEbo(int first, int vertexCount, int primcount, boolean instanced) {
GLStateManager.preDraw();
assert first % 4 == 0 : "QuadConverter: first (" + first + ") must be a multiple of 4";
assert vertexCount % 4 == 0 : "QuadConverter: vertexCount (" + vertexCount + ") must be a multiple of 4";
@@ -92,7 +100,11 @@ public final class QuadConverter {
RENDER_BACKEND.bindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, eboId);
// Index offset: first vertex / 4 quads * 6 indices * 4 bytes per int
final long indexOffset = (long) (first / 4) * 6 * 4;
RENDER_BACKEND.drawElements(GL11.GL_TRIANGLES, quadCount * 6, INDEX_TYPE, indexOffset);
if (instanced) {
RENDER_BACKEND.drawElementsInstanced(GL11.GL_TRIANGLES, quadCount * 6, INDEX_TYPE, indexOffset, primcount);
} else {
RENDER_BACKEND.drawElements(GL11.GL_TRIANGLES, quadCount * 6, INDEX_TYPE, indexOffset);
}
RENDER_BACKEND.bindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, prevEbo);
}
@@ -107,6 +119,10 @@ public final class QuadConverter {
* @param bytesPerIndex bytes per index element
*/
private static void uploadAndDraw(ByteBuffer dst, int triIndexCount, int indexType, int bytesPerIndex) {
uploadAndDraw(dst, triIndexCount, indexType, bytesPerIndex, 1, false);
}
private static void uploadAndDraw(ByteBuffer dst, int triIndexCount, int indexType, int bytesPerIndex, int primcount, boolean instanced) {
GLStateManager.preDraw();
final int needed = triIndexCount * bytesPerIndex;
final int prevEbo = GLStateManager.getBoundEBO();
@@ -126,7 +142,11 @@ public final class QuadConverter {
}
RENDER_BACKEND.bufferSubData(GL15.GL_ELEMENT_ARRAY_BUFFER, 0, dst);
RENDER_BACKEND.drawElements(GL11.GL_TRIANGLES, triIndexCount, indexType, 0L);
if (instanced) {
RENDER_BACKEND.drawElementsInstanced(GL11.GL_TRIANGLES, triIndexCount, indexType, 0L, primcount);
} else {
RENDER_BACKEND.drawElements(GL11.GL_TRIANGLES, triIndexCount, indexType, 0L);
}
RENDER_BACKEND.bindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, prevEbo);
memFree(dst);
@@ -141,6 +161,14 @@ public final class QuadConverter {
* @param offset byte offset into the currently bound EBO
*/
public static void drawQuadElementsAsTriangles(int indexCount, int type, long offset) {
drawQuadElementsFromEbo(indexCount, type, offset, 1, false);
}
public static void drawQuadElementsAsTrianglesInstanced(int indexCount, int type, long offset, int primcount) {
drawQuadElementsFromEbo(indexCount, type, offset, primcount, true);
}
private static void drawQuadElementsFromEbo(int indexCount, int type, long offset, int primcount, boolean instanced) {
if (indexCount == 0) return;
assert indexCount % 4 == 0 : "QuadConverter: indexCount must be multiple of 4";
final int quadCount = indexCount / 4;
@@ -155,7 +183,7 @@ public final class QuadConverter {
triangulateQuads(memAddress0(src), type, memAddress0(dst), GL11.GL_UNSIGNED_INT, quadCount);
memFree(src);
uploadAndDraw(dst, triIndexCount, GL11.GL_UNSIGNED_INT, 4);
uploadAndDraw(dst, triIndexCount, GL11.GL_UNSIGNED_INT, 4, primcount, instanced);
}
/**
@@ -310,6 +310,16 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL31.glDrawElementsInstanced(mode, count, type, indices, primcount);
}
@Override
public void drawArraysInstanced(int mode, int first, int count, int primcount) {
GL31.glDrawArraysInstanced(mode, first, count, primcount);
}
@Override
public void provokingVertex(int provokeMode) {
GL32.glProvokingVertex(provokeMode);
}
@Override
public void multiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride) {
org.lwjgl.opengl.GL43.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
@@ -812,6 +822,11 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL20.glUniform4i(location, v0, v1, v2, v3);
}
@Override
public void uniform2(int location, FloatBuffer value) {
GL20.glUniform2(location, value);
}
@Override
public void uniform3(int location, FloatBuffer value) {
GL20.glUniform3(location, value);
@@ -822,6 +837,26 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL20.glUniform4(location, value);
}
@Override
public void uniform1iv(int location, IntBuffer value) {
GL20.glUniform1(location, value);
}
@Override
public void uniform2iv(int location, IntBuffer value) {
GL20.glUniform2(location, value);
}
@Override
public void uniform3iv(int location, IntBuffer value) {
GL20.glUniform3(location, value);
}
@Override
public void uniform4iv(int location, IntBuffer value) {
GL20.glUniform4(location, value);
}
@Override
public void uniformMatrix3(int location, boolean transpose, FloatBuffer value) {
GL20.glUniformMatrix3(location, transpose, value);
@@ -87,6 +87,8 @@ public abstract class RenderBackend {
public abstract void multiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride);
public abstract void copyBufferSubData(int readTarget, int writeTarget, long readOffset, long writeOffset, long size);
public abstract void drawElementsInstanced(int mode, int count, int type, long indices, int primcount);
public abstract void drawArraysInstanced(int mode, int first, int count, int primcount);
public void provokingVertex(int provokeMode) {}
public abstract void drawElementsBaseVertex(int mode, int count, int type, long indices, int baseVertex);
public abstract void multiDrawElementsBaseVertex(int mode, long pCount, int type, long pIndices, int drawcount, long pBaseVertex);
public abstract void drawBuffer(int mode);
@@ -199,8 +201,13 @@ public abstract class RenderBackend {
public abstract void uniform3i(int location, int v0, int v1, int v2);
public abstract void uniform4f(int location, float v0, float v1, float v2, float v3);
public abstract void uniform4i(int location, int v0, int v1, int v2, int v3);
public abstract void uniform2(int location, FloatBuffer value);
public abstract void uniform3(int location, FloatBuffer value);
public abstract void uniform4(int location, FloatBuffer value);
public abstract void uniform1iv(int location, IntBuffer value);
public abstract void uniform2iv(int location, IntBuffer value);
public abstract void uniform3iv(int location, IntBuffer value);
public abstract void uniform4iv(int location, IntBuffer value);
public abstract void uniformMatrix3(int location, boolean transpose, FloatBuffer value);
public abstract void uniformMatrix4(int location, boolean transpose, FloatBuffer value);
public void uniformMatrix2(int location, boolean transpose, FloatBuffer matrices) {}
@@ -78,7 +78,7 @@ public final class FragmentShaderGenerator {
private static void emitTextureSampling(StringBuilder sb, FragmentKey key) {
for (int i = 0; i < key.nrEnabledUnits(); i++) {
if (!key.unitEnabled(i)) continue;
sb.append(" vec4 tex").append(i).append("Color = texture(u_Sampler").append(i).append(", v_TexCoord").append(i).append(".st);\n");
sb.append(" vec4 tex").append(i).append("Color = textureProj(u_Sampler").append(i).append(", v_TexCoord").append(i).append(");\n");
}
}
@@ -49,6 +49,7 @@ public final class VertexKey {
private static final int BIT_WIDE_LINE = 36;
// Per-unit texmat enable: bits 37-40 (unit 0..3). Unit 1 is the lightmap matrix.
private static final int BIT_UNIT_TEXMAT_BASE = 37;
private static final int BIT_UNIT23_UV_FROM_UNIT0 = 41;
public static final int TG_NONE = 0;
public static final int TG_OBJ_LINEAR = 1;
@@ -85,6 +86,7 @@ public final class VertexKey {
public boolean hasVertexNormal() { return bit(BIT_HAS_VERTEX_NORMAL); }
public boolean hasVertexTexCoord() { return bit(BIT_HAS_VERTEX_TEX); }
public boolean hasVertexLightmap() { return bit(BIT_HAS_VERTEX_LIGHTMAP); }
public boolean unit23UvFromUnit0() { return bit(BIT_UNIT23_UV_FROM_UNIT0); }
/** Color material mode (CM_AMBIENT, CM_DIFFUSE, CM_SPECULAR, CM_EMISSION, CM_AMBIENT_AND_DIFFUSE). Only meaningful when colorMaterialEnabled(). */
public int colorMaterialMode() { return (int)((packed >> BIT_COLOR_MAT_MODE) & 0x7); }
@@ -213,6 +215,10 @@ public final class VertexKey {
if (hasTexCoord) bits |= (1L << BIT_HAS_VERTEX_TEX);
if (hasLightmap) bits |= (1L << BIT_HAS_VERTEX_LIGHTMAP);
if (GLStateManager.consumeUnit23TexCoordSetDuringDraw() && hasTexCoord) {
bits |= (1L << BIT_UNIT23_UV_FROM_UNIT0);
}
if (GLStateManager.anyClipPlaneEnabled()) {
bits |= (1L << BIT_CLIP_PLANES);
}
@@ -106,8 +106,8 @@ public final class VertexShaderGenerator {
if (key.unitTexCoordEnabled(0) && !key.hasVertexTexCoord()) {
sb.append("uniform vec4 u_CurrentTexCoord0;\n");
}
if (key.unitTexCoordEnabled(2)) sb.append("uniform vec4 u_CurrentTexCoord2;\n");
if (key.unitTexCoordEnabled(3)) sb.append("uniform vec4 u_CurrentTexCoord3;\n");
if (key.unitTexCoordEnabled(2) && !key.unit23UvFromUnit0()) sb.append("uniform vec4 u_CurrentTexCoord2;\n");
if (key.unitTexCoordEnabled(3) && !key.unit23UvFromUnit0()) sb.append("uniform vec4 u_CurrentTexCoord3;\n");
if (key.lightmapEnabled() && !key.hasVertexLightmap()) {
sb.append("uniform vec2 u_CurrentLightmapCoord;\n");
@@ -363,8 +363,10 @@ public final class VertexShaderGenerator {
for (int i = 2; i < VertexKey.MAX_UNITS; i++) {
if (!key.unitTexCoordEnabled(i)) continue;
final String src = "u_CurrentTexCoord" + i;
if (key.unitTexMatEnabled(i)) {
final String src = key.unit23UvFromUnit0()
? "vec4(a_TexCoord0, 0.0, 1.0)"
: "u_CurrentTexCoord" + i;
if (!key.unit23UvFromUnit0() && key.unitTexMatEnabled(i)) {
sb.append(" v_TexCoord").append(i).append(" = u_TextureMatrix").append(i).append(" * ").append(src).append(";\n");
} else {
sb.append(" v_TexCoord").append(i).append(" = ").append(src).append(";\n");
@@ -383,7 +385,7 @@ public final class VertexShaderGenerator {
emitTexGenComponent(sb, key.texGenModeS(), "s", "S", key);
emitTexGenComponent(sb, key.texGenModeT(), "t", "T", key);
emitTexGenComponent(sb, key.texGenModeR(), "r", "R", key);
emitTexGenComponent(sb, key.texGenModeR(), "p", "R", key);
emitTexGenComponent(sb, key.texGenModeQ(), "q", "Q", key);
// Always apply texture matrix when texgen is active (forced on in VertexKey)
@@ -46,6 +46,8 @@ public class GLSMRedirector {
private static final String ARBMultiTexture = "org/lwjgl/opengl/ARBMultitexture";
private static final String ARBShaderObjects = "org/lwjgl/opengl/ARBShaderObjects";
private static final String ARBInstancedArrays = "org/lwjgl/opengl/ARBInstancedArrays";
private static final String ARBDrawInstanced = "org/lwjgl/opengl/ARBDrawInstanced";
private static final String EXTDrawInstanced = "org/lwjgl/opengl/EXTDrawInstanced";
// Redirect VAO related calls from NHLib
private static final String UniversalVAO = "com/gtnewhorizon/gtnhlib/client/opengl/UniversalVAO";
@@ -356,7 +358,8 @@ public class GLSMRedirector {
.add("glGetFramebufferAttachmentParameteri")
.add("glBlitFramebuffer");
final var gl31 = RedirectMap.newMap()
.add("glDrawElementsInstanced");
.add("glDrawElementsInstanced")
.add("glDrawArraysInstanced");
final var gl32 = RedirectMap.newMap()
.add("glFramebufferTexture");
final var gl33 = RedirectMap.newMap()
@@ -459,6 +462,14 @@ public class GLSMRedirector {
methodRedirects.put(ARBInstancedArrays, RedirectMap.newMap()
.add("glVertexAttribDivisorARB")
);
methodRedirects.put(ARBDrawInstanced, RedirectMap.newMap()
.add("glDrawArraysInstancedARB", "glDrawArraysInstanced")
.add("glDrawElementsInstancedARB", "glDrawElementsInstanced")
);
methodRedirects.put(EXTDrawInstanced, RedirectMap.newMap()
.add("glDrawArraysInstancedEXT", "glDrawArraysInstanced")
.add("glDrawElementsInstancedEXT", "glDrawElementsInstanced")
);
// APPLE
methodRedirects.put(APPLEVertexArrayObject, RedirectMap.newMap()
@@ -0,0 +1,103 @@
package com.gtnewhorizons.angelica.glsm;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(GLSMCoreExtension.class)
class ArrayUniformUploadGLTest {
private static int compile(int type, String src) {
final int s = GL20.glCreateShader(type);
GL20.glShaderSource(s, src);
GL20.glCompileShader(s);
assertEquals(GL11.GL_TRUE, GL20.glGetShaderi(s, GL20.GL_COMPILE_STATUS), () -> "shader compile failed: " + GL20.glGetShaderInfoLog(s, 4096));
return s;
}
private static int link(String vs, String fs) {
final int v = compile(GL20.GL_VERTEX_SHADER, vs);
final int f = compile(GL20.GL_FRAGMENT_SHADER, fs);
final int p = GL20.glCreateProgram();
GL20.glAttachShader(p, v);
GL20.glAttachShader(p, f);
GL20.glLinkProgram(p);
assertEquals(GL11.GL_TRUE, GL20.glGetProgrami(p, GL20.GL_LINK_STATUS), () -> "link failed: " + GL20.glGetProgramInfoLog(p, 4096));
GL20.glDeleteShader(v);
GL20.glDeleteShader(f);
return p;
}
private static final String VS = "#version 330 core\nvoid main(){ gl_Position = vec4(0.0); }\n";
@Test
void glUniform2FloatBufferUploadsWholeArray() {
// Runtime index keeps the whole array active so element locations stay queryable.
final String fs = "#version 330 core\n"
+ "uniform vec2 cosmicuvs[10];\n"
+ "uniform int idx;\n"
+ "out vec4 o;\n"
+ "void main(){ o = vec4(cosmicuvs[idx], cosmicuvs[(idx+1)%10]); }\n";
final int p = link(VS, fs);
try {
GL20.glUseProgram(p);
final FloatBuffer buf = BufferUtils.createFloatBuffer(20);
for (int i = 0; i < 20; i++) buf.put(i + 1.0f); // 1..20, all distinct, all non-zero
buf.flip();
GLStateManager.glUniform2(GL20.glGetUniformLocation(p, "cosmicuvs"), buf);
final FloatBuffer read = BufferUtils.createFloatBuffer(2);
for (int i = 0; i < 10; i++) {
final int loc = GL20.glGetUniformLocation(p, "cosmicuvs[" + i + "]");
assertTrue(loc >= 0, "element " + i + " optimized out");
read.clear();
GL20.glGetUniform(p, loc, read);
assertEquals(2 * i + 1.0f, read.get(0), 0.0f, "cosmicuvs[" + i + "].x");
assertEquals(2 * i + 2.0f, read.get(1), 0.0f, "cosmicuvs[" + i + "].y");
}
} finally {
GL20.glUseProgram(0);
GL20.glDeleteProgram(p);
}
}
@Test
void glUniform1IntBufferUploadsWholeArray() {
final String fs = "#version 330 core\n"
+ "uniform int vals[4];\n"
+ "uniform int idx;\n"
+ "out vec4 o;\n"
+ "void main(){ o = vec4(float(vals[idx])); }\n";
final int p = link(VS, fs);
try {
GL20.glUseProgram(p);
final IntBuffer buf = BufferUtils.createIntBuffer(4);
buf.put(11).put(22).put(33).put(44).flip();
GLStateManager.glUniform1(GL20.glGetUniformLocation(p, "vals"), buf);
final IntBuffer read = BufferUtils.createIntBuffer(1);
final int[] expect = {11, 22, 33, 44};
for (int i = 0; i < 4; i++) {
final int loc = GL20.glGetUniformLocation(p, "vals[" + i + "]");
assertTrue(loc >= 0, "element " + i + " optimized out");
read.clear();
GL20.glGetUniform(p, loc, read);
assertEquals(expect[i], read.get(0), "vals[" + i + "]");
}
} finally {
GL20.glUseProgram(0);
GL20.glDeleteProgram(p);
}
}
}
@@ -21,7 +21,7 @@ class CompatUniformManagerTest {
void cleanup() {
if (program != 0) {
GL20.glUseProgram(0);
GL20.glDeleteProgram(program);
GLStateManager.glDeleteProgram(program);
program = 0;
}
}
@@ -1,7 +1,5 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.GLDebug;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMInitConfig;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
@@ -0,0 +1,105 @@
package com.gtnewhorizons.angelica.glsm;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ExtendWith(GLSMCoreExtension.class)
class InstancedQuadDrawGLTest {
private static final String VS = "#version 330 core\nlayout(location=0) in vec2 aPos;\nvoid main(){ gl_Position = vec4(aPos, 0.0, 1.0); }\n";
private static final String FS = "#version 330 core\nout vec4 o;\nvoid main(){ o = vec4(1.0); }\n";
private int program;
private int vbo;
private int ebo;
@BeforeEach
void setup() {
program = buildProgram();
GLStateManager.glUseProgram(program);
final FloatBuffer verts = BufferUtils.createFloatBuffer(8);
verts.put(new float[] {0, 0, 1, 0, 1, 1, 0, 1}).flip();
vbo = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, verts, GL15.GL_STATIC_DRAW);
GLStateManager.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0L);
GLStateManager.glEnableVertexAttribArray(0);
final IntBuffer idx = BufferUtils.createIntBuffer(4);
idx.put(new int[] {0, 1, 2, 3}).flip();
ebo = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GLStateManager.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, idx, GL15.GL_STATIC_DRAW);
drainErrors();
}
@AfterEach
void cleanup() {
GLStateManager.glUseProgram(0);
if (program != 0) GL20.glDeleteProgram(program);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
if (vbo != 0) GLStateManager.glDeleteBuffers(vbo);
if (ebo != 0) GLStateManager.glDeleteBuffers(ebo);
drainErrors();
}
@Test
void drawArraysInstanced_quads_noInvalidEnum() {
GLStateManager.glDrawArraysInstanced(GL11.GL_QUADS, 0, 4, 3);
assertEquals(GL11.GL_NO_ERROR, GL11.glGetError(), "GL_QUADS instanced array draw must be emulated, not rejected");
}
@Test
void drawArraysInstanced_triangles_fastPathClean() {
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GLStateManager.glDrawArraysInstanced(GL11.GL_TRIANGLES, 0, 3, 3);
assertEquals(GL11.GL_NO_ERROR, GL11.glGetError(), "non-quad instanced array draw passes through cleanly");
}
@Test
void drawElementsInstanced_quads_noInvalidEnum() {
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GLStateManager.glDrawElementsInstanced(GL11.GL_QUADS, 4, GL11.GL_UNSIGNED_INT, 0L, 3);
assertEquals(GL11.GL_NO_ERROR, GL11.glGetError(), "GL_QUADS instanced element draw must be emulated, not rejected");
}
private static int buildProgram() {
final int vs = compile(GL20.GL_VERTEX_SHADER, VS);
final int fs = compile(GL20.GL_FRAGMENT_SHADER, FS);
final int p = GL20.glCreateProgram();
GL20.glAttachShader(p, vs);
GL20.glAttachShader(p, fs);
GL20.glLinkProgram(p);
assertNotEquals(0, GL20.glGetProgrami(p, GL20.GL_LINK_STATUS), "test shader must link: " + GL20.glGetProgramInfoLog(p, 1024));
GL20.glDeleteShader(vs);
GL20.glDeleteShader(fs);
return p;
}
private static int compile(int type, String src) {
final int s = GL20.glCreateShader(type);
GL20.glShaderSource(s, src);
GL20.glCompileShader(s);
assertNotEquals(0, GL20.glGetShaderi(s, GL20.GL_COMPILE_STATUS), "test shader must compile: " + GL20.glGetShaderInfoLog(s, 1024));
return s;
}
private static void drainErrors() {
while (GL11.glGetError() != GL11.GL_NO_ERROR) { /* clear */ }
}
}
+4
View File
@@ -34,6 +34,10 @@ repositories {
name = "GTNH Maven"
url = uri("https://nexus.gtnewhorizons.com/repository/public/")
}
maven {
name = "Minecraft Libraries"
url = uri("https://libraries.minecraft.net")
}
maven {
name = "Forge"
url = uri("https://maven.minecraftforge.net/")
@@ -348,6 +348,16 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL31C.glDrawElementsInstanced(mode, count, type, indices, primcount);
}
@Override
public void drawArraysInstanced(int mode, int first, int count, int primcount) {
GL31C.glDrawArraysInstanced(mode, first, count, primcount);
}
@Override
public void provokingVertex(int provokeMode) {
GL32C.glProvokingVertex(provokeMode);
}
@Override
public void multiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride) {
GL43C.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
@@ -856,6 +866,11 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL20C.glUniform4i(location, v0, v1, v2, v3);
}
@Override
public void uniform2(int location, FloatBuffer value) {
GL20C.glUniform2fv(location, value);
}
@Override
public void uniform3(int location, FloatBuffer value) {
GL20C.glUniform3fv(location, value);
@@ -866,6 +881,26 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL20C.glUniform4fv(location, value);
}
@Override
public void uniform1iv(int location, IntBuffer value) {
GL20C.glUniform1iv(location, value);
}
@Override
public void uniform2iv(int location, IntBuffer value) {
GL20C.glUniform2iv(location, value);
}
@Override
public void uniform3iv(int location, IntBuffer value) {
GL20C.glUniform3iv(location, value);
}
@Override
public void uniform4iv(int location, IntBuffer value) {
GL20C.glUniform4iv(location, value);
}
@Override
public void uniformMatrix3(int location, boolean transpose, FloatBuffer value) {
GL20C.glUniformMatrix3fv(location, transpose, value);
+1 -1
View File
@@ -16,7 +16,7 @@ pluginManagement {
}
plugins {
id("com.gtnewhorizons.gtnhsettingsconvention") version ("2.0.25")
id("com.gtnewhorizons.gtnhsettingsconvention") version ("2.0.26")
}
include("glsm")
@@ -25,6 +25,7 @@ public class DeferredDrawBatcher {
@Getter private static boolean active = false;
private static DeferredBatchTessellator batchTessellator;
private static long entryStateKey;
private DeferredDrawBatcher() {}
@@ -41,13 +42,14 @@ public class DeferredDrawBatcher {
batchTessellator.clearRanges();
batchTessellator.setParentTessellator(Tessellator.instance);
batchTessellator.snapshotDefaultModelview();
entryStateKey = captureStateKey();
TessellatorManager.startCapturingDirect(batchTessellator);
}
/**
* Exit deferred mode and flush all captured batches. Groups entries by state key
* and vertex format, issues one draw per unique group. Restores the GL state that
* was active for the last group so vanilla sees consistent state.
* and vertex format, issues one draw per unique group. Restores the bracket's entry
* state so the trailing vanilla Tessellator.draw() renders with the layer atlas.
*/
public static void exitAndFlush() {
active = false;
@@ -56,6 +58,7 @@ public class DeferredDrawBatcher {
if (!ranges.isEmpty()) {
ranges.sort(Comparator.comparingLong(DeferredBatchTessellator.DrawRange::stateKey));
flushSorted(ranges);
applyStateKey(entryStateKey);
}
TessellatorManager.stopCapturingDirect();
@@ -147,7 +150,8 @@ public class DeferredDrawBatcher {
* - fog state (mode, color, start/end — constant for the frame)
*/
static long captureStateKey() {
final int textureId = GLStateManager.getTextures().getTextureUnitBindings(0).getBinding();
final int activeUnit = GLStateManager.getActiveTextureUnit();
final int textureId = GLStateManager.getTextures().getTextureUnitBindings(activeUnit).getBinding();
final int srcRgb = GLStateManager.getBlendState().getSrcRgb();
final int dstRgb = GLStateManager.getBlendState().getDstRgb();
final boolean blendEnabled = GLStateManager.getBlendMode().isEnabled();
@@ -269,6 +269,13 @@ public class AngelicaConfig {
@Config.DefaultStringList({"jewelrycraft2:blockCrystal"})
public static String[] alwaysTranslucentSprites;
@Config.Comment({"TileEntity classnames whose render bounds change at runtime (e.g. OpenBlocks Guide).",
"These are always rendered and frustum-tested against their live bounds instead of the cached."})
@Config.DefaultStringList({"openblocks.common.tileentity.TileEntityGuide",
"openblocks.common.tileentity.TileEntityBuilderGuide"})
@Config.RequiresMcRestart
public static String[] dynamicBoundsTileEntities;
@Config.Comment("Register HardcodedCustomUniforms in Iris Shaders. May help with compatibility in certain shader packs")
@Config.DefaultBoolean(false)
public static boolean enableHardcodedCustomUniforms;
@@ -350,4 +357,13 @@ public class AngelicaConfig {
@Config.RequiresMcRestart
public static boolean disableErrorChecks;
@Config.Comment("Fixes various issues with entity overlays, such as z-fighting and eyes.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean entityOverlayFixes;
@Config.Comment("Swap the vanilla damage overlay with one similar to modern. Fixes specific issues with z-fighting.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean entityModernDamageOverlay;
}
@@ -0,0 +1,36 @@
package com.gtnewhorizons.angelica.event;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraftforge.eventbus.api.bus.EventBus;
import net.minecraftforge.eventbus.api.event.MutableEvent;
public class ClientEvent extends MutableEvent {
public static final EventBus<ClientEvent> BUS = EventBus.create(ClientEvent.class);
public final ClientEventType event;
public final EntityRenderer renderer;
public final float partialTicks;
private ClientEvent(ClientEventType event) {
this.event = event;
this.renderer = null;
this.partialTicks = 0;
}
private ClientEvent(ClientEventType event, EntityRenderer renderer, float partialTicks) {
this.event = event;
this.renderer = renderer;
this.partialTicks = partialTicks;
}
public static void post(ClientEventType event, EntityRenderer renderer, float partialTicks) {
if (!BUS.hasListeners()) return;
BUS.post(new ClientEvent(event, renderer, partialTicks));
}
public static void post(ClientEventType event) {
if (!BUS.hasListeners()) return;
BUS.post(new ClientEvent(event));
}
}
@@ -0,0 +1,8 @@
package com.gtnewhorizons.angelica.event;
public enum ClientEventType {
PRE_RENDER_GUI,
PRE_RENDER_HUD,
POST_RENDER_HUD,
ON_TICK,
}
@@ -6,11 +6,12 @@ import com.gtnewhorizon.gtnhlib.client.renderer.postprocessing.CustomFramebuffer
import com.gtnewhorizon.gtnhlib.client.renderer.postprocessing.SharedDepthFramebuffer;
import com.gtnewhorizon.gtnhlib.client.renderer.vao.IVertexArrayObject;
import com.gtnewhorizon.gtnhlib.client.renderer.vao.VertexBufferType;
import com.gtnewhorizon.gtnhlib.client.renderer.vbo.IVertexBuffer;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.DefaultVertexFormat;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.compat.holoinventory.HoloInventoryReflectionCompat;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.event.ClientEvent;
import com.gtnewhorizons.angelica.event.ClientEventType;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMConfig;
import com.gtnewhorizons.angelica.mixins.interfaces.GuiIngameAccessor;
@@ -65,6 +66,8 @@ public class HUDCaching {
}
public static void renderCachedHud(EntityRenderer renderer, GuiIngame ingame, float partialTicks, boolean hasScreen, int mouseX, int mouseY) {
ClientEvent.post(ClientEventType.PRE_RENDER_GUI, renderer, partialTicks);
ClientEvent.post(ClientEventType.PRE_RENDER_HUD, renderer, partialTicks);
if (ModStatus.isXaerosMinimapLoaded && ingame instanceof GuiIngameForge) {
// this used to be called by asming into renderGameOverlay, but we removed it
XaeroMinimapCore.beforeIngameGuiRender(partialTicks);
@@ -78,6 +81,7 @@ public class HUDCaching {
if (!AngelicaConfig.hudCachingActive || mc.displayWidth < 16 || mc.displayHeight < 16) {
ingame.renderGameOverlay(partialTicks, hasScreen, mouseX, mouseY);
ClientEvent.post(ClientEventType.POST_RENDER_HUD, renderer, partialTicks);
return;
}
@@ -170,6 +174,8 @@ public class HUDCaching {
GLStateManager.tryBlendFuncSeparate(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
mc.getTextureManager().bindTexture(Gui.icons);
ClientEvent.post(ClientEventType.POST_RENDER_HUD, renderer, partialTicks);
}
/**
@@ -47,9 +47,7 @@ public enum Mixins implements IMixins {
, "angelica.bugfixes.MixinRenderGlobal_DestroyBlock"
, "angelica.bugfixes.MixinRenderMooshroom_MushroomTint"
, "angelica.bugfixes.MixinRendererLivingEntity_DeferredEntityOverlay"
, "angelica.bugfixes.MixinRendererLivingEntity_OverlayTint"
, "angelica.bugfixes.MixinRenderWither_ArmorCentering"
, "angelica.bugfixes.MixinRendererLivingEntity_EyeDepth"
, "angelica.debug.MixinMinecraft_FPSCap"
, "angelica.ffp.MixinTessellator_CoreProfile"
, "angelica.glsm.MixinSplashProgressCaching"
@@ -60,6 +58,24 @@ public enum Mixins implements IMixins {
)
),
ANGELICA_ENTITY_OVERLAYS(new MixinBuilder()
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.entityOverlayFixes)
.addExcludedMod(TargetedMod.CUSTOM_PLAYER_MODELS)
.addClientMixins(
"angelica.bugfixes.MixinRendererLivingEntity_EyeDepth"
)
),
ANGELICA_DAMAGE_OVERLAY(new MixinBuilder()
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.entityModernDamageOverlay)
.addExcludedMod(TargetedMod.CUSTOM_PLAYER_MODELS)
.addClientMixins(
"angelica.bugfixes.MixinRendererLivingEntity_OverlayTint"
)
),
ANGELICA_VBO_CLOUDS(
new MixinBuilder()
.setApplyIf(() -> AngelicaConfig.enableVBOClouds)
@@ -28,6 +28,7 @@ public enum TargetedMod implements ITargetMod {
TINKERS_CONSTRUCT(null, "TConstruct"),
TWILIGHT_FOREST(null, "TwilightForest"),
BIOMES_O_PLENTY(null, "BiomesOPlenty"),
CUSTOM_PLAYER_MODELS("com.tom.cpmcore.CPMLoadingPlugin", "customplayermodels"),
WITCHERY(null, "witchery");
private final TargetModBuilder builder;
@@ -5,5 +5,5 @@ import net.minecraft.util.AxisAlignedBB;
public interface ITileEntityBoundingBoxCache {
AxisAlignedBB angelica$getCachedRenderBoundingBox();
boolean angelica$isInfiniteExtent();
byte angelica$boundsClass();
}
@@ -9,6 +9,7 @@ import com.gtnewhorizons.angelica.common.BlockError;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.compat.bettercrashes.BetterCrashesCompat;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.rendering.TileEntityRenderBoundsRegistry;
import com.gtnewhorizons.angelica.config.CompatConfig;
import com.gtnewhorizons.angelica.config.ConfigMigrator;
import com.gtnewhorizons.angelica.debug.F3Direction;
@@ -102,6 +103,7 @@ public final class ClientProxy extends CommonProxy {
@Override
public void preInit(FMLPreInitializationEvent event) {
ModStatus.preInit();
for (String name : AngelicaConfig.dynamicBoundsTileEntities) TileEntityRenderBoundsRegistry.registerDynamicClass(name);
super.preInit(event);
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
@@ -4,48 +4,60 @@ import it.unimi.dsi.fastutil.objects.Reference2ByteOpenHashMap;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Registry for tracking which TileEntity classes always return INFINITE_EXTENT_AABB.
* Registry for tracking which TileEntity classes always return INFINITE_EXTENT_AABB or are known to change at runtime
*/
public final class TileEntityRenderBoundsRegistry {
private static final byte UNKNOWN = 0;
private static final byte FINITE = 1;
private static final byte INFINITE = 2;
public static final byte STATIC = 1;
public static final byte INFINITE = 2;
public static final byte DYNAMIC = 3;
private static final Reference2ByteOpenHashMap<Class<? extends TileEntity>> classRegistry = new Reference2ByteOpenHashMap<>();
private static final Set<String> dynamicClassNames = ConcurrentHashMap.newKeySet();
static {
classRegistry.defaultReturnValue(UNKNOWN);
}
private TileEntityRenderBoundsRegistry() {}
public static void registerDynamicClass(String className) {
if (className != null && !className.isEmpty()) dynamicClassNames.add(className);
}
public static boolean isInfiniteExtentsBox(AxisAlignedBB box) {
return box == null || Double.isInfinite(box.minX) || Double.isInfinite(box.minY) || Double.isInfinite(box.minZ) || Double.isInfinite(box.maxX) || Double.isInfinite(box.maxY) || Double.isInfinite(box.maxZ);
}
public static boolean isAlwaysInfiniteExtent(TileEntity te) {
public static byte classify(TileEntity te) {
final Class<? extends TileEntity> clazz = te.getClass();
synchronized (classRegistry) {
final byte result = classRegistry.getByte(clazz);
if (result != UNKNOWN) return result == INFINITE;
final byte cached = classRegistry.getByte(clazz);
if (cached != UNKNOWN) return cached;
}
return probeAndCache(te, clazz);
}
private static boolean probeAndCache(TileEntity te, Class<? extends TileEntity> clazz) {
boolean isInfinite;
try {
final AxisAlignedBB aabb = te.getRenderBoundingBox();
isInfinite = isInfiniteExtentsBox(aabb);
} catch (Throwable t) {
isInfinite = true;
final byte result;
if (dynamicClassNames.contains(clazz.getName())) {
result = DYNAMIC;
} else {
boolean isInfinite;
try {
isInfinite = isInfiniteExtentsBox(te.getRenderBoundingBox());
} catch (Throwable t) {
isInfinite = true;
}
result = isInfinite ? INFINITE : STATIC;
}
synchronized (classRegistry) {
classRegistry.put(clazz, isInfinite ? INFINITE : FINITE);
classRegistry.put(clazz, result);
}
return isInfinite;
return result;
}
public static void clear() {
@@ -151,7 +151,8 @@ public abstract class AngelicaChunkBuilderMeshingTask extends ChunkBuilderTask<C
final TileEntity tileEntity = region.getTileEntity(x, y, z);
if (tileEntity != null && TileEntityRendererDispatcher.instance.hasSpecialRenderer(tileEntity)) {
final boolean isGlobal;
if (TileEntityRenderBoundsRegistry.isAlwaysInfiniteExtent(tileEntity)) {
final byte boundsClass = TileEntityRenderBoundsRegistry.classify(tileEntity);
if (boundsClass == TileEntityRenderBoundsRegistry.INFINITE || boundsClass == TileEntityRenderBoundsRegistry.DYNAMIC) {
isGlobal = true;
} else {
AxisAlignedBB aabb;
@@ -346,8 +346,9 @@ public class CeleritasWorldRenderer extends SimpleWorldRenderer<WorldClient, Ang
final ITileEntityBoundingBoxCache teCache = (ITileEntityBoundingBoxCache) tileEntity;
if (!teCache.angelica$isInfiniteExtent()) {
final AxisAlignedBB aabb = teCache.angelica$getCachedRenderBoundingBox();
final byte boundsClass = teCache.angelica$boundsClass();
if (boundsClass != TileEntityRenderBoundsRegistry.INFINITE) {
final AxisAlignedBB aabb = boundsClass == TileEntityRenderBoundsRegistry.DYNAMIC ? tileEntity.getRenderBoundingBox() : teCache.angelica$getCachedRenderBoundingBox();
if (aabb != null && !this.currentViewport.isBoxVisible(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ)) {
return;
}
@@ -4,6 +4,8 @@ import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import jss.notfine.core.Settings;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
@@ -19,6 +21,13 @@ public class Zoom {
@Getter
private static float zoom = ZOOM_DEFAULT;
public static final float ZOOM_SMOOTH_SNAP_EPSILON = 0.001F;
@Getter
private static float currentZoom = 1.0F;
private static long zoomLerpLastNano = 0L;
@Getter
private static final KeyBinding zoomKey = new KeyBinding("Zoom", 0, "key.categories.misc");
@@ -38,6 +47,29 @@ public class Zoom {
zoom = MathHelper.clamp_float((float) (zoom * Math.pow(ZOOM_STEP, Integer.signum(eventDWheel))), ZOOM_MIN, ZOOM_MAX);
}
public static void updateZoomLerp() {
final long now = System.nanoTime();
float dt = zoomLerpLastNano == 0L ? 0.0F : (now - zoomLerpLastNano) / 1.0e9F;
zoomLerpLastNano = now;
final float target = zoomEnabled ? zoom : 1.0F;
if (dt <= 0.0F || !(boolean) Settings.ZOOM_SMOOTH.option.getStore()) {
currentZoom = target;
return;
}
// Clamp dt so a long frame (alt-tab, GC pause) does not snap the zoom.
dt = Math.min(dt, 0.1F);
final int rate = (int) Settings.ZOOM_SMOOTH_SPEED.option.getStore();
currentZoom += (target - currentZoom) * (1.0F - (float) Math.exp(-dt * rate));
if (Math.abs(target - currentZoom) < ZOOM_SMOOTH_SNAP_EPSILON) {
currentZoom = target;
}
}
private static void resetMouseFilters(Minecraft mc) {
if (mc.entityRenderer != null) {
((IMouseFilterExt) mc.entityRenderer.mouseFilterXAxis).angelica$reset();
@@ -79,4 +111,10 @@ public class Zoom {
handleKeyEvent();
}
}
@SubscribeEvent
public void onRenderTick(TickEvent.RenderTickEvent e) {
if (e.phase != TickEvent.Phase.START) return;
updateZoomLerp();
}
}
@@ -0,0 +1,99 @@
package com.prupe.mcpatcher.ctm;
import com.prupe.mcpatcher.ctm.TileOverrideImpl.CTMCompactExpanded;
import com.prupe.mcpatcher.mal.tile.TileLoader;
import net.minecraft.util.ResourceLocation;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
public class CTMTextureGenerator {
public static void generateTextures(BufferedImage[] compactIcons, CTMCompactExpanded override,
ResourceLocation propsLoc, ResourceLocation blankResource){
BufferedImage cFull = compactIcons[0]; // Full
BufferedImage cNone = compactIcons[1]; // None
BufferedImage cVert = compactIcons[2]; // Vertical
BufferedImage cHori = compactIcons[3]; // Horizontal
BufferedImage cCorn = compactIcons[4]; // Corner
BufferedImage[] expanded = new BufferedImage[47];
// Generate all 47 textures to match normal CTM
expanded[0] = cFull;
expanded[1] = generate(cFull, cHori, cFull, cHori);
expanded[2] = cHori;
expanded[3] = generate(cHori, cFull, cHori, cFull);
expanded[4] = generate(cFull, cHori, cVert, cCorn);
expanded[5] = generate(cHori, cFull, cCorn, cVert);
expanded[6] = generate(cVert, cCorn, cVert, cCorn);
expanded[7] = generate(cHori, cHori, cCorn, cCorn);
expanded[8] = generate(cCorn, cNone, cCorn, cCorn);
expanded[9] = generate(cCorn, cCorn, cCorn, cNone);
expanded[10] = generate(cNone, cCorn, cNone, cCorn);
expanded[11] = generate(cNone, cNone, cCorn, cCorn);
expanded[12] = generate(cFull, cFull, cVert, cVert);
expanded[13] = generate(cFull, cHori, cVert, cNone);
expanded[14] = generate(cHori, cHori, cNone, cNone);
expanded[15] = generate(cHori, cFull, cNone, cVert);
expanded[16] = generate(cVert, cCorn, cFull, cHori);
expanded[17] = generate(cCorn, cVert, cHori, cFull);
expanded[18] = generate(cCorn, cCorn, cHori, cHori);
expanded[19] = generate(cCorn, cVert, cCorn, cVert);
expanded[20] = generate(cNone, cCorn, cCorn, cCorn);
expanded[21] = generate(cCorn, cCorn, cNone, cCorn);
expanded[22] = generate(cCorn, cCorn, cNone, cNone);
expanded[23] = generate(cCorn, cNone, cCorn, cNone);
expanded[24] = cVert;
expanded[25] = generate(cVert, cNone, cVert, cNone);
expanded[26] = cNone;
expanded[27] = generate(cNone, cVert, cNone, cVert);
expanded[28] = generate(cVert, cCorn, cVert, cNone);
expanded[29] = generate(cHori, cHori, cNone, cCorn);
expanded[30] = generate(cVert, cNone, cVert, cCorn);
expanded[31] = generate(cHori, cHori, cCorn, cNone);
expanded[32] = generate(cNone, cNone, cNone, cCorn);
expanded[33] = generate(cNone, cNone, cCorn, cNone);
expanded[34] = generate(cCorn, cNone, cNone, cCorn);
expanded[35] = generate(cNone, cCorn, cCorn, cNone);
expanded[36] = generate(cVert, cVert, cFull, cFull);
expanded[37] = generate(cVert, cNone, cFull, cHori);
expanded[38] = generate(cNone, cNone, cHori, cHori);
expanded[39] = generate(cNone, cVert, cHori, cFull);
expanded[40] = generate(cCorn, cNone, cHori, cHori);
expanded[41] = generate(cNone, cVert, cNone, cVert);
expanded[42] = generate(cNone, cCorn, cHori, cHori);
expanded[43] = generate(cCorn, cVert, cNone, cVert);
expanded[44] = generate(cNone, cCorn, cNone, cNone);
expanded[45] = generate(cCorn, cNone, cNone, cNone);
expanded[46] = cCorn;
for (int i = 0; i < expanded.length; i++){
ResourceLocation resource =
TileLoader.parseTileAddress(propsLoc, String.valueOf(i), blankResource);
override.addIcon(resource, expanded[i]);
}
}
private static BufferedImage generate(BufferedImage tl, BufferedImage tr, BufferedImage bl, BufferedImage br){
int w = tl.getWidth();
int hw = w/2;
BufferedImage img = new BufferedImage(tl.getWidth(), tl.getHeight(), BufferedImage.TYPE_INT_ARGB);
int numFrames = tl.getHeight() / tl.getWidth();
Graphics2D g = img.createGraphics();
for (int i = 0; i < numFrames; i++){
int yOff = w * i;
copy(tl, g, 0, yOff, hw);
copy(tr, g, hw, yOff, hw);
copy(bl, g, 0, yOff + hw, hw);
copy(br, g, hw, yOff + hw, hw);
}
g.dispose();
return img;
}
private static void copy(BufferedImage src, Graphics2D g, int x, int y, int s){
g.drawImage(src, x, y, x+s, y+s, x, y, x+s, y+s, null);
}
}
@@ -10,12 +10,12 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.StampedLock;
import com.github.bsideup.jabel.Desugar;
import net.minecraft.block.Block;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import com.github.bsideup.jabel.Desugar;
import com.prupe.mcpatcher.MCLogger;
import com.prupe.mcpatcher.MCPatcherUtils;
import com.prupe.mcpatcher.mal.block.BlockAPI;
@@ -32,7 +32,7 @@ import jss.notfine.config.MCPatcherForgeConfig;
public class CTMUtils {
private static final MCLogger logger = MCLogger.getLogger(MCLogger.Category.CONNECTED_TEXTURES, "CTM");
public static final MCLogger logger = MCLogger.getLogger(MCLogger.Category.CONNECTED_TEXTURES, "CTM");
private static class Overrides {
private final List<TileOverride> all = new ArrayList<>();
@@ -0,0 +1,77 @@
package com.prupe.mcpatcher.ctm;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.prupe.mcpatcher.mal.tile.TileLoader;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import jss.notfine.render.InterpolatedIcon;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.SimpleResource;
import net.minecraft.client.resources.data.AnimationMetadataSection;
import net.minecraft.util.ResourceLocation;
import java.awt.image.BufferedImage;
@SideOnly(Side.CLIENT)
public class GeneratedCTMAtlasSprite extends InterpolatedIcon {
private final TileLoader loader;
private final boolean aniFiltering;
private boolean interpolated;
public GeneratedCTMAtlasSprite(TileLoader loader, boolean aniFiltering, String name) {
super(name);
this.loader = loader;
this.aniFiltering = aniFiltering;
}
@Override
protected void updateAnimationInterpolated() throws IllegalArgumentException, IllegalAccessException {
if(interpolated) super.updateAnimationInterpolated();
}
@Override
public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) {
return true;
}
@Override
public boolean load(IResourceManager manager, ResourceLocation location) {
BufferedImage img = loader.getImageForPath(location);
if(img == null) return true;
try {
ResourceLocation metaLoc = getMetaLoc(location);
IResource iresource = manager.getResource(metaLoc);
AnimationMetadataSection anim = (AnimationMetadataSection)iresource.getMetadata("animation");
interpolated = anim != null && AngelicaConfig.enableNotFineFeatures && shouldInterpolate(iresource);
loadSprite(new BufferedImage[]{img, null, null, null, null}, anim, aniFiltering);
}catch (Exception exception){
CTMUtils.logger.error("Error loading sprite for " + location);
exception.printStackTrace();
return true;
}
return false;
}
private static boolean shouldInterpolate(IResource resource){
try {
if (resource instanceof SimpleResource simple) {
return simple.mcmetaJson.getAsJsonObject("animation")
.getAsJsonPrimitive("interpolate").getAsBoolean();
}
}catch (Exception _){}
return false;
}
/**
* Find the mcmeta file associated with 0.png
*/
private static ResourceLocation getMetaLoc(ResourceLocation location) {
String path = location.getResourcePath();
int index = path.lastIndexOf('/');
if(index == -1) return new ResourceLocation(location.getResourceDomain(), "0.png");
path = path.substring(0, index) + "/0.png";
return new ResourceLocation(location.getResourceDomain(), path);
}
}
@@ -5,6 +5,7 @@ import static com.prupe.mcpatcher.ctm.RenderBlockState.CONNECT_BY_MATERIAL;
import static com.prupe.mcpatcher.ctm.RenderBlockState.CONNECT_BY_TILE;
import static com.prupe.mcpatcher.ctm.RenderBlockState.NORMALS;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashSet;
@@ -32,10 +33,10 @@ public abstract class TileOverride implements Comparable<TileOverride> {
private static final MCLogger logger = MCLogger.getLogger(MCLogger.Category.CONNECTED_TEXTURES, "CTM");
private final PropertiesFile properties;
protected final PropertiesFile properties;
private final String baseFilename;
private final TileLoader tileLoader;
private final int renderPass;
protected final TileLoader tileLoader;
protected final int renderPass;
private final int weight;
private final List<BlockStateMatcher> matchBlocks;
private final Set<String> matchTiles;
@@ -45,7 +46,7 @@ public abstract class TileOverride implements Comparable<TileOverride> {
private final BitSet biomes;
private final BitSet height;
private final List<ResourceLocation> tileNames = new ArrayList<>();
protected final List<ResourceLocation> tileNames = new ArrayList<>();
protected IIcon[] icons;
// Index into this array is formed from these bit values:
@@ -103,6 +104,7 @@ public abstract class TileOverride implements Comparable<TileOverride> {
case "sandstone", "top" -> override = new TileOverrideImpl.Top(properties, tileLoader);
case "repeat", "pattern" -> override = new TileOverrideImpl.Repeat(properties, tileLoader);
case "ctm_compact", "compact" -> override = new TileOverrideImpl.CTMCompact(properties, tileLoader);
case "compact_expanded" -> override = new TileOverrideImpl.CTMCompactExpanded(properties, tileLoader);
default -> properties.error("unknown method \"%s\"", method);
}
@@ -196,7 +198,12 @@ public abstract class TileOverride implements Comparable<TileOverride> {
return tileLoader.preloadTile(resource, renderPass > RenderPassAPI.MAX_BASE_RENDER_PASS);
}
private void loadIcons() {
public void addIcon(ResourceLocation resource, BufferedImage img){
tileNames.add(resource);
tileLoader.addTile(resource, img, null, true);
}
protected void loadIcons() {
tileNames.clear();
String tileList = properties.getString("tiles", "");
ResourceLocation blankResource = RenderPassAPI.instance.getBlankResource(renderPass);
@@ -221,16 +228,7 @@ public abstract class TileOverride implements Comparable<TileOverride> {
try {
int from = Integer.parseInt(matcher.group(1));
int to = Integer.parseInt(matcher.group(2));
for (int i = from; i <= to; i++) {
ResourceLocation resource = TileLoader
.parseTileAddress(properties.getResource(), String.valueOf(i), blankResource);
if (TexturePackAPI.hasResource(resource)) {
addIcon(resource);
} else {
properties.warning("could not find image %s", resource);
tileNames.add(null);
}
}
loadOverrideIcons(from, to, blankResource);
} catch (NumberFormatException e) {
e.printStackTrace();
}
@@ -250,6 +248,19 @@ public abstract class TileOverride implements Comparable<TileOverride> {
}
}
protected void loadOverrideIcons(int from, int to, ResourceLocation blankResource){
for (int i = from; i <= to; i++) {
ResourceLocation resource = TileLoader
.parseTileAddress(properties.getResource(), String.valueOf(i), blankResource);
if (TexturePackAPI.hasResource(resource)) {
addIcon(resource);
} else {
properties.warning("could not find image %s", resource);
tileNames.add(null);
}
}
}
private List<BlockStateMatcher> getBlockList(String property, String defaultMetadata) {
List<BlockStateMatcher> blocks = new ArrayList<>();
if (!MCPatcherUtils.isNullOrEmpty(defaultMetadata)) {
@@ -12,15 +12,22 @@ import static com.prupe.mcpatcher.ctm.RenderBlockState.REL_UL;
import static com.prupe.mcpatcher.ctm.RenderBlockState.REL_UR;
import static com.prupe.mcpatcher.ctm.RenderBlockState.TOP_FACE;
import com.prupe.mcpatcher.mal.block.RenderPassAPI;
import com.prupe.mcpatcher.mal.resource.TexturePackAPI;
import net.minecraft.util.IIcon;
import com.prupe.mcpatcher.mal.resource.PropertiesFile;
import com.prupe.mcpatcher.mal.tile.TileLoader;
import com.prupe.mcpatcher.mal.util.WeightedIndex;
import net.minecraft.util.ResourceLocation;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class TileOverrideImpl {
final static class CTM extends TileOverride {
static class CTM extends TileOverride {
CTM(PropertiesFile properties, TileLoader tileLoader) {
super(properties, tileLoader);
@@ -505,4 +512,48 @@ public class TileOverrideImpl {
return p;
}
}
final public static class CTMCompactExpanded extends CTM {
CTMCompactExpanded(PropertiesFile propertiesFile, TileLoader tileLoader) {
super(propertiesFile, tileLoader);
}
@Override
String checkTileMap() {
return null;
}
@Override
String getMethod() {
return "compact_expanded";
}
@Override
protected void loadOverrideIcons(int from, int to, ResourceLocation blankResource) {
List<BufferedImage> compactIcons = new ArrayList<>();
if(from != 0){
properties.error("expanded compact CTM requires range to start at 0, starts at %d", from);
}
if(to - from + 1 != 5){
properties.error("expanded compact CTM requires exactly 5 icons, got range %d - %d", from, to);
}
for (int i = from; i <= to; i++) {
ResourceLocation resource = TileLoader
.parseTileAddress(properties.getResource(), String.valueOf(i), blankResource);
if (TexturePackAPI.hasResource(resource)) {
compactIcons.add(tileLoader.loadResourceImage(resource,
renderPass > RenderPassAPI.MAX_BASE_RENDER_PASS));
} else {
// Promote from warning to error for compact CTM
properties.error("could not find image %s, required for expanded compact CTM", resource);
tileNames.add(null);
}
}
if(compactIcons.size() == 5){
CTMTextureGenerator.generateTextures(compactIcons.toArray(new BufferedImage[0]),
this, properties.getResource(), blankResource);
}
}
}
}
@@ -11,6 +11,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.prupe.mcpatcher.ctm.GeneratedCTMAtlasSprite;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
@@ -44,6 +45,7 @@ public class TileLoader {
private TextureMap baseTextureMap;
private final Map<String, TextureAtlasSprite> baseTexturesByName = new HashMap<>();
private final Set<ResourceLocation> tilesToRegister = new HashSet<>();
private final Set<ResourceLocation> generatedTiles = new HashSet<>();
private final Map<ResourceLocation, BufferedImage> tileImages = new HashMap<>();
private final Map<String, IIcon> iconMap = new HashMap<>();
@@ -119,6 +121,10 @@ public class TileLoader {
logger.fine("after registerIcons(%s) %d icons", mapName, map.size());
}
public BufferedImage getImageForPath(ResourceLocation rl) {
return tileImages.get(rl);
}
public static String getOverridePath(String prefix, String basePath, String name, String ext) {
String path;
if (name.endsWith(".png")) {
@@ -218,6 +224,22 @@ public class TileLoader {
if (tileImages.containsKey(resource)) {
return true;
}
return addTile(resource, loadResourceImage(resource, alternate), special, false);
}
public boolean addTile(ResourceLocation resource, BufferedImage image, String special, boolean generated) {
tilesToRegister.add(resource);
tileImages.put(resource, image);
if(generated){
generatedTiles.add(resource);
}
if (special != null) {
specialTextures.put(resource.toString(), special);
}
return true;
}
public BufferedImage loadResourceImage(ResourceLocation resource, boolean alternate){
BufferedImage image = null;
if (!MCPatcherForgeConfig.ConnectedTextures.debugTextures) {
image = TexturePackAPI.getImage(resource);
@@ -228,12 +250,7 @@ public class TileLoader {
if (image == null) {
image = generateDebugTexture(resource.getResourcePath(), 64, 64, alternate);
}
tilesToRegister.add(resource);
tileImages.put(resource, image);
if (special != null) {
specialTextures.put(resource.toString(), special);
}
return true;
return image;
}
public boolean preloadTile(ResourceLocation resource, boolean alternate) {
@@ -287,8 +304,14 @@ public class TileLoader {
return false;
}
}
IIcon icon = textureMap.registerIcon(name);
map.put(name, (TextureAtlasSprite) icon);
TextureAtlasSprite icon;
if(generatedTiles.contains(resource)){
icon = new GeneratedCTMAtlasSprite(this, textureMap.anisotropicFiltering > 1, name);
textureMap.setTextureEntry(name, icon);
}else{
icon = (TextureAtlasSprite)textureMap.registerIcon(name);
}
map.put(name, icon);
iconMap.put(name, icon);
String extra = (width == height ? "" : ", " + (height / width) + " frames");
subLogger.finer("%s -> %s icon %dx%d%s", name, mapName, width, width, extra);
@@ -299,6 +322,7 @@ public class TileLoader {
public void finish() {
tilesToRegister.clear();
tileImages.clear();
generatedTiles.clear();
}
public IIcon getIcon(String name) {
+3 -1
View File
@@ -174,7 +174,9 @@ public enum Settings {
RenderStars.reloadStarRenderList(Minecraft.getMinecraft().renderGlobal);
}
},
VOID_FOG(new NotFineOptionTickBox(false, OptionImpact.LOW));
VOID_FOG(new NotFineOptionTickBox(false, OptionImpact.LOW)),
ZOOM_SMOOTH(new NotFineOptionTickBox(true, OptionImpact.LOW)),
ZOOM_SMOOTH_SPEED(new NotFineOptionSlider(14, 1, 30, 1, OptionImpact.LOW));
public final NotFineOption<?> option;
@@ -1,6 +1,7 @@
package jss.notfine.gui;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import jss.notfine.config.NotFineConfig;
import jss.notfine.core.Settings;
@@ -169,6 +170,12 @@ public class NotFineGameOptionPages {
.build());
}
if (AngelicaConfig.enableZoom) {
groups.add(OptionGroup.createBuilder()
.add(Settings.ZOOM_SMOOTH.option)
.add(Settings.ZOOM_SMOOTH_SPEED.option)
.build());
}
return new OptionPage(I18n.format("options.video"), ImmutableList.copyOf(groups));
}
@@ -29,7 +29,7 @@ public class InterpolatedIcon extends TextureAtlasSprite {
}
}
private void updateAnimationInterpolated() throws IllegalArgumentException, IllegalAccessException {
protected void updateAnimationInterpolated() throws IllegalArgumentException, IllegalAccessException {
double d0 = 1.0D - tickCounter / (double) animationMetadata.getFrameTimeSingle(frameCounter);
int i = animationMetadata.getFrameIndex(frameCounter);
@@ -532,6 +532,13 @@ public class SodiumGameOptionPages {
.build())
.build());
if (AngelicaConfig.enableZoom) {
groups.add(OptionGroup.createBuilder()
.add(Settings.ZOOM_SMOOTH.option)
.add(Settings.ZOOM_SMOOTH_SPEED.option)
.build());
}
return new OptionPage(I18n.format("sodium.options.pages.appearance"), ImmutableList.copyOf(groups));
}
@@ -161,6 +161,7 @@ public class DHCompatInternal {
if (((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion() != cachedVersion) {
cachedVersion = ((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion();
createDepthTex(Minecraft.getMinecraft().getFramebuffer().framebufferWidth, Minecraft.getMinecraft().getFramebuffer().framebufferHeight);
storedDepthTex = -1;
}
if (storedDepthTex != depthTex && dhTerrainFramebuffer != null) {
storedDepthTex = depthTex;
@@ -31,7 +31,6 @@ import net.coderbot.iris.uniforms.custom.CustomUniforms;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.DynamicTexture;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
@@ -46,12 +45,6 @@ import java.util.Map;
public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgram {
// Uniforms
public final int modelViewUniform;
public final int modelViewInverseUniform;
public final int projectionUniform;
public final int projectionInverseUniform;
public final int normalMatrix3fUniform;
// Fog/Clip Uniforms
private final int id;
private final ProgramUniforms uniforms;
private final CustomUniforms customUniforms;
@@ -62,7 +55,6 @@ public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgra
private final Matrix4f tempModel = new Matrix4f();
private final Matrix4f tempProj = new Matrix4f();
private final Matrix4f tempMat4 = new Matrix4f();
private final Matrix3f tempMat3 = new Matrix3f();
private final int instancedShaderOffsetChunkUniform;
private final int instancedShaderOffsetSubChunkUniform;
@@ -143,12 +135,6 @@ public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgra
GLStateManager.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GLStateManager.glEnableVertexAttribArray(0);
projectionUniform = tryGetUniformLocation2("iris_ProjectionMatrix");
projectionInverseUniform = tryGetUniformLocation2("iris_ProjectionMatrixInverse");
modelViewUniform = tryGetUniformLocation2("iris_ModelViewMatrix");
modelViewInverseUniform = tryGetUniformLocation2("iris_ModelViewMatrixInverse");
normalMatrix3fUniform = tryGetUniformLocation2("iris_NormalMatrix");
this.instancedShaderOffsetChunkUniform = this.tryGetUniformLocation2("uOffsetChunk");
this.instancedShaderOffsetSubChunkUniform = this.tryGetUniformLocation2("uOffsetSubChunk");
this.instancedShaderCameraChunkPosUniform = this.tryGetUniformLocation2("uCameraPosChunk");
@@ -213,18 +199,6 @@ public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgra
}
}
public void setUniform(int index, Matrix3f matrix) {
if (index == -1) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(9);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix3(index, false, buffer);
}
}
// Override ShaderProgram.bind()
public void bind(DhApiRenderParam renderParam) {
GLStateManager.glBindVertexArray(va);
@@ -238,14 +212,8 @@ public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgra
toJOML(tempModel, renderParam.dhModelViewMatrix);
toJOML(tempProj, renderParam.dhProjectionMatrix);
setUniform(modelViewUniform, tempModel);
setUniform(projectionUniform, tempProj);
this.setUniform(this.instancedShaderProjectionModelViewMatrixUniform, tempMat4.set(tempProj).mul(tempModel));
tempModel.invert();
tempProj.invert();
setUniform(modelViewInverseUniform, tempModel);
setUniform(projectionInverseUniform, tempProj);
setUniform(normalMatrix3fUniform, tempModel.transpose3x3(tempMat3));
LodRendererEvents.pushDhMatrices(tempProj, tempModel);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + IrisSamplers.LIGHTMAP_TEXTURE_UNIT);
DynamicTexture lightmapTexture = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapTexture();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, lightmapTexture.getGlTextureId());
@@ -259,6 +227,7 @@ public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgra
}
public void unbind() {
LodRendererEvents.popDhMatrices();
GLStateManager.glBindVertexArray(0);
GLStateManager.glUseProgram(0);
ProgramUniforms.clearActiveUniforms();
@@ -3,7 +3,6 @@ package net.coderbot.iris.compat.dh;
import com.google.common.primitives.Ints;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
import com.mitchej123.lwjgl.MemoryStack;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import net.coderbot.iris.gl.blending.BlendModeOverride;
@@ -26,15 +25,12 @@ import net.coderbot.iris.uniforms.builtin.BuiltinReplacementUniforms;
import net.coderbot.iris.uniforms.custom.CustomUniforms;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.DynamicTexture;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL32;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -44,11 +40,6 @@ public class IrisLodRenderProgram {
public final int modelOffsetUniform;
public final int worldYOffsetUniform;
public final int mircoOffsetUniform;
public final int modelViewUniform;
public final int modelViewInverseUniform;
public final int projectionUniform;
public final int projectionInverseUniform;
public final int normalMatrix3fUniform;
// Fog/Clip Uniforms
public final int clipDistanceUniform;
private final int id;
@@ -58,9 +49,6 @@ public class IrisLodRenderProgram {
private final ProgramImages images;
private final BlendModeOverride blend;
private final BufferBlendOverride[] bufferBlendOverrides;
private final Matrix4f tempMat4a = new Matrix4f();
private final Matrix4f tempMat4b = new Matrix4f();
private final Matrix3f tempMat3 = new Matrix3f();
// This will bind AbstractVertexAttribute
private IrisLodRenderProgram(String name, boolean isShadowPass, boolean translucent, BlendModeOverride override, BufferBlendOverride[] bufferBlendOverrides, String vertex, String tessControl, String tessEval, String geometry, String fragment, CustomUniforms customUniforms, DeferredWorldRenderingPipeline pipeline) {
@@ -132,11 +120,6 @@ public class IrisLodRenderProgram {
modelOffsetUniform = tryGetUniformLocation2("modelOffset");
worldYOffsetUniform = tryGetUniformLocation2("worldYOffset");
mircoOffsetUniform = tryGetUniformLocation2("mircoOffset");
projectionUniform = tryGetUniformLocation2("iris_ProjectionMatrix");
projectionInverseUniform = tryGetUniformLocation2("iris_ProjectionMatrixInverse");
modelViewUniform = tryGetUniformLocation2("iris_ModelViewMatrix");
modelViewInverseUniform = tryGetUniformLocation2("iris_ModelViewMatrixInverse");
normalMatrix3fUniform = tryGetUniformLocation2("iris_NormalMatrix");
// Fog/Clip Uniforms
clipDistanceUniform = tryGetUniformLocation2("clipDistance");
@@ -176,30 +159,6 @@ public class IrisLodRenderProgram {
return GLStateManager.glGetUniformLocation(this.id, name);
}
public void setUniform(int index, Matrix4fc matrix) {
if (index == -1 || matrix == null) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(16);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix4(index, false, buffer);
}
}
public void setUniform(int index, Matrix3f matrix) {
if (index == -1) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(9);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix3(index, false, buffer);
}
}
// Override ShaderProgram.bind()
public void bind() {
GLStateManager.glUseProgram(id);
@@ -227,11 +186,8 @@ public class IrisLodRenderProgram {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + IrisSamplers.LIGHTMAP_TEXTURE_UNIT);
DynamicTexture lightmapTexture = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapTexture();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, lightmapTexture.getGlTextureId());
setUniform(modelViewUniform, modelView);
setUniform(modelViewInverseUniform, modelView.invert(tempMat4a));
setUniform(projectionUniform, projection);
setUniform(projectionInverseUniform, projection.invert(tempMat4b));
setUniform(normalMatrix3fUniform, tempMat4a.set(modelView).invert().transpose3x3(tempMat3));
LodRendererEvents.pushDhMatrices(projection, modelView);
setUniform(mircoOffsetUniform, 0.01f); // 0.01 block offset
@@ -33,6 +33,7 @@ import net.coderbot.iris.shadows.ShadowRenderingState;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.irisshaders.iris.api.v0.IrisApi;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL11;
public class LodRendererEvents {
@@ -46,6 +47,28 @@ public class LodRendererEvents {
private static int textureHeight;
private static final Matrix4f tempMat4 = new Matrix4f();
private static boolean dhMatricesActive = false;
private static final Matrix4f savedModelView = new Matrix4f();
private static final Matrix4f savedProjection = new Matrix4f();
static void pushDhMatrices(Matrix4fc projection, Matrix4fc modelView) {
if (!dhMatricesActive) {
savedModelView.set(GLStateManager.getModelViewMatrix());
savedProjection.set(GLStateManager.getProjectionMatrix());
dhMatricesActive = true;
}
GLStateManager.setModelViewMatrix(modelView);
GLStateManager.setProjectionMatrix(projection);
}
static void popDhMatrices() {
if (dhMatricesActive) {
GLStateManager.setModelViewMatrix(savedModelView);
GLStateManager.setProjectionMatrix(savedProjection);
dhMatricesActive = false;
}
}
// constructor //
@@ -181,6 +204,7 @@ public class LodRendererEvents {
DhApiBeforeRenderCleanupEvent beforeCleanupEvent = new DhApiBeforeRenderCleanupEvent() {
@Override
public void beforeCleanup(DhApiEventParam<DhApiRenderParam> event) {
popDhMatrices();
if (getInstance().shouldOverride) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
getInstance().getShadowShader().unbind();
@@ -55,7 +55,7 @@ public class PackRenderTargetDirectives {
renderTargetSettings.forEach((index, settings) -> {
if (settings.shouldClear()) {
buffersToBeCleared.add(index.intValue());
buffersToBeCleared.add(index);
}
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 B

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

@@ -1,6 +1,6 @@
matchBlocks=minecraft:glass minecraft:glass_pane
matchBlocks=glass
metadata=0
method=ctm
method=compact
faces=all
tiles=0-46
connect=block
tiles=0-4
connect=block
@@ -0,0 +1,6 @@
matchBlocks=glass_pane
metadata=0
method=compact
faces=all
tiles=0-4
connect=sides
Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Loaded 100 of 218 files, more files were not shown because too many files have changed in this diff. Show more