mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-25 20:22:22 +00:00
Plenty of fixes for GTNH (#2202)
This commit is contained in:
1 parent
c7a0f3a208
commit
fe82cd320a
26 files changed
+675
-82
No files matched your search
@@ -107,9 +107,11 @@ public final class StateSet {
|
||||
GLStateManager.getTextures().getTextureUnitBindings(0), GLStateManager.getTextures().getTextureUnitBindings(1),
|
||||
GLStateManager.getActiveTextureUnitStack(), GLStateManager.getProgramStack(),
|
||||
GLStateManager.getBlendMode(), GLStateManager.getAlphaTest(), GLStateManager.getDepthTest(),
|
||||
GLStateManager.getTextures().getTextureUnitStates(0)
|
||||
GLStateManager.getTextures().getTextureUnitStates(0),
|
||||
GLStateManager.getColorMask(), GLStateManager.getCullState(),
|
||||
GLStateManager.getPolygonState(), GLStateManager.getPolygonOffsetFillState()
|
||||
),
|
||||
R_BLEND | R_DEPTH | R_TEXTURE | R_ACTIVE_UNIT | R_PROGRAM,
|
||||
R_BLEND | R_DEPTH | R_COLOR_MASK | R_TEXTURE | R_ACTIVE_UNIT | R_PROGRAM | R_POLYGON,
|
||||
0,
|
||||
true);
|
||||
}
|
||||
@@ -121,9 +123,11 @@ public final class StateSet {
|
||||
GLStateManager.getTextures().getTextureUnitBindings(0), GLStateManager.getTextures().getTextureUnitBindings(1),
|
||||
GLStateManager.getActiveTextureUnitStack(),
|
||||
GLStateManager.getBlendMode(), GLStateManager.getAlphaTest(), GLStateManager.getDepthTest(),
|
||||
GLStateManager.getTextures().getTextureUnitStates(0)
|
||||
GLStateManager.getTextures().getTextureUnitStates(0),
|
||||
GLStateManager.getColorMask(), GLStateManager.getCullState(),
|
||||
GLStateManager.getPolygonState(), GLStateManager.getPolygonOffsetFillState()
|
||||
),
|
||||
R_BLEND | R_DEPTH | R_TEXTURE | R_ACTIVE_UNIT,
|
||||
R_BLEND | R_DEPTH | R_COLOR_MASK | R_TEXTURE | R_ACTIVE_UNIT | R_POLYGON,
|
||||
0,
|
||||
true);
|
||||
}
|
||||
|
||||
+25
-13
@@ -54,9 +54,17 @@ public final class GeometryShaderGenerator {
|
||||
sb.append(" vec4 c0 = gl_in[0].gl_Position;\n");
|
||||
sb.append(" vec4 c1 = gl_in[1].gl_Position;\n\n");
|
||||
|
||||
sb.append(" float d0 = c0.z + c0.w;\n");
|
||||
sb.append(" float d1 = c1.z + c1.w;\n");
|
||||
sb.append(" if (d0 < 0.0 && d1 < 0.0) return;\n");
|
||||
sb.append(" float t0 = d0 < 0.0 ? d0 / (d0 - d1) : 0.0;\n");
|
||||
sb.append(" float t1 = d1 < 0.0 ? d0 / (d0 - d1) : 1.0;\n");
|
||||
sb.append(" vec4 p0 = mix(c0, c1, t0);\n");
|
||||
sb.append(" vec4 p1 = mix(c0, c1, t1);\n\n");
|
||||
|
||||
sb.append(" // NDC positions\n");
|
||||
sb.append(" vec2 n0 = c0.xy / c0.w;\n");
|
||||
sb.append(" vec2 n1 = c1.xy / c1.w;\n\n");
|
||||
sb.append(" vec2 n0 = p0.xy / p0.w;\n");
|
||||
sb.append(" vec2 n1 = p1.xy / p1.w;\n\n");
|
||||
|
||||
sb.append(" // Screen-space direction and perpendicular\n");
|
||||
sb.append(" vec2 dir = normalize((n1 - n0) * u_ViewportSize);\n");
|
||||
@@ -74,22 +82,22 @@ public final class GeometryShaderGenerator {
|
||||
}
|
||||
|
||||
private static void emitVertex(StringBuilder sb, VertexKey key, int endpointIdx, String offsetExpr) {
|
||||
final String ci = "c" + endpointIdx;
|
||||
final String pi = "p" + endpointIdx;
|
||||
final String ni = "n" + endpointIdx;
|
||||
final String idx = "[" + endpointIdx + "]";
|
||||
final String ti = "t" + endpointIdx;
|
||||
|
||||
sb.append(" // Endpoint ").append(endpointIdx).append(' ').append(offsetExpr).append('\n');
|
||||
|
||||
sb.append(" v_Color = v_Color_gs").append(idx).append(";\n");
|
||||
sb.append(" v_Color = ").append(lerp("v_Color_gs", ti)).append(";\n");
|
||||
if (key.separateSpecular()) {
|
||||
sb.append(" v_SpecularColor = v_SpecularColor_gs").append(idx).append(";\n");
|
||||
sb.append(" v_SpecularColor = ").append(lerp("v_SpecularColor_gs", ti)).append(";\n");
|
||||
}
|
||||
if (key.unitTexCoordEnabled(0) || key.texGenEnabled()) sb.append(" v_TexCoord0 = v_TexCoord0_gs").append(idx).append(";\n");
|
||||
if (key.lightmapEnabled()) sb.append(" v_TexCoord1 = v_TexCoord1_gs").append(idx).append(";\n");
|
||||
if (key.unitTexCoordEnabled(2)) sb.append(" v_TexCoord2 = v_TexCoord2_gs").append(idx).append(";\n");
|
||||
if (key.unitTexCoordEnabled(3)) sb.append(" v_TexCoord3 = v_TexCoord3_gs").append(idx).append(";\n");
|
||||
if (key.unitTexCoordEnabled(0) || key.texGenEnabled()) sb.append(" v_TexCoord0 = ").append(lerp("v_TexCoord0_gs", ti)).append(";\n");
|
||||
if (key.lightmapEnabled()) sb.append(" v_TexCoord1 = ").append(lerp("v_TexCoord1_gs", ti)).append(";\n");
|
||||
if (key.unitTexCoordEnabled(2)) sb.append(" v_TexCoord2 = ").append(lerp("v_TexCoord2_gs", ti)).append(";\n");
|
||||
if (key.unitTexCoordEnabled(3)) sb.append(" v_TexCoord3 = ").append(lerp("v_TexCoord3_gs", ti)).append(";\n");
|
||||
if (key.fogEnabled()) {
|
||||
sb.append(" v_FogCoord = v_FogCoord_gs").append(idx).append(";\n");
|
||||
sb.append(" v_FogCoord = ").append(lerp("v_FogCoord_gs", ti)).append(";\n");
|
||||
}
|
||||
if (key.lineStipple()) {
|
||||
sb.append(" v_LineStart = v_LineStart_gs[0];\n");
|
||||
@@ -97,11 +105,15 @@ public final class GeometryShaderGenerator {
|
||||
|
||||
if (key.clipPlanesEnabled()) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
sb.append(" gl_ClipDistance[").append(i).append("] = gl_in").append(idx).append(".gl_ClipDistance[").append(i).append("];\n");
|
||||
sb.append(" gl_ClipDistance[").append(i).append("] = mix(gl_in[0].gl_ClipDistance[").append(i).append("], gl_in[1].gl_ClipDistance[").append(i).append("], ").append(ti).append(");\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(" gl_Position = vec4((").append(ni).append(' ').append(offsetExpr).append(") * ").append(ci).append(".w, ").append(ci).append(".z, ").append(ci).append(".w);\n");
|
||||
sb.append(" gl_Position = vec4((").append(ni).append(' ').append(offsetExpr).append(") * ").append(pi).append(".w, ").append(pi).append(".z, ").append(pi).append(".w);\n");
|
||||
sb.append(" EmitVertex();\n\n");
|
||||
}
|
||||
|
||||
private static String lerp(String input, String t) {
|
||||
return "mix(" + input + "[0], " + input + "[1], " + t + ")";
|
||||
}
|
||||
}
|
||||
@@ -89,33 +89,41 @@ public class GLSM_StateSet_GLTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void fontRestoresDepthAxisAndShadeModelButNotCull() {
|
||||
void fontRestoresDepthAxisShadeModelAndPolygonOffsetButNotStencil() {
|
||||
try {
|
||||
GLStateManager.enableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
|
||||
GLStateManager.glShadeModel(GL11.GL_SMOOTH);
|
||||
GLStateManager.enableCull();
|
||||
GLStateManager.glCullFace(GL11.GL_BACK);
|
||||
GLStateManager.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GLStateManager.glPolygonOffset(0.0f, 0.0f);
|
||||
GLStateManager.glEnable(GL11.GL_STENCIL_TEST);
|
||||
|
||||
final int d = GLStateManager.pushState(StateSet.FONT);
|
||||
GLStateManager.disableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_ALWAYS);
|
||||
GLStateManager.glShadeModel(GL11.GL_FLAT);
|
||||
GLStateManager.glCullFace(GL11.GL_FRONT);
|
||||
GLStateManager.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GLStateManager.glPolygonOffset(-10.0f, -10.0f);
|
||||
GLStateManager.glDisable(GL11.GL_STENCIL_TEST);
|
||||
GLStateManager.popStateTo(d);
|
||||
|
||||
verifyIsEnabled(GL11.GL_DEPTH_TEST, true, "Depth test enable - restored by FONT pop");
|
||||
assertEquals(GL11.GL_LEQUAL, GLStateManager.getDepthState().getFunc(), "cache depth func");
|
||||
assertEquals(GL11.GL_LEQUAL, GL11.glGetInteger(GL11.GL_DEPTH_FUNC), "driver depth func");
|
||||
assertEquals(GL11.GL_SMOOTH, GLStateManager.getShadeModelState().getValue(), "cache shade model");
|
||||
assertEquals(GL11.GL_FRONT, GLStateManager.getPolygonState().getCullFaceMode(), "cache cull face mode - not a FONT member, must stay toggled");
|
||||
assertEquals(GL11.GL_FRONT, GL11.glGetInteger(GL11.GL_CULL_FACE_MODE), "driver cull face mode - not a FONT member, must stay toggled");
|
||||
verifyIsEnabled(GL11.GL_POLYGON_OFFSET_FILL, false, "Polygon offset fill - restored by FONT pop");
|
||||
assertEquals(0.0f, GLStateManager.getPolygonState().getOffsetFactor(), "cache polygon offset factor");
|
||||
assertEquals(0.0f, GL11.glGetFloat(GL11.GL_POLYGON_OFFSET_FACTOR), "driver polygon offset factor");
|
||||
assertEquals(0.0f, GLStateManager.getPolygonState().getOffsetUnits(), "cache polygon offset units");
|
||||
assertEquals(0.0f, GL11.glGetFloat(GL11.GL_POLYGON_OFFSET_UNITS), "driver polygon offset units");
|
||||
verifyIsEnabled(GL11.GL_STENCIL_TEST, false, "Stencil test - not a FONT member, must stay toggled");
|
||||
} finally {
|
||||
GLStateManager.disableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_LESS);
|
||||
GLStateManager.glShadeModel(GL11.GL_SMOOTH);
|
||||
GLStateManager.disableCull();
|
||||
GLStateManager.glCullFace(GL11.GL_BACK);
|
||||
GLStateManager.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GLStateManager.glPolygonOffset(0.0f, 0.0f);
|
||||
GLStateManager.glDisable(GL11.GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.gtnewhorizons.angelica.glsm.ffp;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLCoreTest;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
@GLCoreTest
|
||||
class WideLineClipGLTest {
|
||||
|
||||
private static final int SIZE = 64;
|
||||
private static final double NEAR = 0.05;
|
||||
private static final float LINE_WIDTH = 3.0f;
|
||||
private static final int BACKGROUND = 0xFF000000;
|
||||
|
||||
private static final float[] IN_FRONT = { 0f, -1f, -2f };
|
||||
private static final float[] BEHIND = { 0f, 0.8f, 2f };
|
||||
|
||||
private boolean savedEmulation;
|
||||
private int vao;
|
||||
private int vbo;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
assumeTrue(GLStateManager.supportsGeometryShaders());
|
||||
savedEmulation = GLStateManager.wideLineEmulationEnabled;
|
||||
GLStateManager.wideLineEmulationEnabled = true;
|
||||
|
||||
FfpFixture.resetFfpState();
|
||||
ShaderManager.enable();
|
||||
ShaderManager.getInstance().activate();
|
||||
GLStateManager.glViewport(0, 0, SIZE, SIZE);
|
||||
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
|
||||
GLStateManager.glLoadIdentity();
|
||||
GLStateManager.glFrustum(-NEAR, NEAR, -NEAR, NEAR, NEAR, 100.0);
|
||||
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
|
||||
GLStateManager.glLoadIdentity();
|
||||
GLStateManager.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GLStateManager.glLineWidth(LINE_WIDTH);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
GLStateManager.wideLineEmulationEnabled = savedEmulation;
|
||||
GLStateManager.glLineWidth(1.0f);
|
||||
if (vbo != 0) { GLStateManager.glDeleteBuffers(vbo); vbo = 0; }
|
||||
if (vao != 0) { GLStateManager.glDeleteVertexArrays(vao); vao = 0; }
|
||||
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
|
||||
GLStateManager.glLoadIdentity();
|
||||
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
|
||||
FfpFixture.resetFfpState();
|
||||
while (GL11.glGetError() != GL11.GL_NO_ERROR) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
void lineEndingBehindTheCameraKeepsItsWidth() {
|
||||
assertConstantWidth(IN_FRONT, BEHIND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void lineStartingBehindTheCameraKeepsItsWidth() {
|
||||
assertConstantWidth(BEHIND, IN_FRONT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void lineFullyBehindTheCameraDrawsNothing() {
|
||||
final int[] pixels = drawLine(new float[] { 0f, -1f, 2f }, BEHIND);
|
||||
for (int px : pixels) {
|
||||
assertEquals(BACKGROUND, px);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertConstantWidth(float[] start, float[] end) {
|
||||
final int[] pixels = drawLine(start, end);
|
||||
for (int row = 0; row < SIZE / 4; row++) {
|
||||
int lit = 0;
|
||||
for (int x = 0; x < SIZE; x++) {
|
||||
if (pixels[row * SIZE + x] != BACKGROUND) lit++;
|
||||
}
|
||||
final int y = row, count = lit;
|
||||
assertTrue(count > 0 && count <= LINE_WIDTH + 1, () -> "row " + y + " is " + count + " pixels wide");
|
||||
}
|
||||
assertEquals(GL11.GL_NO_ERROR, GL11.glGetError());
|
||||
}
|
||||
|
||||
private int[] drawLine(float[] start, float[] end) {
|
||||
vao = GLStateManager.glGenVertexArrays();
|
||||
GLStateManager.glBindVertexArray(vao);
|
||||
vbo = GLStateManager.glGenBuffers();
|
||||
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
|
||||
final FloatBuffer positions = BufferUtils.createFloatBuffer(6);
|
||||
positions.put(start).put(end).flip();
|
||||
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, positions, GL15.GL_STATIC_DRAW);
|
||||
FfpFixture.attrib(0, 3, GL11.GL_FLOAT, false, 12, 0);
|
||||
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
VAOManager.setCurrentVertexFlags(0);
|
||||
|
||||
FfpFixture.clear();
|
||||
GLStateManager.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
GLStateManager.glDrawArrays(GL11.GL_LINES, 0, 2);
|
||||
GLStateManager.glBindVertexArray(0);
|
||||
return FfpFixture.readRegion(SIZE);
|
||||
}
|
||||
}
|
||||
@@ -192,6 +192,9 @@ public class BatchingFontRenderer {
|
||||
private int lightmapTextureId = 0;
|
||||
private int lightmapPackedLight = -1;
|
||||
|
||||
private final TextDrawState drawState = new TextDrawState();
|
||||
private final TextDrawState liveDrawState = new TextDrawState();
|
||||
|
||||
private final Vector3f lightingFactor = new Vector3f(1.0f, 1.0f, 1.0f);
|
||||
private boolean lightingFactorActive = false;
|
||||
|
||||
@@ -243,6 +246,13 @@ public class BatchingFontRenderer {
|
||||
lightmapPackedLight = packedLight;
|
||||
}
|
||||
|
||||
private void captureDrawState() {
|
||||
liveDrawState.captureLive();
|
||||
if (liveDrawState.sameAs(drawState)) return;
|
||||
sealBatchSegment();
|
||||
drawState.set(liveDrawState);
|
||||
}
|
||||
|
||||
private static final class TextSegment {
|
||||
final Matrix4f mvp = new Matrix4f();
|
||||
final Matrix4f modelView = new Matrix4f();
|
||||
@@ -256,8 +266,7 @@ public class BatchingFontRenderer {
|
||||
int packedLight;
|
||||
float normalX, normalY, normalZ;
|
||||
int blockEntityId;
|
||||
boolean depthTest;
|
||||
boolean depthMask;
|
||||
final TextDrawState drawState = new TextDrawState();
|
||||
}
|
||||
|
||||
// 16-bit EBO index range
|
||||
@@ -543,8 +552,7 @@ public class BatchingFontRenderer {
|
||||
segment.normalY = normal.y;
|
||||
segment.normalZ = normal.z;
|
||||
segment.blockEntityId = CapturedRenderingState.INSTANCE.getCurrentRenderedBlockEntity();
|
||||
segment.depthTest = GLStateManager.getDepthTest().isEnabled();
|
||||
segment.depthMask = GLStateManager.isEffectiveDepthMaskEnabled();
|
||||
segment.drawState.set(drawState);
|
||||
batchSegments.add(segment);
|
||||
batchSealedEnd = end;
|
||||
}
|
||||
@@ -576,7 +584,8 @@ public class BatchingFontRenderer {
|
||||
|
||||
private static boolean shouldDeferNow() {
|
||||
if (!GLStateManager.isMainThread()) return false;
|
||||
return TesrBatchRenderer.INSTANCE.hasPendingGeometry() || ModelPartBatcher.INSTANCE.isActive();
|
||||
return (TesrBatchRenderer.INSTANCE.hasPendingGeometry() || ModelPartBatcher.INSTANCE.isActive())
|
||||
&& BatchDrawDefaults.drawsToPassFramebuffer();
|
||||
}
|
||||
|
||||
public void beginDeferredBatch() {
|
||||
@@ -664,23 +673,13 @@ public class BatchingFontRenderer {
|
||||
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
|
||||
GLStateManager.glPushMatrix();
|
||||
try {
|
||||
boolean curDepthTest = GLStateManager.getDepthTest().isEnabled();
|
||||
boolean curDepthMask = GLStateManager.isEffectiveDepthMaskEnabled();
|
||||
for (final TextSegment segment : deferredSegments) {
|
||||
final BatchingFontRenderer owner = segment.owner;
|
||||
if (segment.cmdStart == segment.cmdEnd) continue;
|
||||
|
||||
GLStateManager.setModelViewMatrix(segment.modelView);
|
||||
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(segment.blockEntityId);
|
||||
|
||||
if (segment.depthTest != curDepthTest) {
|
||||
if (segment.depthTest) GLStateManager.enableDepthTest(); else GLStateManager.disableDepthTest();
|
||||
curDepthTest = segment.depthTest;
|
||||
}
|
||||
if (segment.depthMask != curDepthMask) {
|
||||
GLStateManager.glDepthMask(segment.depthMask);
|
||||
curDepthMask = segment.depthMask;
|
||||
}
|
||||
segment.drawState.apply();
|
||||
|
||||
final FontDrawCmd[] cmdsData = owner.batchCommands.elements();
|
||||
Arrays.sort(cmdsData, segment.cmdStart, segment.cmdEnd, FontDrawCmd.DRAW_ORDER_COMPARATOR);
|
||||
@@ -708,22 +707,13 @@ public class BatchingFontRenderer {
|
||||
deferredSegments.get(0).owner.setupFontDrawState();
|
||||
flushLastTexture = INVALID_TEXTURE;
|
||||
resetFlushLightmap();
|
||||
boolean curDepthTest = GLStateManager.getDepthTest().isEnabled();
|
||||
boolean curDepthMask = GLStateManager.isEffectiveDepthMaskEnabled();
|
||||
for (final TextSegment segment : deferredSegments) {
|
||||
FLUSH_MVP.clear();
|
||||
segment.mvp.get(FLUSH_MVP);
|
||||
GLStateManager.glUniformMatrix4(segment.owner.mvpMatrixLocation, false, FLUSH_MVP);
|
||||
uploadLightmap(segment.owner.lightmapLocation, segment.lightmapActive, segment.lightmapU,
|
||||
segment.lightmapV, segment.lightmapTexture);
|
||||
if (segment.depthTest != curDepthTest) {
|
||||
if (segment.depthTest) GLStateManager.enableDepthTest(); else GLStateManager.disableDepthTest();
|
||||
curDepthTest = segment.depthTest;
|
||||
}
|
||||
if (segment.depthMask != curDepthMask) {
|
||||
GLStateManager.glDepthMask(segment.depthMask);
|
||||
curDepthMask = segment.depthMask;
|
||||
}
|
||||
segment.owner.applyDrawState(segment.drawState);
|
||||
drawCommands(segment.owner.batchCommands.elements(), segment.cmdStart, segment.cmdEnd, segment.owner);
|
||||
}
|
||||
} finally {
|
||||
@@ -734,6 +724,11 @@ public class BatchingFontRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private void applyDrawState(TextDrawState state) {
|
||||
state.apply();
|
||||
GLStateManager.glUniform1f(alphaTestRefLocation, state.alphaRef);
|
||||
}
|
||||
|
||||
public static void discardDeferredText() {
|
||||
if (deferredSegments.isEmpty()) return;
|
||||
for (int i = 0, n = deferredSegments.size(); i < n; i++) {
|
||||
@@ -841,6 +836,7 @@ public class BatchingFontRenderer {
|
||||
segment.mvp.get(FLUSH_MVP);
|
||||
GLStateManager.glUniformMatrix4(mvpMatrixLocation, false, FLUSH_MVP);
|
||||
uploadLightmap(lightmapLocation, segment.lightmapActive, segment.lightmapU, segment.lightmapV, segment.lightmapTexture);
|
||||
applyDrawState(segment.drawState);
|
||||
drawCommands(cmds, segment.cmdStart, segment.cmdEnd, this);
|
||||
}
|
||||
if (batchSealedEnd < cmdCount) {
|
||||
@@ -849,6 +845,7 @@ public class BatchingFontRenderer {
|
||||
scratchMvp.get(FLUSH_MVP);
|
||||
GLStateManager.glUniformMatrix4(mvpMatrixLocation, false, FLUSH_MVP);
|
||||
uploadLightmap(lightmapLocation, lightmapActive, lightmapU, lightmapV, lightmapTextureId);
|
||||
applyDrawState(drawState);
|
||||
drawCommands(cmds, batchSealedEnd, cmdCount, this);
|
||||
}
|
||||
} finally {
|
||||
@@ -882,7 +879,6 @@ public class BatchingFontRenderer {
|
||||
fontBrightnessLast = FontConfig.fontBrightness;
|
||||
GLStateManager.glUniform1f(fontBrightness, 0.625f * FontConfig.fontBrightness + 0.1875f);
|
||||
}
|
||||
GLStateManager.glUniform1f(alphaTestRefLocation, GLStateManager.getAlphaState().getReference());
|
||||
if (lightmapSamplerProgram != fontShaderId) {
|
||||
GLStateManager.glUniform1i(lightmapSamplerLocation, LIGHTMAP_TEX_UNIT);
|
||||
lightmapSamplerProgram = fontShaderId;
|
||||
@@ -1011,12 +1007,14 @@ public class BatchingFontRenderer {
|
||||
if (segment.cmdStart == segment.cmdEnd) continue;
|
||||
GLStateManager.setModelViewMatrix(segment.modelView);
|
||||
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(segment.blockEntityId);
|
||||
segment.drawState.apply();
|
||||
emitRangeThroughPipeline(this, cmdsData, segment.cmdStart, segment.cmdEnd,
|
||||
segment.packedLight, segment.normalX, segment.normalY, segment.normalZ);
|
||||
}
|
||||
if (batchSealedEnd < cmdCount) {
|
||||
GLStateManager.setModelViewMatrix(scratchModelView);
|
||||
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(prevBlockEntityId);
|
||||
drawState.apply();
|
||||
final Vector3f normal = ShaderManager.getCurrentNormal();
|
||||
emitRangeThroughPipeline(this, cmdsData, batchSealedEnd, cmdCount,
|
||||
lightmapPackedLight, normal.x, normal.y, normal.z);
|
||||
@@ -1241,6 +1239,7 @@ public class BatchingFontRenderer {
|
||||
|
||||
this.beginBatch();
|
||||
this.captureLightmapState();
|
||||
this.captureDrawState();
|
||||
this.lightingFactorActive = isWorldSpaceText() && FFPVertexLighting.modulatesVertexColor(this.lightingFactor);
|
||||
float curX = anchorX;
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.gtnewhorizons.angelica.client.font;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.ColorMask;
|
||||
import com.gtnewhorizons.angelica.glsm.states.PolygonState;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
/**
|
||||
* Drawing text picks up settings from whoever asked for it, such as depth testing, culling, polygon offset and
|
||||
* alpha cutoff. Text is sometimes drawn later than requested, so these are saved with it to make the late draw
|
||||
* look the same as an immediate one.
|
||||
*/
|
||||
final class TextDrawState {
|
||||
private final ColorMask colorMaskScratch = new ColorMask();
|
||||
|
||||
boolean depthTest;
|
||||
int depthFunc;
|
||||
boolean depthMask;
|
||||
boolean colorRed;
|
||||
boolean colorGreen;
|
||||
boolean colorBlue;
|
||||
boolean colorAlpha;
|
||||
boolean cull;
|
||||
int cullFace;
|
||||
int frontFace;
|
||||
boolean polygonOffset;
|
||||
float offsetFactor;
|
||||
float offsetUnits;
|
||||
float alphaRef;
|
||||
|
||||
void captureLive() {
|
||||
depthTest = GLStateManager.getDepthTest().isEnabled();
|
||||
depthFunc = GLStateManager.getDepthState().getFunc();
|
||||
depthMask = GLStateManager.isEffectiveDepthMaskEnabled();
|
||||
final ColorMask colorMask = GLStateManager.getEffectiveColorMask(colorMaskScratch);
|
||||
colorRed = colorMask.red;
|
||||
colorGreen = colorMask.green;
|
||||
colorBlue = colorMask.blue;
|
||||
colorAlpha = colorMask.alpha;
|
||||
final PolygonState polygon = GLStateManager.getPolygonState();
|
||||
cull = GLStateManager.getCullState().isEnabled();
|
||||
cullFace = polygon.getCullFaceMode();
|
||||
frontFace = polygon.getFrontFace();
|
||||
polygonOffset = GLStateManager.getPolygonOffsetFillState().isEnabled();
|
||||
offsetFactor = polygon.getOffsetFactor();
|
||||
offsetUnits = polygon.getOffsetUnits();
|
||||
alphaRef = GLStateManager.getAlphaState().getReference();
|
||||
}
|
||||
|
||||
boolean sameAs(TextDrawState other) {
|
||||
return depthTest == other.depthTest
|
||||
&& depthFunc == other.depthFunc
|
||||
&& depthMask == other.depthMask
|
||||
&& colorRed == other.colorRed
|
||||
&& colorGreen == other.colorGreen
|
||||
&& colorBlue == other.colorBlue
|
||||
&& colorAlpha == other.colorAlpha
|
||||
&& cull == other.cull
|
||||
&& cullFace == other.cullFace
|
||||
&& frontFace == other.frontFace
|
||||
&& polygonOffset == other.polygonOffset
|
||||
&& offsetFactor == other.offsetFactor
|
||||
&& offsetUnits == other.offsetUnits
|
||||
&& alphaRef == other.alphaRef;
|
||||
}
|
||||
|
||||
void set(TextDrawState other) {
|
||||
depthTest = other.depthTest;
|
||||
depthFunc = other.depthFunc;
|
||||
depthMask = other.depthMask;
|
||||
colorRed = other.colorRed;
|
||||
colorGreen = other.colorGreen;
|
||||
colorBlue = other.colorBlue;
|
||||
colorAlpha = other.colorAlpha;
|
||||
cull = other.cull;
|
||||
cullFace = other.cullFace;
|
||||
frontFace = other.frontFace;
|
||||
polygonOffset = other.polygonOffset;
|
||||
offsetFactor = other.offsetFactor;
|
||||
offsetUnits = other.offsetUnits;
|
||||
alphaRef = other.alphaRef;
|
||||
}
|
||||
|
||||
void apply() {
|
||||
if (depthTest) GLStateManager.enableDepthTest(); else GLStateManager.disableDepthTest();
|
||||
GLStateManager.glDepthFunc(depthFunc);
|
||||
GLStateManager.glDepthMask(depthMask);
|
||||
GLStateManager.glColorMask(colorRed, colorGreen, colorBlue, colorAlpha);
|
||||
if (cull) GLStateManager.enableCull(); else GLStateManager.disableCull();
|
||||
GLStateManager.glCullFace(cullFace);
|
||||
GLStateManager.glFrontFace(frontFace);
|
||||
if (polygonOffset) GLStateManager.glEnable(GL11.GL_POLYGON_OFFSET_FILL); else GLStateManager.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GLStateManager.glPolygonOffset(offsetFactor, offsetUnits);
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,12 @@ import com.gtnewhorizons.angelica.compat.backhand.BackhandReflectionCompat;
|
||||
import com.gtnewhorizons.angelica.compat.battlegear2.Battlegear2Compat;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.dynamiclights.config.EntityLightConfig;
|
||||
import com.gtnewhorizons.angelica.helpers.ItemBlockLight;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.PrimedEntityAccessor;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import mods.battlegear2.api.core.IBattlePlayer;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -586,10 +586,7 @@ public class DynamicLights {
|
||||
if (item instanceof IDynamicLightProducer lightProducer) {
|
||||
return lightProducer.getLuminance(stack);
|
||||
} else if (item instanceof ItemBlock itemBlock) {
|
||||
final Block block = itemBlock.field_150939_a;
|
||||
if (block != null) {
|
||||
return block.getLightValue();
|
||||
}
|
||||
return ItemBlockLight.getLightValue(itemBlock, stack);
|
||||
}
|
||||
|
||||
if (item == Items.lava_bucket) return Blocks.lava.getLightValue();
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.gtnewhorizons.angelica.helpers;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/**
|
||||
* Light value of the block an ItemBlock stack would place.
|
||||
*/
|
||||
public final class ItemBlockLight {
|
||||
|
||||
private static final SingleBlockAccess ACCESS = new SingleBlockAccess();
|
||||
|
||||
private ItemBlockLight() {}
|
||||
|
||||
public static int getLightValue(ItemBlock item, ItemStack stack) {
|
||||
final Block block = item.field_150939_a;
|
||||
if (block == null) return 0;
|
||||
ACCESS.set(block, item.getMetadata(stack.getItemDamage()));
|
||||
try {
|
||||
return block.getLightValue(ACCESS, 0, 0, 0);
|
||||
} catch (RuntimeException e) {
|
||||
return block.getLightValue();
|
||||
} finally {
|
||||
ACCESS.set(Blocks.air, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SingleBlockAccess implements IBlockAccess {
|
||||
private Block block = Blocks.air;
|
||||
private int metadata;
|
||||
|
||||
void set(Block block, int metadata) {
|
||||
this.block = block;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
private static boolean isOrigin(int x, int y, int z) {
|
||||
return x == 0 && y == 0 && z == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
return isOrigin(x, y, z) ? block : Blocks.air;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockMetadata(int x, int y, int z) {
|
||||
return isOrigin(x, y, z) ? metadata : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity getTileEntity(int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightBrightnessForSkyBlocks(int x, int y, int z, int min) {
|
||||
return min << 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isBlockProvidingPowerTo(int x, int y, int z, int direction) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAirBlock(int x, int y, int z) {
|
||||
return !isOrigin(x, y, z) || block == Blocks.air;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeGenBase getBiomeGenForCoords(int x, int z) {
|
||||
return BiomeGenBase.plains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean extendedLevelsInChunkCache() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,9 +73,6 @@ public final class SelectionBoxRenderer {
|
||||
public static void draw(AxisAlignedBB aabb, int color) {
|
||||
if (program == null || vao == null) return;
|
||||
|
||||
GLStateManager.enableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
|
||||
|
||||
final float minX = (float) aabb.minX, minY = (float) aabb.minY, minZ = (float) aabb.minZ;
|
||||
final float extX = (float) (aabb.maxX - aabb.minX);
|
||||
final float extY = (float) (aabb.maxY - aabb.minY);
|
||||
|
||||
+4
@@ -119,6 +119,10 @@ public class CeleritasWorldRenderer extends SimpleWorldRenderer<WorldClient, Ang
|
||||
return this.renderSectionManager;
|
||||
}
|
||||
|
||||
public WorldClient getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
private long asyncEwmaNanos;
|
||||
private long uploadEwmaNanos;
|
||||
|
||||
|
||||
@@ -43,6 +43,16 @@ public final class BakedTransformCapture extends DirectTessellator {
|
||||
|
||||
@Override
|
||||
protected int interceptDraw(Tessellator tessellator) {
|
||||
transform = delta.deltaOrNull(deltaMatrix);
|
||||
try {
|
||||
return super.interceptDraw(tessellator);
|
||||
} finally {
|
||||
transform = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int draw() {
|
||||
final Color4 color = GLStateManager.getColor();
|
||||
final int packed = ColorABGR.pack(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
|
||||
if (!sawRun) {
|
||||
@@ -51,12 +61,7 @@ public final class BakedTransformCapture extends DirectTessellator {
|
||||
} else if (packed != firstColor) {
|
||||
colorUniform = false;
|
||||
}
|
||||
transform = delta.deltaOrNull(deltaMatrix);
|
||||
try {
|
||||
return super.interceptDraw(tessellator);
|
||||
} finally {
|
||||
transform = null;
|
||||
}
|
||||
return super.draw();
|
||||
}
|
||||
|
||||
// While capturing, Tessellator.instance is this tessellator, so vanilla code (e.g. RenderBlocks.renderBlockAsItem)
|
||||
|
||||
@@ -25,6 +25,11 @@ public final class BatchDrawDefaults {
|
||||
passFramebuffer = GLStateManager.getDrawFramebuffer();
|
||||
}
|
||||
|
||||
public static boolean drawsToPassFramebuffer() {
|
||||
return passFramebuffer < 0 || TesrBatchRenderer.deferredPipeline() != null
|
||||
|| GLStateManager.getDrawFramebuffer() == passFramebuffer;
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
if (passFramebuffer >= 0 && TesrBatchRenderer.deferredPipeline() == null) {
|
||||
final int framebuffer = GLStateManager.getDrawFramebuffer();
|
||||
|
||||
@@ -3,7 +3,6 @@ package jss.notfine.gui;
|
||||
import me.jellysquid.mods.sodium.client.gui.options.OptionPage;
|
||||
import me.jellysquid.mods.sodium.client.gui.options.storage.OptionStorage;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiListExtended;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
@@ -19,7 +18,7 @@ public class GuiCustomMenu extends GuiScreen {
|
||||
private final OptionPage[] subPages;
|
||||
protected String screenTitle;
|
||||
|
||||
private GuiListExtended optionsRowList;
|
||||
private GuiCustomOptionsRowList optionsRowList;
|
||||
|
||||
public GuiCustomMenu(GuiScreen parentGuiScreen, OptionPage optionPage, OptionPage... subPages) {
|
||||
this.parentGuiScreen = parentGuiScreen;
|
||||
@@ -30,6 +29,7 @@ public class GuiCustomMenu extends GuiScreen {
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
buttonList.clear();
|
||||
buttonList.add(new GuiButton(200, width / 2 - 110, height - 27, I18n.format("gui.done")));
|
||||
optionsRowList = new GuiCustomOptionsRowList(mc, width, height, 32, height - 32, 25, optionPage, subPages);
|
||||
@@ -88,9 +88,15 @@ public class GuiCustomMenu extends GuiScreen {
|
||||
if(keyCode == Keyboard.KEY_ESCAPE && !(parentGuiScreen instanceof GuiCustomMenu)) {
|
||||
saveChanges();
|
||||
}
|
||||
optionsRowList.keyTyped(keyCode);
|
||||
super.keyTyped(typedChar, keyCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
}
|
||||
|
||||
private void saveChanges() {
|
||||
for(OptionStorage<?> storage : dirtyStorages) {
|
||||
storage.save();
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import jss.notfine.gui.options.control.element.NotFineControlElementFactory;
|
||||
import jss.notfine.gui.options.control.element.SliderControlElement;
|
||||
import me.jellysquid.mods.sodium.client.gui.options.Option;
|
||||
import me.jellysquid.mods.sodium.client.gui.options.OptionGroup;
|
||||
import me.jellysquid.mods.sodium.client.gui.options.OptionPage;
|
||||
@@ -20,6 +21,7 @@ import java.util.List;
|
||||
public class GuiCustomOptionsRowList extends GuiListExtended {
|
||||
private static final NotFineControlElementFactory factory = new NotFineControlElementFactory();
|
||||
private final List<Row> settingsList = Lists.newArrayList();
|
||||
private GuiButton focusedButton;
|
||||
|
||||
public GuiCustomOptionsRowList(Minecraft mc, int width, int height, int top, int bottom, int slotHeight, OptionPage optionPage, OptionPage... subPages) {
|
||||
super(mc, width, height, top, bottom, slotHeight);
|
||||
@@ -64,8 +66,14 @@ public class GuiCustomOptionsRowList extends GuiListExtended {
|
||||
return super.getScrollBarX() + 32;
|
||||
}
|
||||
|
||||
public void keyTyped(int keyCode) {
|
||||
if(focusedButton instanceof SliderControlElement slider) {
|
||||
slider.keyTyped(keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class Row implements GuiListExtended.IGuiListEntry {
|
||||
public class Row implements GuiListExtended.IGuiListEntry {
|
||||
private final Minecraft mc = Minecraft.getMinecraft();
|
||||
private final GuiButton buttonOne, buttonTwo;
|
||||
|
||||
@@ -93,9 +101,11 @@ public class GuiCustomOptionsRowList extends GuiListExtended {
|
||||
@Override
|
||||
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY) {
|
||||
if(buttonOne.mousePressed(mc, x, y)) {
|
||||
focusedButton = buttonOne;
|
||||
return true;
|
||||
}
|
||||
if(buttonTwo != null && buttonTwo.mousePressed(mc, x, y)) {
|
||||
focusedButton = buttonTwo;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -6,6 +6,7 @@ import me.jellysquid.mods.sodium.client.util.Dim2i;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
public class SliderControlElement extends NotFineControlElement<Integer> {
|
||||
private final ControlValueFormatter formatter;
|
||||
@@ -68,6 +69,29 @@ public class SliderControlElement extends NotFineControlElement<Integer> {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyTyped(int keyCode) {
|
||||
if(!option.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int step;
|
||||
if(keyCode == Keyboard.KEY_LEFT) {
|
||||
step = -interval;
|
||||
} else if(keyCode == Keyboard.KEY_RIGHT) {
|
||||
step = interval;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int stepped = MathHelper.clamp_int(option.getValue() + step, min, max);
|
||||
if(stepped != option.getValue()) {
|
||||
option.setValue(stepped);
|
||||
value = MathHelper.clamp_float((float)(stepped - min) / (max - min), 0f, 1f);
|
||||
onOptionValueChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateSlider(int mouseX) {
|
||||
value = (float)(mouseX - (xPosition + 4)) / (float)(width - 8);
|
||||
//Clamp normalized value
|
||||
|
||||
+13
@@ -78,6 +78,7 @@ public class ReeseSodiumVideoOptionsScreen extends SodiumOptionsGUI {
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
this.frame = this.parentFrameBuilder().build();
|
||||
this.children.add(this.frame);
|
||||
|
||||
@@ -287,6 +288,18 @@ public class ReeseSodiumVideoOptionsScreen extends SodiumOptionsGUI {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||
final boolean onSearchField = this.searchTextField.isMouseOver(mouseX, mouseY);
|
||||
|
||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
|
||||
if (!onSearchField) {
|
||||
this.searchTextField.setFocused(false);
|
||||
this.setFocused(this.frame);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return !this.hasPendingChanges;
|
||||
|
||||
+5
@@ -154,6 +154,11 @@ public class SearchTextFieldComponent extends AbstractWidget {
|
||||
return this.isFocused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver(double mouseX, double mouseY) {
|
||||
return this.dim.containsCursor(mouseX, mouseY);
|
||||
}
|
||||
|
||||
private void drawSelectionHighlight(int x1, int y1, int x2, int y2) {
|
||||
int i;
|
||||
if (x1 < x2) {
|
||||
|
||||
@@ -54,6 +54,7 @@ public class SodiumOptionsGUI extends ScrollableGuiScreen {
|
||||
|
||||
protected boolean hasPendingChanges;
|
||||
protected ControlElement<?> hoveredElement;
|
||||
private Element focusedElement;
|
||||
|
||||
protected OptionPage shaderPacks;
|
||||
|
||||
@@ -97,13 +98,20 @@ public class SodiumOptionsGUI extends ScrollableGuiScreen {
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
this.rebuildGUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
}
|
||||
|
||||
protected void rebuildGUI() {
|
||||
this.controls.clear();
|
||||
this.children.clear();
|
||||
this.drawable.clear();
|
||||
this.focusedElement = null;
|
||||
|
||||
if (this.currentPage == null) {
|
||||
if (this.pages.isEmpty()) {
|
||||
@@ -298,6 +306,10 @@ public class SodiumOptionsGUI extends ScrollableGuiScreen {
|
||||
SodiumGameOptionPages.quality(), SodiumGameOptionPages.advanced(), SodiumGameOptionPages.performance(),
|
||||
SodiumGameOptionPages.appearance()));
|
||||
}
|
||||
|
||||
if (this.focusedElement != null) {
|
||||
this.focusedElement.keyTyped(typedChar, keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
@@ -314,7 +326,11 @@ public class SodiumOptionsGUI extends ScrollableGuiScreen {
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
|
||||
this.children.forEach(element -> element.mouseClicked(mouseX, mouseY, mouseButton));
|
||||
this.children.forEach(element -> {
|
||||
if (element.mouseClicked(mouseX, mouseY, mouseButton)) {
|
||||
this.focusedElement = element;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+25
@@ -7,6 +7,7 @@ import me.jellysquid.mods.sodium.client.gui.options.control.ControlValueFormatte
|
||||
import me.jellysquid.mods.sodium.client.gui.utils.Rect2i;
|
||||
import me.jellysquid.mods.sodium.client.util.Dim2i;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
public class SodiumControlElementFactory implements ControlElementFactory {
|
||||
@Override
|
||||
@@ -194,6 +195,30 @@ public class SodiumControlElementFactory implements ControlElementFactory {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(char typedChar, int keyCode) {
|
||||
if (!this.option.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int step;
|
||||
if (keyCode == Keyboard.KEY_LEFT) {
|
||||
step = -this.interval;
|
||||
} else if (keyCode == Keyboard.KEY_RIGHT) {
|
||||
step = this.interval;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int value = MathHelper.clamp_int(this.option.getValue() + step, this.min, this.min + this.range);
|
||||
|
||||
if (this.option.getValue() != value) {
|
||||
this.option.setValue(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TickBoxControlElement extends SodiumControlElement<Boolean> {
|
||||
|
||||
@@ -320,8 +320,6 @@ public class Iris {
|
||||
// See: https://github.com/IrisShaders/Iris/issues/323
|
||||
lastDimensionName = "Overworld";
|
||||
Iris.getPipelineManager().preparePipeline("Overworld");
|
||||
|
||||
BlockRenderingSettings.INSTANCE.reloadRendererIfRequired();
|
||||
}
|
||||
|
||||
public static void toggleShaders(Minecraft minecraft, boolean enabled) throws IOException {
|
||||
@@ -684,8 +682,6 @@ public class Iris {
|
||||
// https://github.com/IrisShaders/Iris/issues/1330
|
||||
if (Minecraft.getMinecraft().theWorld != null) {
|
||||
Iris.getPipelineManager().preparePipeline(Iris.getCurrentDimensionName());
|
||||
|
||||
BlockRenderingSettings.INSTANCE.reloadRendererIfRequired();
|
||||
}
|
||||
|
||||
if (loadedIncompatiblePack() && Minecraft.getMinecraft().thePlayer != null) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import lombok.Getter;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
|
||||
import net.coderbot.iris.uniforms.SystemTimeUniforms;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -43,6 +44,7 @@ public class PipelineManager {
|
||||
Iris.logger.info("Creating pipeline for dimension '{}'", currentDimension);
|
||||
pipeline = pipelineFactory.apply(currentDimension);
|
||||
pipelinesPerDimension.put(currentDimension, pipeline);
|
||||
BlockRenderingSettings.INSTANCE.reloadRendererIfRequired();
|
||||
if (Tracy.ENABLED) {
|
||||
shaderSection = Tracy.sectionEnter(Tracy.SECTION_SHADERS, "shaders " + Iris.getCurrentPackName() + " / " + currentDimension);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.irisshaders.iris.api.v0.item;
|
||||
|
||||
import com.gtnewhorizons.angelica.helpers.ItemBlockLight;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -11,8 +12,7 @@ public interface IrisItemLightProvider {
|
||||
|
||||
default int getLightEmission(EntityPlayer player, ItemStack stack) {
|
||||
if (stack.getItem() instanceof ItemBlock item) {
|
||||
|
||||
return item.field_150939_a.getLightValue();
|
||||
return ItemBlockLight.getLightValue(item, stack);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -10,19 +10,25 @@ void main() {
|
||||
vec4 c0 = gl_in[0].gl_Position;
|
||||
vec4 c1 = gl_in[1].gl_Position;
|
||||
|
||||
vec2 n0 = c0.xy / c0.w;
|
||||
vec2 n1 = c1.xy / c1.w;
|
||||
float d0 = c0.z + c0.w;
|
||||
float d1 = c1.z + c1.w;
|
||||
if (d0 < 0.0 && d1 < 0.0) return;
|
||||
vec4 p0 = d0 < 0.0 ? mix(c0, c1, d0 / (d0 - d1)) : c0;
|
||||
vec4 p1 = d1 < 0.0 ? mix(c0, c1, d0 / (d0 - d1)) : c1;
|
||||
|
||||
vec2 n0 = p0.xy / p0.w;
|
||||
vec2 n1 = p1.xy / p1.w;
|
||||
|
||||
vec2 dir = normalize((n1 - n0) * u_ViewportSize);
|
||||
vec2 offset = vec2(-dir.y, dir.x) * u_LineWidth / u_ViewportSize;
|
||||
|
||||
gl_Position = vec4((n0 + offset) * c0.w, c0.z, c0.w);
|
||||
gl_Position = vec4((n0 + offset) * p0.w, p0.z, p0.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4((n0 - offset) * c0.w, c0.z, c0.w);
|
||||
gl_Position = vec4((n0 - offset) * p0.w, p0.z, p0.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4((n1 + offset) * c1.w, c1.z, c1.w);
|
||||
gl_Position = vec4((n1 + offset) * p1.w, p1.z, p1.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4((n1 - offset) * c1.w, c1.z, c1.w);
|
||||
gl_Position = vec4((n1 - offset) * p1.w, p1.z, p1.w);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
+2
@@ -66,6 +66,7 @@ public class MixinRenderGlobal implements IRenderGlobalExt {
|
||||
@Unique private static final Tracy.ZoneId Z_MT_QUEUE = Tracy.zoneId("mtQueue", Tracy.COLOR_TERRAIN);
|
||||
|
||||
@Shadow public Minecraft mc;
|
||||
@Shadow public WorldClient theWorld;
|
||||
@Shadow @Final private TextureManager renderEngine;
|
||||
|
||||
@Unique private static final String SECTION_SOLID = "draw_chunk_layer_solid";
|
||||
@@ -264,6 +265,7 @@ public class MixinRenderGlobal implements IRenderGlobalExt {
|
||||
|
||||
@Inject(method = "loadRenderers", at = @At("RETURN"))
|
||||
private void onReload(CallbackInfo ci) {
|
||||
if (this.celeritas$renderer.getWorld() != this.theWorld) return;
|
||||
angelica$reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.layer.GbufferPrograms;
|
||||
import net.coderbot.iris.pipeline.WorldRenderingPhase;
|
||||
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -20,6 +21,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(RenderGlobal.class)
|
||||
public class MixinRenderGlobal {
|
||||
|
||||
@Inject(method = "setWorldAndLoadRenderers", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;loadRenderers()V"))
|
||||
private void iris$preparePipelineForNewWorld(WorldClient world, CallbackInfo ci) {
|
||||
Iris.getPipelineManager().preparePipeline(Iris.getCurrentDimensionName());
|
||||
}
|
||||
|
||||
@Inject(method = "renderSky", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/Tessellator;instance:Lnet/minecraft/client/renderer/Tessellator;"))
|
||||
private void iris$renderSky$beginNormalSky(float partialTicks, CallbackInfo ci) {
|
||||
// None of the vanilla sky is rendered until after this call, so if anything is rendered before, it's CUSTOM_SKY.
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.gtnewhorizons.angelica.client.font;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLCoreTest;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.StateSet;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@GLCoreTest
|
||||
class TextDrawStateGLTest {
|
||||
|
||||
@AfterEach
|
||||
void resetState() {
|
||||
setDefaults();
|
||||
}
|
||||
|
||||
private static void setDefaults() {
|
||||
GLStateManager.disableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_LESS);
|
||||
GLStateManager.glDepthMask(true);
|
||||
GLStateManager.glColorMask(true, true, true, true);
|
||||
GLStateManager.disableCull();
|
||||
GLStateManager.glCullFace(GL11.GL_BACK);
|
||||
GLStateManager.glFrontFace(GL11.GL_CCW);
|
||||
GLStateManager.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GLStateManager.glPolygonOffset(0.0f, 0.0f);
|
||||
GLStateManager.glAlphaFunc(GL11.GL_ALWAYS, 0.0f);
|
||||
}
|
||||
|
||||
private static void setNonDefaults() {
|
||||
GLStateManager.enableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_GEQUAL);
|
||||
GLStateManager.glDepthMask(false);
|
||||
GLStateManager.glColorMask(false, false, false, false);
|
||||
GLStateManager.enableCull();
|
||||
GLStateManager.glCullFace(GL11.GL_FRONT);
|
||||
GLStateManager.glFrontFace(GL11.GL_CW);
|
||||
GLStateManager.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GLStateManager.glPolygonOffset(-10.0f, -10.0f);
|
||||
GLStateManager.glAlphaFunc(GL11.GL_GREATER, 0.5f);
|
||||
}
|
||||
|
||||
private static TextDrawState capture() {
|
||||
final TextDrawState state = new TextDrawState();
|
||||
state.captureLive();
|
||||
return state;
|
||||
}
|
||||
|
||||
private static List<Field> stateFields() {
|
||||
final List<Field> fields = new ArrayList<>();
|
||||
for (Field field : TextDrawState.class.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers()) || !field.getType().isPrimitive()) continue;
|
||||
field.setAccessible(true);
|
||||
fields.add(field);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
private static boolean isGlState(Field field) {
|
||||
return !field.getName().equals("alphaRef");
|
||||
}
|
||||
|
||||
@Test
|
||||
void everyFieldIsMovedByTheTestState() throws IllegalAccessException {
|
||||
setDefaults();
|
||||
final TextDrawState defaults = capture();
|
||||
setNonDefaults();
|
||||
final TextDrawState moved = capture();
|
||||
for (Field field : stateFields()) {
|
||||
assertNotEquals(field.get(defaults), field.get(moved), field.getName() + " - add it to setNonDefaults()");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void sameAsAndSetCoverEveryField() throws IllegalAccessException {
|
||||
setNonDefaults();
|
||||
final TextDrawState moved = capture();
|
||||
setDefaults();
|
||||
final TextDrawState defaults = capture();
|
||||
for (Field field : stateFields()) {
|
||||
final TextDrawState copy = new TextDrawState();
|
||||
copy.set(moved);
|
||||
assertEquals(field.get(moved), field.get(copy), field.getName() + " - missing from set()");
|
||||
assertTrue(copy.sameAs(moved));
|
||||
field.set(copy, field.get(defaults));
|
||||
assertFalse(copy.sameAs(moved), field.getName() + " - missing from sameAs()");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyReplaysCapturedState() throws IllegalAccessException {
|
||||
setNonDefaults();
|
||||
final TextDrawState captured = capture();
|
||||
setDefaults();
|
||||
captured.apply();
|
||||
final TextDrawState replayed = capture();
|
||||
for (Field field : stateFields()) {
|
||||
if (!isGlState(field)) continue;
|
||||
assertEquals(field.get(captured), field.get(replayed), field.getName());
|
||||
}
|
||||
assertEquals(GL11.GL_GEQUAL, GL11.glGetInteger(GL11.GL_DEPTH_FUNC), "driver depth func");
|
||||
assertEquals(GL11.GL_FRONT, GL11.glGetInteger(GL11.GL_CULL_FACE_MODE), "driver cull face");
|
||||
assertEquals(GL11.GL_CW, GL11.glGetInteger(GL11.GL_FRONT_FACE), "driver front face");
|
||||
assertEquals(-10.0f, GL11.glGetFloat(GL11.GL_POLYGON_OFFSET_FACTOR), "driver polygon offset factor");
|
||||
assertTrue(GL11.glIsEnabled(GL11.GL_POLYGON_OFFSET_FILL), "driver polygon offset fill");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fontStateSetRestoresEverythingApplyTouches() throws IllegalAccessException {
|
||||
assertApplyDoesNotLeak(StateSet.FONT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fontPipelineStateSetRestoresEverythingApplyTouches() throws IllegalAccessException {
|
||||
assertApplyDoesNotLeak(StateSet.FONT_PIPELINE);
|
||||
}
|
||||
|
||||
private static void assertApplyDoesNotLeak(StateSet set) throws IllegalAccessException {
|
||||
setNonDefaults();
|
||||
final TextDrawState moved = capture();
|
||||
setDefaults();
|
||||
final TextDrawState before = capture();
|
||||
|
||||
final int depth = GLStateManager.pushState(set);
|
||||
moved.apply();
|
||||
GLStateManager.popStateTo(depth);
|
||||
|
||||
final TextDrawState after = capture();
|
||||
for (Field field : stateFields()) {
|
||||
if (!isGlState(field)) continue;
|
||||
assertEquals(field.get(before), field.get(after), field.getName() + " - not restored by the font state set");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user