Split up GLStateManager and add public GLState API (#2305)

This commit is contained in:
Jason Mitchell authored and GitHub committed 2026-10-26 21:11:49 -07:00
1 parent 9bbb0537ee
commit 91e67f8d5d
494 files changed
+22968 -20523

No files matched your search

@@ -78,8 +78,8 @@ import java.lang.annotation.Target;
* <pre>
* &#64;Surround(method = ..., at = &#64;At(value = "INVOKE", target = ...))
* private void enter() {
* &#64;Surround.Carry("depth") int depth = GLStateManager.pushState(StateSet.BLEND);
* &#64;Surround.Carry("prev") int prevProgram = GLStateManager.getActiveProgram();
* &#64;Surround.Carry("depth") int depth = GLSMAttribStack.pushState(StateSet.BLEND);
* &#64;Surround.Carry("prev") int prevProgram = GLSMPrograms.getActiveProgram();
* &#64;Surround.Carry Class&lt;?&gt; prevRenderable = TesrAttribution.currentRenderable;
* }
*
@@ -257,8 +257,8 @@ public class CompatUniformManager {
}
private static void uploadMatrices(int[] locs, boolean mvChanged, boolean mvLinearChanged, boolean projChanged, boolean texMatChanged) {
final Matrix4f mv = GLStateManager.getModelViewMatrix();
final Matrix4f proj = GLStateManager.getProjectionMatrix();
final Matrix4f mv = GLSMMatrices.getModelViewMatrix();
final Matrix4f proj = GLSMMatrices.getProjectionMatrix();
if (mvChanged) {
// ModelView
@@ -340,13 +340,13 @@ public class CompatUniformManager {
// angelica_LightmapTextureMatrix — actual GLSM texture unit 1 matrix (set by enableLightmap())
if (locs[LOC_LIGHTMAP_TEXTURE_MATRIX] != -1) {
GLStateManager.getTextures().getTextureUnitMatrix(1).get(mat4Buf);
GLSMTextures.getTextures().getTextureUnitMatrix(1).get(mat4Buf);
RENDER_BACKEND.uniformMatrix4(locs[LOC_LIGHTMAP_TEXTURE_MATRIX], false, mat4Buf);
}
// iris_TextureMatrix — texture unit 0 matrix (animated by glints, etc.)
if (locs[LOC_IRIS_TEXTURE_MATRIX] != -1) {
GLStateManager.getTextures().getTextureUnitMatrix(0).get(mat4Buf);
GLSMTextures.getTextures().getTextureUnitMatrix(0).get(mat4Buf);
RENDER_BACKEND.uniformMatrix4(locs[LOC_IRIS_TEXTURE_MATRIX], false, mat4Buf);
}
}
@@ -359,7 +359,7 @@ public class CompatUniformManager {
private static void uploadFragmentUniforms(int[] locs) {
// Fog uniforms
FogStateStack fog = GLStateManager.getFogState();
FogStateStack fog = GLSMFog.getFogState();
if (locs[LOC_FOG_DENSITY] != -1) {
RENDER_BACKEND.uniform1f(locs[LOC_FOG_DENSITY], Math.max(0.0f, fog.getDensity()));
}
@@ -383,10 +383,10 @@ public class CompatUniformManager {
// Return -1.0f for ALWAYS or disabled so `alpha <= ref` never discards.
if (locs[LOC_ALPHA_TEST_REF] != -1) {
final float ref;
if (!GLStateManager.getAlphaTest().isEnabled() || GLStateManager.getAlphaState().getFunction() == GL11.GL_ALWAYS) {
if (!GLSMDepthStencilAlpha.getAlphaTest().isEnabled() || GLSMDepthStencilAlpha.getAlphaState().getFunction() == GL11.GL_ALWAYS) {
ref = -1.0f;
} else {
ref = GLStateManager.getAlphaState().getReference();
ref = GLSMDepthStencilAlpha.getAlphaState().getReference();
}
RENDER_BACKEND.uniform1f(locs[LOC_ALPHA_TEST_REF], ref);
}
@@ -396,8 +396,8 @@ public class CompatUniformManager {
* Scene color = emission + ambient * lightModel.ambient, alpha = diffuse.a Same computation as {@code Uniforms.uploadLightingPreComputed()}.
*/
private static void uploadSceneColor(int[] locs) {
final MaterialState mat = GLStateManager.getFrontMaterial();
final LightModelState lm = GLStateManager.getLightModel();
final MaterialState mat = GLSMLighting.getFrontMaterial();
final LightModelState lm = GLSMLighting.getLightModel();
vec4Buf.clear();
vec4Buf.put(mat.emission.x + mat.ambient.x * lm.ambient.x)
.put(mat.emission.y + mat.ambient.y * lm.ambient.y)
@@ -408,7 +408,7 @@ public class CompatUniformManager {
}
private static void uploadLightSources(int[] locs) {
final LightStateStack[] lights = GLStateManager.getLightDataStates();
final LightStateStack[] lights = GLSMLighting.getLightDataStates();
for (int li = 0; li < 2; li++) {
final int base = LOC_LIGHT_BASE + li * LIGHT_FIELDS;
final LightState light = lights[li];
@@ -455,7 +455,7 @@ public class CompatUniformManager {
private static void uploadMaterial(int[] locs) {
// Early exit: if the first material field isn't present, no material uniforms exist
if (locs[LOC_MAT_BASE] == -1) return;
final MaterialState mat = GLStateManager.getFrontMaterial();
final MaterialState mat = GLSMLighting.getFrontMaterial();
if (locs[LOC_MAT_BASE + MF_EMISSION] != -1)
RENDER_BACKEND.uniform4f(locs[LOC_MAT_BASE + MF_EMISSION], mat.emission.x, mat.emission.y, mat.emission.z, mat.emission.w);
if (locs[LOC_MAT_BASE + MF_AMBIENT] != -1)
@@ -470,10 +470,10 @@ public class CompatUniformManager {
private static void uploadClipPlanes(int[] locs) {
if (locs[LOC_CLIP_PLANES_ENABLED] != -1) {
RENDER_BACKEND.uniform1i(locs[LOC_CLIP_PLANES_ENABLED], GLStateManager.anyClipPlaneEnabled() ? 1 : 0);
RENDER_BACKEND.uniform1i(locs[LOC_CLIP_PLANES_ENABLED], GLSMRasterizer.anyClipPlaneEnabled() ? 1 : 0);
}
if (locs[LOC_CLIP_PLANES] != -1) {
final ClipPlaneState cps = GLStateManager.getClipPlaneState();
final ClipPlaneState cps = GLSMRasterizer.getClipPlaneState();
clipPlaneBuf.clear();
for (int i = 0; i < GLStateManager.MAX_CLIP_PLANES; i++) {
cps.putEyePlane(i, clipPlaneBuf);
@@ -80,7 +80,7 @@ public class DisplayListManager {
private static int glListMode = 0;
private static int glListId = -1;
private static int recordedStatePushes;
private static final DisplayListCommand POP_STATE = GLStateManager::popState;
private static final DisplayListCommand POP_STATE = GLSMAttribStack::popState;
private static CommandRecorder currentRecorder = null; // Command recorder (null when not recording)
private static volatile Thread recordingThread = null; // Thread that started recording (for thread-safety)
private static List<AccumulatedDraw> accumulatedDraws = null; // Accumulates quad draws for batching
@@ -237,7 +237,7 @@ public class DisplayListManager {
currentRecorder.writeMultMatrix(pending);
}
if (glListMode == GL11.GL_COMPILE_AND_EXECUTE) {
GLStateManager.applyMultMatrix(pending);
GLSMMatrices.applyMultMatrix(pending);
}
@@ -722,7 +722,7 @@ public class DisplayListManager {
/**
* Add an immediate mode draw to the current display list compilation.
* Called by GLStateManager.glEnd() when immediate mode geometry is ready.
* Called by GLSMDraws.glEnd() when immediate mode geometry is ready.
*
* <p>This method captures the current transform and command position, creating
* an AccumulatedDraw that will be interleaved correctly with other commands
@@ -781,7 +781,7 @@ public class DisplayListManager {
/**
* Update the relative transform with a matrix multiplication during display list compilation.
* Called by GLStateManager.glMultMatrix().
* Called by GLSMMatrices.glMultMatrix().
*
* <p>In normal mode: accumulates transforms, emits collapsed MultMatrix at barriers.
* <p>In debug mode: emits MultMatrix immediately (no collapsing).
@@ -833,7 +833,7 @@ public class DisplayListManager {
/**
* Reset the relative transform to identity during display list compilation.
* Called by GLStateManager.glLoadMatrix() - after loading an absolute matrix,
* Called by GLSMMatrices.glLoadMatrix() - after loading an absolute matrix,
* subsequent transforms are relative to that loaded matrix (i.e., start from identity).
*/
static void resetRelativeTransform() {
@@ -1147,7 +1147,7 @@ public class DisplayListManager {
}
if (pendingDraw.drawMode != tessellator.drawMode
|| pendingDraw.format != tessellator.getVertexFormat()
|| GLStateManager.isContinuousDraw(tessellator.drawMode)
|| GLSMDraws.isContinuousDraw(tessellator.drawMode)
) {
drawBarrier();
createNewDraw(tessellator, copyLast);
@@ -160,8 +160,8 @@ final class ExitStateCapture {
textureInherited = true;
modelView.set(context.modelViewMatrix);
attribDepth = context.attribDepth;
modelViewDepth = GLStateManager.getMatrixStackDepth(context.modelViewMatrix);
textureDepth = GLStateManager.getMatrixStackDepth(context.textures.getTextureUnitMatrix(0));
modelViewDepth = GLSMMatrices.getMatrixStackDepth(context.modelViewMatrix);
textureDepth = GLSMMatrices.getMatrixStackDepth(context.textures.getTextureUnitMatrix(0));
entryOverrides = overridesInControl();
}
@@ -185,8 +185,8 @@ final class ExitStateCapture {
}
private boolean stacksMatchEntry() {
return context.attribDepth == attribDepth && GLStateManager.getMatrixStackDepth(context.modelViewMatrix) == modelViewDepth
&& GLStateManager.getMatrixStackDepth(context.textures.getTextureUnitMatrix(0)) == textureDepth && modelView.equals(context.modelViewMatrix);
return context.attribDepth == attribDepth && GLSMMatrices.getMatrixStackDepth(context.modelViewMatrix) == modelViewDepth
&& GLSMMatrices.getMatrixStackDepth(context.textures.getTextureUnitMatrix(0)) == textureDepth && modelView.equals(context.modelViewMatrix);
}
void cancel() {
@@ -448,7 +448,7 @@ final class ExitStateCapture {
if (result == null) return;
final int mode = context.matrixMode.getMode();
if (mode == GL11.GL_TEXTURE && context.activeTextureUnit.getValue() == 0) {
final int depth = GLStateManager.getMatrixStackDepth(context.textures.getTextureUnitMatrix(0));
final int depth = GLSMMatrices.getMatrixStackDepth(context.textures.getTextureUnitMatrix(0));
if (depth < matrixWrites.length) {
matrixWrites[depth] = result.writes;
matrixInherited[depth] = textureInherited;
@@ -476,7 +476,7 @@ final class ExitStateCapture {
reject();
return;
}
final int depth = GLStateManager.getMatrixStackDepth(matrix);
final int depth = GLSMMatrices.getMatrixStackDepth(matrix);
if (depth <= entryDepth) {
result.valid = false;
return;
@@ -549,34 +549,34 @@ final class ExitStateCapture {
// Capabilities go first so the glColor4f below bakes into the material only if color material is on at exit.
for (int field = 0; field < CAPS.length; field++) {
if (!has(fields, field)) continue;
if (field == TEXTURE0 || field == TEXTURE1) GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + field - TEXTURE0);
if (field == TEXTURE0 || field == TEXTURE1) GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0 + field - TEXTURE0);
// glEnable would bake the live color, not the exit color, into the material.
if (field == COLOR_MATERIAL) {
context.colorMaterial.setEnabled((in.enabled & (1L << field)) != 0);
} else if ((in.enabled & (1L << field)) != 0) GLStateManager.glEnable(CAPS[field]);
else GLStateManager.glDisable(CAPS[field]);
} else if ((in.enabled & (1L << field)) != 0) GLSMEnable.glEnable(CAPS[field]);
else GLSMEnable.glDisable(CAPS[field]);
}
if (has(fields, COLOR)) GLStateManager.glColor4f(in.color.getRed(), in.color.getGreen(), in.color.getBlue(), in.color.getAlpha());
if (has(fields, NORMAL)) GLStateManager.glNormal3f(in.normal.x, in.normal.y, in.normal.z);
if (has(fields, TEXCOORD)) GLStateManager.glTexCoord4f(in.texCoord.x, in.texCoord.y, in.texCoord.z, in.texCoord.w);
if (has(fields, LIGHTMAP)) GLStateManager.setLightmapTextureCoords(GL13.GL_TEXTURE1, in.lightmapX, in.lightmapY);
if (has(fields, SHADER_COLOR)) GLStateManager.setShaderColor(in.shaderColor.x, in.shaderColor.y, in.shaderColor.z, in.shaderColor.w);
if (has(fields, OVERLAY_COLOR)) GLStateManager.setOverlayColor(in.overlayColor.x, in.overlayColor.y, in.overlayColor.z, in.overlayColor.w);
if (has(fields, BLEND_FUNC)) GLStateManager.tryBlendFuncSeparate(in.blend.getSrcRgb(), in.blend.getDstRgb(), in.blend.getSrcAlpha(), in.blend.getDstAlpha());
if (has(fields, ALPHA_FUNC)) GLStateManager.glAlphaFunc(in.alpha.getFunction(), in.alpha.getReference());
if (has(fields, DEPTH_FUNC)) GLStateManager.glDepthFunc(in.depthFunction);
if (has(fields, DEPTH_MASK)) GLStateManager.glDepthMask(in.depthMask);
if (has(fields, COLOR_MASK)) GLStateManager.glColorMask(in.colorMask.red, in.colorMask.green, in.colorMask.blue, in.colorMask.alpha);
if (has(fields, CULL_FACE)) GLStateManager.glCullFace(in.cullFace);
if (has(fields, FRONT_FACE)) GLStateManager.glFrontFace(in.frontFace);
if (has(fields, SHADE_MODEL)) GLStateManager.glShadeModel(in.shadeModel);
if (has(fields, OFFSET_VALUES)) GLStateManager.glPolygonOffsetClamp(in.offsetFactor, in.offsetUnits, in.offsetClamp);
if (has(fields, COLOR)) GLSMCurrentAttribs.glColor4f(in.color.getRed(), in.color.getGreen(), in.color.getBlue(), in.color.getAlpha());
if (has(fields, NORMAL)) GLSMCurrentAttribs.glNormal3f(in.normal.x, in.normal.y, in.normal.z);
if (has(fields, TEXCOORD)) GLSMCurrentAttribs.glTexCoord4f(in.texCoord.x, in.texCoord.y, in.texCoord.z, in.texCoord.w);
if (has(fields, LIGHTMAP)) GLSMCurrentAttribs.setLightmapTextureCoords(GL13.GL_TEXTURE1, in.lightmapX, in.lightmapY);
if (has(fields, SHADER_COLOR)) GLSMCurrentAttribs.setShaderColor(in.shaderColor.x, in.shaderColor.y, in.shaderColor.z, in.shaderColor.w);
if (has(fields, OVERLAY_COLOR)) GLSMCurrentAttribs.setOverlayColor(in.overlayColor.x, in.overlayColor.y, in.overlayColor.z, in.overlayColor.w);
if (has(fields, BLEND_FUNC)) GLSMBlend.tryBlendFuncSeparate(in.blend.getSrcRgb(), in.blend.getDstRgb(), in.blend.getSrcAlpha(), in.blend.getDstAlpha());
if (has(fields, ALPHA_FUNC)) GLSMDepthStencilAlpha.glAlphaFunc(in.alpha.getFunction(), in.alpha.getReference());
if (has(fields, DEPTH_FUNC)) GLSMDepthStencilAlpha.glDepthFunc(in.depthFunction);
if (has(fields, DEPTH_MASK)) GLSMDepthStencilAlpha.glDepthMask(in.depthMask);
if (has(fields, COLOR_MASK)) GLSMBlend.glColorMask(in.colorMask.red, in.colorMask.green, in.colorMask.blue, in.colorMask.alpha);
if (has(fields, CULL_FACE)) GLSMRasterizer.glCullFace(in.cullFace);
if (has(fields, FRONT_FACE)) GLSMRasterizer.glFrontFace(in.frontFace);
if (has(fields, SHADE_MODEL)) GLSMRasterizer.glShadeModel(in.shadeModel);
if (has(fields, OFFSET_VALUES)) GLSMRasterizer.glPolygonOffsetClamp(in.offsetFactor, in.offsetUnits, in.offsetClamp);
if (has(fields, TEXTURE_BINDING)) {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, in.texture);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0);
GLSMTextures.glBindTexture(GL11.GL_TEXTURE_2D, in.texture);
}
if (has(fields, TEXTURE_MATRIX)) GLStateManager.setTextureMatrix(0, in.textureMatrix);
if (has(fields, COLOR_MATERIAL_SETTINGS)) GLStateManager.glColorMaterial(in.materialFace, in.materialParameter);
if (has(fields, TEXTURE_MATRIX)) GLSMMatrices.setTextureMatrix(0, in.textureMatrix);
if (has(fields, COLOR_MATERIAL_SETTINGS)) GLSMLighting.glColorMaterial(in.materialFace, in.materialParameter);
boolean materialChanged = false;
for (int field = FRONT_AMBIENT; field <= BACK_EMISSION; field++) {
if (!has(fields, field)) continue;
@@ -590,8 +590,8 @@ final class ExitStateCapture {
materialChanged = true;
}
if (materialChanged) context.lightingGeneration++;
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + (has(fields, ACTIVE_UNIT) ? in.activeUnit : liveUnit));
if (has(fields, CLIENT_ACTIVE_UNIT)) GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0 + in.clientActiveUnit);
if (has(fields, MATRIX_MODE)) GLStateManager.glMatrixMode(in.matrixMode);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0 + (has(fields, ACTIVE_UNIT) ? in.activeUnit : liveUnit));
if (has(fields, CLIENT_ACTIVE_UNIT)) GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0 + in.clientActiveUnit);
if (has(fields, MATRIX_MODE)) GLSMMatrices.glMatrixMode(in.matrixMode);
}
}
@@ -68,10 +68,10 @@ public class Feature {
*/
private static void addTextureGenStates(Set<IStateStack<?>> collection) {
for(int i = 0 ; i < GLStateManager.MAX_TEXTURE_UNITS; i++) {
collection.add(GLStateManager.getTextures().getTexGenSStates(i));
collection.add(GLStateManager.getTextures().getTexGenTStates(i));
collection.add(GLStateManager.getTextures().getTexGenRStates(i));
collection.add(GLStateManager.getTextures().getTexGenQStates(i));
collection.add(GLSMTextures.getTextures().getTexGenSStates(i));
collection.add(GLSMTextures.getTextures().getTexGenTStates(i));
collection.add(GLSMTextures.getTextures().getTexGenRStates(i));
collection.add(GLSMTextures.getTextures().getTexGenQStates(i));
}
}
@@ -79,24 +79,24 @@ public class Feature {
final Int2ObjectMap<Set<IStateStack<?>>> attribToFeatures = new Int2ObjectOpenHashMap<>();
attribToFeatures.put(GL11.GL_COLOR_BUFFER_BIT, ImmutableSet.of(
GLStateManager.getAlphaTest()
, GLStateManager.getAlphaState()
, GLStateManager.getBlendMode()
, GLStateManager.getBlendState()
, GLStateManager.getColorLogicOpState()
, GLStateManager.getDitherState()
, GLStateManager.getDrawBuffer()
, GLStateManager.getIndexLogicOpState()
, GLStateManager.getLogicOpMode()
, GLStateManager.getColorMask()
, GLStateManager.getClearColor()
GLSMDepthStencilAlpha.getAlphaTest()
, GLSMDepthStencilAlpha.getAlphaState()
, GLSMBlend.getBlendMode()
, GLSMBlend.getBlendState()
, GLSMBlend.getColorLogicOpState()
, GLSMRasterizer.getDitherState()
, GLSMFramebuffer.getDrawBuffer()
, GLSMBlend.getIndexLogicOpState()
, GLSMBlend.getLogicOpMode()
, GLSMBlend.getColorMask()
, GLSMBlend.getClearColor()
));
attribToFeatures.put(GL11.GL_CURRENT_BIT, ImmutableSet.of(
GLStateManager.getColor()
, GLStateManager.getSecondaryColor() // Current secondary color
GLSMCurrentAttribs.getColor()
, GLSMCurrentAttribs.getSecondaryColor() // Current secondary color
, ShaderManager.getNormalStack() // Current normal vector
, ShaderManager.getTexCoordStack() // Current texture coordinates
, GLStateManager.getEdgeFlagState()
, GLSMRasterizer.getEdgeFlagState()
// Current color index
// Current raster position
// GL_CURRENT_RASTER_POSITION_VALID flag
@@ -106,82 +106,82 @@ public class Feature {
// GL_EDGE_FLAG flag
));
attribToFeatures.put(GL11.GL_DEPTH_BUFFER_BIT, ImmutableSet.of(
GLStateManager.getDepthTest()
, GLStateManager.getDepthState()
GLSMDepthStencilAlpha.getDepthTest()
, GLSMDepthStencilAlpha.getDepthState()
// Depth buffer clear value
// GL_DEPTH_WRITEMASK enable bit
));
final HashSet<IStateStack<?>> enableBits = new HashSet<>(ImmutableSet.of(
GLStateManager.getAlphaTest()
, GLStateManager.getAutoNormalState()
, GLStateManager.getBlendMode()
, GLStateManager.getColorLogicOpState()
, GLStateManager.getColorMaterial()
, GLStateManager.getColorSumState()
, GLStateManager.getCullState()
, GLStateManager.getDepthTest()
, GLStateManager.getDitherState()
, GLStateManager.getFogMode()
, GLStateManager.getIndexLogicOpState()
, GLStateManager.getLightStates()[0] // GL_LIGHT0
, GLStateManager.getLightStates()[1] // GL_LIGHT1
, GLStateManager.getLightStates()[2] // GL_LIGHT2
, GLStateManager.getLightStates()[3] // GL_LIGHT3
, GLStateManager.getLightStates()[4] // GL_LIGHT4
, GLStateManager.getLightStates()[5] // GL_LIGHT5
, GLStateManager.getLightStates()[6] // GL_LIGHT6
, GLStateManager.getLightStates()[7] // GL_LIGHT7
, GLStateManager.getLightingState()
, GLStateManager.getLineSmoothState()
, GLStateManager.getLineStippleState()
, GLStateManager.getMap1Color4State()
, GLStateManager.getMap1IndexState()
, GLStateManager.getMap1NormalState()
, GLStateManager.getMap1TextureCoord1State()
, GLStateManager.getMap1TextureCoord2State()
, GLStateManager.getMap1TextureCoord3State()
, GLStateManager.getMap1TextureCoord4State()
, GLStateManager.getMap1Vertex3State()
, GLStateManager.getMap1Vertex4State()
, GLStateManager.getMap2Color4State()
, GLStateManager.getMap2IndexState()
, GLStateManager.getMap2NormalState()
, GLStateManager.getMap2TextureCoord1State()
, GLStateManager.getMap2TextureCoord2State()
, GLStateManager.getMap2TextureCoord3State()
, GLStateManager.getMap2TextureCoord4State()
, GLStateManager.getMap2Vertex3State()
, GLStateManager.getMap2Vertex4State()
, GLStateManager.getMultisampleState()
, GLStateManager.getNormalizeState()
, GLStateManager.getPointSmoothState()
, GLStateManager.getPolygonOffsetPointState()
, GLStateManager.getPolygonOffsetLineState()
, GLStateManager.getPolygonOffsetFillState()
, GLStateManager.getPointSpriteState()
, GLStateManager.getVertexProgramTwoSideState()
, GLStateManager.getPolygonSmoothState()
, GLStateManager.getPolygonStippleState()
, GLStateManager.getRescaleNormalState()
, GLStateManager.getSampleAlphaToCoverageState()
, GLStateManager.getSampleAlphaToOneState()
, GLStateManager.getSampleCoverageState()
, GLStateManager.getScissorTest()
, GLStateManager.getStencilTest()
GLSMDepthStencilAlpha.getAlphaTest()
, GLSMRasterizer.getAutoNormalState()
, GLSMBlend.getBlendMode()
, GLSMBlend.getColorLogicOpState()
, GLSMLighting.getColorMaterial()
, GLSMCurrentAttribs.getColorSumState()
, GLSMRasterizer.getCullState()
, GLSMDepthStencilAlpha.getDepthTest()
, GLSMRasterizer.getDitherState()
, GLSMFog.getFogMode()
, GLSMBlend.getIndexLogicOpState()
, GLSMLighting.getLightStates()[0] // GL_LIGHT0
, GLSMLighting.getLightStates()[1] // GL_LIGHT1
, GLSMLighting.getLightStates()[2] // GL_LIGHT2
, GLSMLighting.getLightStates()[3] // GL_LIGHT3
, GLSMLighting.getLightStates()[4] // GL_LIGHT4
, GLSMLighting.getLightStates()[5] // GL_LIGHT5
, GLSMLighting.getLightStates()[6] // GL_LIGHT6
, GLSMLighting.getLightStates()[7] // GL_LIGHT7
, GLSMLighting.getLightingState()
, GLSMRasterizer.getLineSmoothState()
, GLSMRasterizer.getLineStippleState()
, GLSMRasterizer.getMap1Color4State()
, GLSMRasterizer.getMap1IndexState()
, GLSMRasterizer.getMap1NormalState()
, GLSMRasterizer.getMap1TextureCoord1State()
, GLSMRasterizer.getMap1TextureCoord2State()
, GLSMRasterizer.getMap1TextureCoord3State()
, GLSMRasterizer.getMap1TextureCoord4State()
, GLSMRasterizer.getMap1Vertex3State()
, GLSMRasterizer.getMap1Vertex4State()
, GLSMRasterizer.getMap2Color4State()
, GLSMRasterizer.getMap2IndexState()
, GLSMRasterizer.getMap2NormalState()
, GLSMRasterizer.getMap2TextureCoord1State()
, GLSMRasterizer.getMap2TextureCoord2State()
, GLSMRasterizer.getMap2TextureCoord3State()
, GLSMRasterizer.getMap2TextureCoord4State()
, GLSMRasterizer.getMap2Vertex3State()
, GLSMRasterizer.getMap2Vertex4State()
, GLSMRasterizer.getMultisampleState()
, GLSMLighting.getNormalizeState()
, GLSMRasterizer.getPointSmoothState()
, GLSMRasterizer.getPolygonOffsetPointState()
, GLSMRasterizer.getPolygonOffsetLineState()
, GLSMRasterizer.getPolygonOffsetFillState()
, GLSMRasterizer.getPointSpriteState()
, GLSMPrograms.getVertexProgramTwoSideState()
, GLSMRasterizer.getPolygonSmoothState()
, GLSMRasterizer.getPolygonStippleState()
, GLSMLighting.getRescaleNormalState()
, GLSMRasterizer.getSampleAlphaToCoverageState()
, GLSMRasterizer.getSampleAlphaToOneState()
, GLSMRasterizer.getSampleCoverageState()
, GLSMRasterizer.getScissorTest()
, GLSMDepthStencilAlpha.getStencilTest()
));
// Enable bits for the user-definable clipping planes
for(int i = 0; i < GLStateManager.getClipPlaneStates().length; i++) {
enableBits.add(GLStateManager.getClipPlaneStates()[i]);
for(int i = 0; i < GLSMRasterizer.getClipPlaneStates().length; i++) {
enableBits.add(GLSMRasterizer.getClipPlaneStates()[i]);
}
// GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D flags
for(int i = 0 ; i < GLStateManager.MAX_TEXTURE_UNITS; i++) {
enableBits.add(GLStateManager.getTextures().getTexture1DStates(i));
enableBits.add(GLStateManager.getTextures().getTextureUnitStates(i));
enableBits.add(GLStateManager.getTextures().getTexture3DStates(i));
enableBits.add(GLStateManager.getTextures().getTextureCubeMapStates(i));
enableBits.add(GLSMTextures.getTextures().getTexture1DStates(i));
enableBits.add(GLSMTextures.getTextures().getTextureUnitStates(i));
enableBits.add(GLSMTextures.getTextures().getTexture3DStates(i));
enableBits.add(GLSMTextures.getTextures().getTextureCubeMapStates(i));
}
// Flags GL_TEXTURE_GEN_x where x is S, T, R, or Q
@@ -189,30 +189,30 @@ public class Feature {
attribToFeatures.put(GL11.GL_ENABLE_BIT, enableBits);
attribToFeatures.put(GL11.GL_EVAL_BIT, ImmutableSet.of(
GLStateManager.getAutoNormalState()
, GLStateManager.getMap1Color4State()
, GLStateManager.getMap1IndexState()
, GLStateManager.getMap1NormalState()
, GLStateManager.getMap1TextureCoord1State()
, GLStateManager.getMap1TextureCoord2State()
, GLStateManager.getMap1TextureCoord3State()
, GLStateManager.getMap1TextureCoord4State()
, GLStateManager.getMap1Vertex3State()
, GLStateManager.getMap1Vertex4State()
, GLStateManager.getMap2Color4State()
, GLStateManager.getMap2IndexState()
, GLStateManager.getMap2NormalState()
, GLStateManager.getMap2TextureCoord1State()
, GLStateManager.getMap2TextureCoord2State()
, GLStateManager.getMap2TextureCoord3State()
, GLStateManager.getMap2TextureCoord4State()
, GLStateManager.getMap2Vertex3State()
, GLStateManager.getMap2Vertex4State()
GLSMRasterizer.getAutoNormalState()
, GLSMRasterizer.getMap1Color4State()
, GLSMRasterizer.getMap1IndexState()
, GLSMRasterizer.getMap1NormalState()
, GLSMRasterizer.getMap1TextureCoord1State()
, GLSMRasterizer.getMap1TextureCoord2State()
, GLSMRasterizer.getMap1TextureCoord3State()
, GLSMRasterizer.getMap1TextureCoord4State()
, GLSMRasterizer.getMap1Vertex3State()
, GLSMRasterizer.getMap1Vertex4State()
, GLSMRasterizer.getMap2Color4State()
, GLSMRasterizer.getMap2IndexState()
, GLSMRasterizer.getMap2NormalState()
, GLSMRasterizer.getMap2TextureCoord1State()
, GLSMRasterizer.getMap2TextureCoord2State()
, GLSMRasterizer.getMap2TextureCoord3State()
, GLSMRasterizer.getMap2TextureCoord4State()
, GLSMRasterizer.getMap2Vertex3State()
, GLSMRasterizer.getMap2Vertex4State()
));
attribToFeatures.put(GL11.GL_FOG_BIT, ImmutableSet.of(
GLStateManager.getFogMode()
, GLStateManager.getColorSumState()
, GLStateManager.getFogState()
GLSMFog.getFogMode()
, GLSMCurrentAttribs.getColorSumState()
, GLSMFog.getFogState()
// ^^ Fog density
// ^^ Linear fog start
// ^^ Linear fog end
@@ -220,54 +220,54 @@ public class Feature {
// ^^ GL_FOG_MODE value
));
attribToFeatures.put(GL11.GL_HINT_BIT, ImmutableSet.of(
GLStateManager.getHintState()
GLSMRasterizer.getHintState()
));
attribToFeatures.put(GL11.GL_LIGHTING_BIT, ImmutableSet.of(
GLStateManager.getColorMaterial()
, GLStateManager.getColorMaterialFace()
, GLStateManager.getColorMaterialParameter()
, GLStateManager.getLightModel()
, GLStateManager.getLightingState()
GLSMLighting.getColorMaterial()
, GLSMLighting.getColorMaterialFace()
, GLSMLighting.getColorMaterialParameter()
, GLSMLighting.getLightModel()
, GLSMLighting.getLightingState()
// Enable bit for each light
, GLStateManager.getLightStates()[0] // GL_LIGHT0
, GLStateManager.getLightStates()[1] // GL_LIGHT1
, GLStateManager.getLightStates()[2] // GL_LIGHT2
, GLStateManager.getLightStates()[3] // GL_LIGHT3
, GLStateManager.getLightStates()[4] // GL_LIGHT4
, GLStateManager.getLightStates()[5] // GL_LIGHT5
, GLStateManager.getLightStates()[6] // GL_LIGHT6
, GLStateManager.getLightStates()[7] // GL_LIGHT7
, GLSMLighting.getLightStates()[0] // GL_LIGHT0
, GLSMLighting.getLightStates()[1] // GL_LIGHT1
, GLSMLighting.getLightStates()[2] // GL_LIGHT2
, GLSMLighting.getLightStates()[3] // GL_LIGHT3
, GLSMLighting.getLightStates()[4] // GL_LIGHT4
, GLSMLighting.getLightStates()[5] // GL_LIGHT5
, GLSMLighting.getLightStates()[6] // GL_LIGHT6
, GLSMLighting.getLightStates()[7] // GL_LIGHT7
// Ambient, diffuse, and specular intensity for each light
// Direction, position, exponent, and cutoff angle for each light
// Constant, linear, and quadratic attenuation factors for each light
, GLStateManager.getLightDataStates()[0]
, GLStateManager.getLightDataStates()[1]
, GLStateManager.getLightDataStates()[2]
, GLStateManager.getLightDataStates()[3]
, GLStateManager.getLightDataStates()[4]
, GLStateManager.getLightDataStates()[5]
, GLStateManager.getLightDataStates()[6]
, GLStateManager.getLightDataStates()[7]
, GLSMLighting.getLightDataStates()[0]
, GLSMLighting.getLightDataStates()[1]
, GLSMLighting.getLightDataStates()[2]
, GLSMLighting.getLightDataStates()[3]
, GLSMLighting.getLightDataStates()[4]
, GLSMLighting.getLightDataStates()[5]
, GLSMLighting.getLightDataStates()[6]
, GLSMLighting.getLightDataStates()[7]
// Ambient, diffuse, specular, and emissive color for each material
// Ambient, diffuse, and specular color indices for each material
// Specular exponent for each material
, GLStateManager.getFrontMaterial()
, GLStateManager.getBackMaterial()
, GLStateManager.getShadeModelState()
, GLSMLighting.getFrontMaterial()
, GLSMLighting.getBackMaterial()
, GLSMRasterizer.getShadeModelState()
));
attribToFeatures.put(GL11.GL_LINE_BIT, ImmutableSet.of(
GLStateManager.getLineSmoothState()
, GLStateManager.getLineStippleState()
, GLStateManager.getLineState()
GLSMRasterizer.getLineSmoothState()
, GLSMRasterizer.getLineStippleState()
, GLSMRasterizer.getLineState()
));
attribToFeatures.put(GL11.GL_LIST_BIT, ImmutableSet.of(
// GL_LIST_BASE setting
));
attribToFeatures.put(GL13.GL_MULTISAMPLE_BIT, ImmutableSet.of(
GLStateManager.getMultisampleState()
, GLStateManager.getSampleAlphaToCoverageState()
, GLStateManager.getSampleAlphaToOneState()
, GLStateManager.getSampleCoverageState()
GLSMRasterizer.getMultisampleState()
, GLSMRasterizer.getSampleAlphaToCoverageState()
, GLSMRasterizer.getSampleAlphaToOneState()
, GLSMRasterizer.getSampleCoverageState()
// GL_SAMPLE_COVERAGE_VALUE value
// GL_SAMPLE_COVERAGE_INVERT value
));
@@ -283,32 +283,32 @@ public class Feature {
// GL_READ_BUFFER setting
));
attribToFeatures.put(GL11.GL_POINT_BIT, ImmutableSet.of(
GLStateManager.getPointSmoothState()
, GLStateManager.getPointSpriteState()
, GLStateManager.getPointState()
GLSMRasterizer.getPointSmoothState()
, GLSMRasterizer.getPointSpriteState()
, GLSMRasterizer.getPointState()
));
attribToFeatures.put(GL11.GL_POLYGON_BIT, ImmutableSet.of(
GLStateManager.getCullState()
, GLStateManager.getPolygonSmoothState()
, GLStateManager.getPolygonStippleState()
, GLStateManager.getPolygonOffsetFillState()
, GLStateManager.getPolygonOffsetLineState()
, GLStateManager.getPolygonOffsetPointState()
, GLStateManager.getPolygonState()
GLSMRasterizer.getCullState()
, GLSMRasterizer.getPolygonSmoothState()
, GLSMRasterizer.getPolygonStippleState()
, GLSMRasterizer.getPolygonOffsetFillState()
, GLSMRasterizer.getPolygonOffsetLineState()
, GLSMRasterizer.getPolygonOffsetPointState()
, GLSMRasterizer.getPolygonState()
));
attribToFeatures.put(GL11.GL_POLYGON_STIPPLE_BIT, ImmutableSet.of(
// Polygon stipple pattern
));
attribToFeatures.put(GL11.GL_SCISSOR_BIT, ImmutableSet.of(
GLStateManager.getScissorTest()
, GLStateManager.getScissorState()
GLSMRasterizer.getScissorTest()
, GLSMRasterizer.getScissorState()
));
attribToFeatures.put(GL11.GL_STENCIL_BUFFER_BIT, ImmutableSet.of(
GLStateManager.getStencilTest()
, GLStateManager.getStencilState()
GLSMDepthStencilAlpha.getStencilTest()
, GLSMDepthStencilAlpha.getStencilState()
));
final Set<IStateStack<?>> textureAttribs = new HashSet<>(ImmutableSet.of(
GLStateManager.getActiveTextureUnitStack()
GLSMTextures.getActiveTextureUnitStack()
// GL_TEXTURE_ENV_MODE + GL_TEXTURE_ENV_COLOR — now per-unit in TexEnvState (added below)
// Enable bits for the four texture coordinates
@@ -325,12 +325,12 @@ public class Feature {
// Current Texture Bindings - GL_TEXTURE_BINDING_2D + per-unit TexEnvState
for(int i = 0 ; i < GLStateManager.MAX_TEXTURE_UNITS; i++) {
textureAttribs.add(GLStateManager.getTextures().getTextureUnitBindings(i));
textureAttribs.add(GLStateManager.getTextures().getTexEnvState(i));
textureAttribs.add(GLStateManager.getTextures().getTexture1DStates(i));
textureAttribs.add(GLStateManager.getTextures().getTextureUnitStates(i));
textureAttribs.add(GLStateManager.getTextures().getTexture3DStates(i));
textureAttribs.add(GLStateManager.getTextures().getTextureCubeMapStates(i));
textureAttribs.add(GLSMTextures.getTextures().getTextureUnitBindings(i));
textureAttribs.add(GLSMTextures.getTextures().getTexEnvState(i));
textureAttribs.add(GLSMTextures.getTextures().getTexture1DStates(i));
textureAttribs.add(GLSMTextures.getTextures().getTextureUnitStates(i));
textureAttribs.add(GLSMTextures.getTextures().getTexture3DStates(i));
textureAttribs.add(GLSMTextures.getTextures().getTextureCubeMapStates(i));
}
// Enable bits GL_TEXTURE_GEN_x where x is S, T, R, or Q
@@ -341,17 +341,17 @@ public class Feature {
final Set<IStateStack<?>> transformAttribs = new HashSet<>(ImmutableSet.of(
// Coefficients of the six clipping planes
GLStateManager.getMatrixMode()
, GLStateManager.getNormalizeState()
, GLStateManager.getRescaleNormalState()
GLSMMatrices.getMatrixMode()
, GLSMLighting.getNormalizeState()
, GLSMLighting.getRescaleNormalState()
));
for(int i = 0; i < GLStateManager.getClipPlaneStates().length; i++) {
transformAttribs.add(GLStateManager.getClipPlaneStates()[i]);
for(int i = 0; i < GLSMRasterizer.getClipPlaneStates().length; i++) {
transformAttribs.add(GLSMRasterizer.getClipPlaneStates()[i]);
}
attribToFeatures.put(GL11.GL_TRANSFORM_BIT, transformAttribs);
attribToFeatures.put(GL11.GL_VIEWPORT_BIT, ImmutableSet.of(
GLStateManager.getViewportState()
GLSMRasterizer.getViewportState()
));
for (Int2ObjectMap.Entry<Set<IStateStack<?>>> entry : attribToFeatures.int2ObjectEntrySet()) {
@@ -121,7 +121,7 @@ public class FeedbackManager {
final float ndcY = clipVec.y / w;
final float ndcZ = clipVec.z / w;
final ViewportState vp = GLStateManager.getViewportState();
final ViewportState vp = GLSMRasterizer.getViewportState();
final float winX = vp.x + vp.width * (ndcX + 1.0f) * 0.5f;
final float winY = vp.y + vp.height * (ndcY + 1.0f) * 0.5f;
final float winZ = (float) ((vp.depthRangeFar - vp.depthRangeNear) * ndcZ + (vp.depthRangeFar + vp.depthRangeNear)) * 0.5f;
@@ -229,7 +229,7 @@ public class FeedbackManager {
}
private static void computeMVP() {
mvpMatrix.set(GLStateManager.getProjectionMatrix()).mul(GLStateManager.getModelViewMatrix());
mvpMatrix.set(GLSMMatrices.getProjectionMatrix()).mul(GLSMMatrices.getModelViewMatrix());
}
private static int computeMask(int type) {
@@ -277,13 +277,13 @@ public class FeedbackManager {
final int previousVbo = glCtx.boundVBO;
if (positionVbo != 0 && positionVbo != previousVbo) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionVbo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionVbo);
}
try {
RENDER_BACKEND.getBufferSubData(GL15.GL_ARRAY_BUFFER, offset, destination);
} finally {
if (positionVbo != 0 && positionVbo != previousVbo) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, previousVbo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, previousVbo);
}
}
}
@@ -161,7 +161,7 @@ public class GLContextState {
public final BooleanStateStack colorSumState = track(new BooleanStateStack(GL14.GL_COLOR_SUM, false, true));
public final Color4Stack clearColor = member(new Color4Stack(StackIdAllocator.nextId(), new Color4(0.0F, 0.0F, 0.0F, 0.0F)).restoreBit(StateSet.R_CLEAR_COLOR));
public final ColorMaskStack colorMask = member(new ColorMaskStack(StackIdAllocator.nextId()));
public final IntegerStateStack drawBuffer = member(new IntegerStateStack(GLStateManager.DEFAULT_DRAW_BUFFER, StackIdAllocator.nextId()).restoreBit(StateSet.R_DRAW_BUFFER));
public final IntegerStateStack drawBuffer = member(new IntegerStateStack(GLSMFramebuffer.DEFAULT_DRAW_BUFFER, StackIdAllocator.nextId()).restoreBit(StateSet.R_DRAW_BUFFER));
public final IntegerStateStack logicOpMode = member(new IntegerStateStack(GL11.GL_COPY, StackIdAllocator.nextId()).restoreBit(StateSet.R_LOGIC_OP));
public final BooleanStateStack cullState = track(new BooleanStateStack(GL11.GL_CULL_FACE));
public final AlphaState restoredAlphaScratch = new AlphaState();
@@ -245,12 +245,12 @@ public class GLContextState {
public final int[] storageBufferBindings = new int[GLStateManager.INDEXED_BUFFER_SLOTS];
public PixelStoreState pixelUnpackState = PixelStoreState.DEFAULT;
public PixelStoreState pixelPackState = PixelStoreState.DEFAULT;
public final int[] clientAttribSavedMask = new int[GLStateManager.CLIENT_ATTRIB_STACK_DEPTH];
public final PixelStoreState[] clientAttribSavedPixelUnpack = new PixelStoreState[GLStateManager.CLIENT_ATTRIB_STACK_DEPTH];
public final PixelStoreState[] clientAttribSavedPixelPack = new PixelStoreState[GLStateManager.CLIENT_ATTRIB_STACK_DEPTH];
public final int[] clientAttribSavedUnpackBuffer = new int[GLStateManager.CLIENT_ATTRIB_STACK_DEPTH];
public final int[] clientAttribSavedPackBuffer = new int[GLStateManager.CLIENT_ATTRIB_STACK_DEPTH];
public final VAOManager.ClientArrays[] clientAttribSavedArrays = new VAOManager.ClientArrays[GLStateManager.CLIENT_ATTRIB_STACK_DEPTH];
public final int[] clientAttribSavedMask = new int[GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH];
public final PixelStoreState[] clientAttribSavedPixelUnpack = new PixelStoreState[GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH];
public final PixelStoreState[] clientAttribSavedPixelPack = new PixelStoreState[GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH];
public final int[] clientAttribSavedUnpackBuffer = new int[GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH];
public final int[] clientAttribSavedPackBuffer = new int[GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH];
public final VAOManager.ClientArrays[] clientAttribSavedArrays = new VAOManager.ClientArrays[GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH];
public int clientAttribStackPointer = 0;
public int restoreChangedMask;
public long restoreUnitChangedMask;
@@ -0,0 +1,667 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.ffp.VAOManager;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredBlendHandler;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredDepthColorHandler;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
import com.gtnewhorizons.angelica.glsm.stacks.BlendStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.CowDepths;
import com.gtnewhorizons.angelica.glsm.stacks.CowDispatch;
import com.gtnewhorizons.angelica.glsm.stacks.CowStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.RetainedState;
import com.gtnewhorizons.angelica.glsm.states.AlphaState;
import com.gtnewhorizons.angelica.glsm.states.PixelStoreState;
import com.gtnewhorizons.angelica.glsm.states.SamplerUnitArray;
import com.gtnewhorizons.angelica.glsm.states.TextureBinding;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL21;
import org.lwjgl.opengl.GL30;
import java.util.List;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_ATTRIB_STACK_DEPTH;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_TEXTURE_UNITS;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.RETAINED_SLOT;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.primaryContext;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.warnOnce;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMAttribStack {
private GLSMAttribStack() {}
public static long attribPushes;
public static long attribSlotsSaved;
public static long attribValueRestores;
public static long attribBackendCalls;
public static long attribDiscards;
/** Register a state stack id as modified at the current depth (called from beforeModify). */
public static void registerModifiedState(GLContextState c, int id) {
if (c.attribDepth > 0) {
final int depth = c.attribDepth - 1;
c.modifiedIds[depth][c.modifiedCount[depth]++] = id;
if (!c.poppingAttributes) {
attribSlotsSaved++;
}
}
}
static final int CLIENT_ATTRIB_STACK_DEPTH = 16;
public static void glPushClientAttrib(int mask) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final int sp = glCtx.clientAttribStackPointer;
if (sp < CLIENT_ATTRIB_STACK_DEPTH) {
glCtx.clientAttribSavedMask[sp] = mask;
if ((mask & GL11.GL_CLIENT_PIXEL_STORE_BIT) != 0) {
glCtx.clientAttribSavedPixelPack[sp] = glCtx.pixelPackState;
glCtx.clientAttribSavedPixelUnpack[sp] = glCtx.pixelUnpackState;
glCtx.clientAttribSavedPackBuffer[sp] = glCtx.boundPixelPackBuffer;
glCtx.clientAttribSavedUnpackBuffer[sp] = glCtx.boundPixelUnpackBuffer;
}
if ((mask & GL11.GL_CLIENT_VERTEX_ARRAY_BIT) != 0) {
VAOManager.ClientArrays saved = glCtx.clientAttribSavedArrays[sp];
if (saved == null) glCtx.clientAttribSavedArrays[sp] = saved = new VAOManager.ClientArrays();
saved.boundVAO = glCtx.boundVAO;
saved.boundVBO = glCtx.boundVBO;
saved.boundEBO = glCtx.vaos.boundEBO;
saved.clientActiveTextureUnit = glCtx.clientActiveTextureUnit;
glCtx.vaos.saveClientArrays(saved);
}
glCtx.clientAttribStackPointer = sp + 1;
}
}
public static void glPopClientAttrib() {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (glCtx.clientAttribStackPointer > 0) {
final int sp = --glCtx.clientAttribStackPointer;
final int mask = glCtx.clientAttribSavedMask[sp];
if ((mask & GL11.GL_CLIENT_PIXEL_STORE_BIT) != 0) {
final PixelStoreState pack = glCtx.clientAttribSavedPixelPack[sp];
final PixelStoreState unpack = glCtx.clientAttribSavedPixelUnpack[sp];
glCtx.clientAttribSavedPixelPack[sp] = null;
glCtx.clientAttribSavedPixelUnpack[sp] = null;
PixelStoreState.applyDiff(glCtx.pixelPackState, pack, true);
glCtx.pixelPackState = pack;
PixelStoreState.applyDiff(glCtx.pixelUnpackState, unpack, false);
glCtx.pixelUnpackState = unpack;
final int packBuffer = glCtx.clientAttribSavedPackBuffer[sp];
if (glCtx.boundPixelPackBuffer != packBuffer) GLSMBuffers.glBindBuffer(GL21.GL_PIXEL_PACK_BUFFER, packBuffer);
final int unpackBuffer = glCtx.clientAttribSavedUnpackBuffer[sp];
if (glCtx.boundPixelUnpackBuffer != unpackBuffer) GLSMBuffers.glBindBuffer(GL21.GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
}
if ((mask & GL11.GL_CLIENT_VERTEX_ARRAY_BIT) != 0) {
restoreClientArrays(glCtx, glCtx.clientAttribSavedArrays[sp]);
}
}
}
private static void restoreClientArrays(GLContextState glCtx, VAOManager.ClientArrays saved) {
final VAOManager vaos = glCtx.vaos;
if (!vaos.vaoMap.containsKey(saved.boundVAO)) return;
GLSMVertexInput.bindVertexArrayInternal(glCtx, saved.boundVAO);
glCtx.clientActiveTextureUnit = saved.clientActiveTextureUnit;
if (vaos.isBufferLive(saved.boundVBO, saved)) {
final int changed = vaos.restoreClientArrays(saved);
for (int pointers = changed & 0xFFFF; pointers != 0; pointers &= pointers - 1) {
GLSMVertexInput.pointAttrib(glCtx, Integer.numberOfTrailingZeros(pointers));
}
for (int enables = changed >>> 16; enables != 0; enables &= enables - 1) {
GLSMVertexInput.syncAttribEnable(glCtx, Integer.numberOfTrailingZeros(enables));
}
if (glCtx.boundVBO != saved.boundVBO) GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, saved.boundVBO);
}
if (vaos.boundEBO != saved.boundEBO && vaos.isBufferLive(saved.boundEBO, saved)) GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, saved.boundEBO);
}
public static void pushState(int mask) {
pushStateLive(StateSet.forMask(mask));
}
public static int pushState(StateSet set) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
final int token = ctx().attribDepth + DisplayListManager.virtualStateDepth(mode);
if (token >= MAX_ATTRIB_STACK_DEPTH) {
throw new IllegalStateException("Attrib stack overflow: max depth " + MAX_ATTRIB_STACK_DEPTH + " reached");
}
DisplayListManager.recordPushState(set);
if (mode == RecordMode.COMPILE) {
return token;
}
}
return pushStateLive(set);
}
static int pushStateLive(StateSet set) {
attribPushes++;
final GLContextState glCtx = ctx();
glCtx.exitCapture.pushAttrib();
if (glCtx.attribDepth >= MAX_ATTRIB_STACK_DEPTH) {
throw new IllegalStateException("Attrib stack overflow: max depth " + MAX_ATTRIB_STACK_DEPTH + " reached");
}
final int depthBefore = glCtx.attribDepth;
glCtx.attribSets[depthBefore] = set;
glCtx.savedBatchStateGen[depthBefore] = glCtx.batchStateGeneration;
snapshotGenerations(glCtx, set.bump);
glCtx.modifiedCount[depthBefore] = 0;
if ((set.restore & StateSet.R_PROGRAM) != 0) {
glCtx.programStack.setValue(glCtx.activeProgram);
glCtx.programStack.push();
attribSlotsSaved++;
}
glCtx.attribDepth++;
return depthBefore;
}
private static void snapshotGenerations(GLContextState glCtx, int bump) {
final int depth = glCtx.attribDepth;
if ((bump & StateSet.B_LIGHTING) != 0) {
glCtx.savedLightingGen[depth] = glCtx.lightingGeneration;
}
if ((bump & (StateSet.B_FRAG_COLORBUF | StateSet.B_FRAG_TEXTURE | StateSet.B_FRAG_FOG)) != 0) {
glCtx.savedFragmentGen[depth] = glCtx.fragmentGeneration;
}
if ((bump & StateSet.B_TRANSFORM) != 0) {
glCtx.savedMvGen[depth] = glCtx.mvGeneration;
glCtx.savedMvLinearGen[depth] = glCtx.mvLinearGeneration;
glCtx.savedProjGen[depth] = glCtx.projGeneration;
glCtx.savedTexMatGen[depth] = glCtx.texMatrixGeneration;
}
if ((bump & StateSet.B_CURRENT) != 0) {
glCtx.savedColorGen[depth] = glCtx.colorGeneration;
glCtx.savedNormalGen[depth] = glCtx.ffp.normalGeneration;
glCtx.savedTexCoordGen[depth] = glCtx.ffp.texCoordGeneration;
}
}
public static void popStateTo(int depth) {
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
while (glCtx.attribDepth + DisplayListManager.virtualStateDepth(mode) > depth) {
if (mode == RecordMode.COMPILE && DisplayListManager.recordPopStateIfPending()) continue;
if (mode == RecordMode.COMPILE_AND_EXECUTE) DisplayListManager.recordPopStateIfPending();
popState();
}
}
public static void popState() {
final GLContextState glCtx = ctx();
if (glCtx.attribDepth > 0 && glCtx.savedBatchStateGen[glCtx.attribDepth - 1] != glCtx.batchStateGeneration) {
beforeUncapturedStateChange();
}
final int poppedDepth = glCtx.attribDepth;
final StateSet set = glCtx.attribSets[poppedDepth - 1];
glCtx.exitCapture.popAttrib(set);
final boolean inspectAlpha = GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()
&& ((glCtx.alphaState.cowDepths().claimedAt(poppedDepth) && set.contains(glCtx.alphaState.stackId()))
|| (glCtx.alphaTest.cowDepths().claimedAt(poppedDepth) && set.contains(glCtx.alphaTest.stackId())));
final AlphaState effectiveAlpha = inspectAlpha ? glCtx.alphaState.readEffective(glCtx.restoredAlphaScratch) : null;
final boolean effectiveEnabled = inspectAlpha && glCtx.alphaTest.isEffectivelyEnabled();
final int effectiveFunction = inspectAlpha ? effectiveAlpha.getFunction() : 0;
final float effectiveReference = inspectAlpha ? effectiveAlpha.getReference() : 0.0f;
final boolean liveEnabled = inspectAlpha && glCtx.alphaTest.isEnabled();
final int liveFunction = inspectAlpha ? glCtx.alphaState.getFunction() : 0;
final float liveReference = inspectAlpha ? glCtx.alphaState.getReference() : 0.0f;
final boolean prevPoppingAttributes = glCtx.poppingAttributes;
glCtx.poppingAttributes = true;
try {
glCtx.attribDepth--;
final int restore = set.restore;
final boolean blendSnapshotted = set.blendSnapshot
&& (glCtx.blendState.cowDepths().claimedAt(poppedDepth) || glCtx.blendMode.cowDepths().claimedAt(poppedDepth))
&& GLSMBlend.snapshotVanillaBlendFunc();
int changed = 0;
long unitsChanged = 0L;
if ((restore & StateSet.R_PROGRAM) != 0) {
glCtx.programStack.setValue(glCtx.activeProgram);
if (glCtx.programStack.topSlotChanged()) changed |= StateSet.R_PROGRAM;
glCtx.programStack.pop();
}
final int depth = glCtx.attribDepth;
final int count = glCtx.modifiedCount[depth];
final int[] ids = glCtx.modifiedIds[depth];
final CowStateStack<?>[] stackById = glCtx.stackById;
final CowDepths[] depthsById = glCtx.depthsById;
final int[] restoreBitById = glCtx.restoreBitById;
final int[] restoreUnitById = glCtx.restoreUnitById;
final byte[] kindById = glCtx.kindById;
for (int i = 0; i < count; i++) {
final int id = ids[i];
final CowStateStack<?> cow = stackById[id];
final byte kind = kindById[id];
if (set.contains(id)) {
final int bit = restoreBitById[id];
if (bit != 0 && CowDispatch.topSlotChanged(kind, cow)) {
changed |= bit;
final int unit = restoreUnitById[id];
if (unit >= 0) unitsChanged |= 1L << Math.min(unit, 63);
}
final int slot = depthsById[id].pop();
if (slot >= 0) CowDispatch.restoreSlot(kind, cow, slot);
if (bit == 0
&& (kind == CowDispatch.BOOLEAN
|| kind == CowDispatch.CLIP_PLANE_BOOLEAN
|| kind == CowDispatch.TEXTURE_UNIT_BOOLEAN)) attribValueRestores++;
} else {
if (depthsById[id].discard(poppedDepth) >= 0) registerModifiedState(glCtx, id);
attribDiscards++;
}
}
glCtx.modifiedCount[depth] = 0;
glCtx.restoreChangedMask = changed;
glCtx.restoreUnitChangedMask = unitsChanged;
applyRestoredState(set, blendSnapshotted);
} finally {
glCtx.poppingAttributes = prevPoppingAttributes;
}
if (inspectAlpha) {
glCtx.alphaState.readEffective(glCtx.restoredAlphaScratch);
if (effectiveEnabled != glCtx.alphaTest.isEffectivelyEnabled()
|| effectiveFunction != effectiveAlpha.getFunction()
|| Float.compare(effectiveReference, effectiveAlpha.getReference()) != 0
|| liveEnabled != glCtx.alphaTest.isEnabled()
|| liveFunction != glCtx.alphaState.getFunction()
|| Float.compare(liveReference, glCtx.alphaState.getReference()) != 0) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
}
}
public static void retainModifiedState(int depth, RetainedState out) {
final GLContextState glCtx = ctx();
if (depth < 0 || depth != glCtx.attribDepth - 1) {
throw new IllegalStateException("retainModifiedState: depth " + depth + " is not the open push (attrib depth " + glCtx.attribDepth + ")");
}
glCtx.retainedOwner = out;
final int count = glCtx.modifiedCount[depth];
final int[] ids = glCtx.modifiedIds[depth];
final CowStateStack<?>[] stackById = glCtx.stackById;
out.ensureCapacity(count);
for (int i = 0; i < count; i++) {
final int id = ids[i];
stackById[id].captureSlot(RETAINED_SLOT);
out.ids[i] = id;
}
out.count = count;
out.program = glCtx.activeProgram;
out.programGen = GLSMPrograms.programLifetimeGeneration;
}
public static void applyRetainedState(RetainedState in) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (glCtx.retainedOwner != in) return;
final CowStateStack<?>[] stackById = glCtx.stackById;
final byte[] kindById = glCtx.kindById;
final int[] ids = in.ids;
final int count = in.count;
int first = 0;
while (first < count && !CowDispatch.slotChanged(kindById[ids[first]], stackById[ids[first]], RETAINED_SLOT)) first++;
if (first < count) applyRetainedChanges(glCtx, in, first);
if (in.program != glCtx.activeProgram && (in.program == 0 || in.programGen == GLSMPrograms.programLifetimeGeneration)) GLSMPrograms.glUseProgram(in.program);
}
private static void applyRetainedChanges(GLContextState glCtx, RetainedState in, int first) {
beforeUncapturedStateChange();
final boolean blendSnapshotted = GLSMBlend.snapshotVanillaBlendFunc();
final int alphaFuncId = glCtx.alphaState.stackId();
final int alphaTestId = glCtx.alphaTest.stackId();
boolean alphaChanged = false;
final boolean prevPoppingAttributes = glCtx.poppingAttributes;
glCtx.poppingAttributes = true;
try {
final CowStateStack<?>[] stackById = glCtx.stackById;
final int[] restoreBitById = glCtx.restoreBitById;
final int[] restoreUnitById = glCtx.restoreUnitById;
final byte[] kindById = glCtx.kindById;
int changed = 0;
long unitsChanged = 0L;
for (int i = first; i < in.count; i++) {
final int id = in.ids[i];
final CowStateStack<?> cow = stackById[id];
final byte kind = kindById[id];
if (!CowDispatch.slotChanged(kind, cow, RETAINED_SLOT)) continue;
cow.beforeModify();
final int bit = restoreBitById[id];
if (bit != 0) {
changed |= bit;
final int unit = restoreUnitById[id];
if (unit >= 0) unitsChanged |= 1L << Math.min(unit, 63);
}
CowDispatch.restoreSlot(kind, cow, RETAINED_SLOT);
if (id == alphaFuncId || id == alphaTestId) alphaChanged = true;
}
glCtx.restoreChangedMask = changed;
glCtx.restoreUnitChangedMask = unitsChanged;
issueRestoredBackendState(glCtx, -1);
glCtx.lightingGeneration++;
glCtx.fragmentGeneration++;
glCtx.colorGeneration++;
glCtx.ffp.normalGeneration++;
glCtx.ffp.texCoordGeneration++;
glCtx.dirtyColorAttrib = true;
glCtx.dirtyNormalAttrib = true;
glCtx.dirtyTexCoordAttrib = true;
GLSMBlend.postVanillaBlendChangeIfMoved(blendSnapshotted);
} finally {
glCtx.poppingAttributes = prevPoppingAttributes;
}
if (alphaChanged && GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
}
private static boolean isDepthColorOverridden() {
final DeferredDepthColorHandler dch = GLSMHooks.depthColorHandler;
return dch != null && dch.isOverrideHeld();
}
public static void replayStateToBackend() {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (RENDER_BACKEND == null) return;
final List<BooleanStateStack> booleanStates = glCtx.allBooleanStates;
for (int i = 0; i < booleanStates.size(); i++) {
booleanStates.get(i).applyToBackend();
}
RENDER_BACKEND.depthFunc(glCtx.depthState.getFunc());
RENDER_BACKEND.depthMask(glCtx.depthState.isEnabled());
RENDER_BACKEND.clearDepth(glCtx.depthState.getClearValue());
GLSMBlend.issueBlendFunc(glCtx.blendState);
glCtx.blendState.clearFuncUnknownState();
RENDER_BACKEND.blendEquationSeparate(glCtx.blendState.getEquationRgb(), glCtx.blendState.getEquationAlpha());
RENDER_BACKEND.blendColor(glCtx.blendState.getBlendColorR(), glCtx.blendState.getBlendColorG(), glCtx.blendState.getBlendColorB(), glCtx.blendState.getBlendColorA());
RENDER_BACKEND.colorMask(glCtx.colorMask.red, glCtx.colorMask.green, glCtx.colorMask.blue, glCtx.colorMask.alpha);
RENDER_BACKEND.clearColor(glCtx.clearColor.getRed(), glCtx.clearColor.getGreen(), glCtx.clearColor.getBlue(), glCtx.clearColor.getAlpha());
RENDER_BACKEND.logicOp(glCtx.logicOpMode.getValue());
RENDER_BACKEND.stencilFuncSeparate(GL11.GL_FRONT, glCtx.stencilState.getFuncFront(), glCtx.stencilState.getRefFront(), glCtx.stencilState.getValueMaskFront());
RENDER_BACKEND.stencilFuncSeparate(GL11.GL_BACK, glCtx.stencilState.getFuncBack(), glCtx.stencilState.getRefBack(), glCtx.stencilState.getValueMaskBack());
RENDER_BACKEND.stencilOpSeparate(GL11.GL_FRONT, glCtx.stencilState.getFailOpFront(), glCtx.stencilState.getZFailOpFront(), glCtx.stencilState.getZPassOpFront());
RENDER_BACKEND.stencilOpSeparate(GL11.GL_BACK, glCtx.stencilState.getFailOpBack(), glCtx.stencilState.getZFailOpBack(), glCtx.stencilState.getZPassOpBack());
RENDER_BACKEND.stencilMaskSeparate(GL11.GL_FRONT, glCtx.stencilState.getWriteMaskFront());
RENDER_BACKEND.stencilMaskSeparate(GL11.GL_BACK, glCtx.stencilState.getWriteMaskBack());
RENDER_BACKEND.clearStencil(glCtx.stencilState.getClearValue());
RENDER_BACKEND.viewport(glCtx.viewportState.x, glCtx.viewportState.y, glCtx.viewportState.width, glCtx.viewportState.height);
RENDER_BACKEND.depthRange(glCtx.viewportState.depthRangeNear, glCtx.viewportState.depthRangeFar);
RENDER_BACKEND.scissor(glCtx.scissorState.x, glCtx.scissorState.y, glCtx.scissorState.width, glCtx.scissorState.height);
RENDER_BACKEND.lineWidth(Math.clamp(glCtx.lineState.getWidth(), GLSMRasterizer.lineWidthMin, GLSMRasterizer.lineWidthMax));
GLSMRasterizer.applyPointState(glCtx);
GLSMRasterizer.applyHintState(glCtx);
RENDER_BACKEND.polygonMode(GL11.GL_FRONT_AND_BACK, glCtx.polygonState.getFrontMode());
applyPolygonOffset(glCtx);
RENDER_BACKEND.cullFace(glCtx.polygonState.getCullFaceMode());
RENDER_BACKEND.frontFace(glCtx.polygonState.getFrontFace());
final SamplerUnitArray samplerUnits = glCtx.samplerUnits;
for (int i = 0; i <= samplerUnits.getHighestBoundUnit(); i++) {
final int sampler = samplerUnits.get(i);
if (sampler != 0) RENDER_BACKEND.bindSampler(i, sampler);
}
for (int i = 0; i <= glCtx.maxBoundTextureUnit; i++) {
final TextureBinding b = glCtx.textures.getTextureUnitBindings(i);
RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + i);
RENDER_BACKEND.bindTexture(b.getTarget() == 0 ? GL11.GL_TEXTURE_2D : b.getTarget(), b.getBinding());
}
RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + GLSMTextures.getActiveTextureUnit());
if (glCtx.defaultVAO == 0 && primaryContext().defaultVAO != 0) glCtx.defaultVAO = RENDER_BACKEND.genVertexArrays();
if (!glCtx.vaos.isInitialized()) glCtx.vaos.init(glCtx.defaultVAO);
RENDER_BACKEND.bindVertexArray(glCtx.boundVAO != 0 ? glCtx.boundVAO : glCtx.defaultVAO);
RENDER_BACKEND.useProgram(glCtx.activeProgram);
glCtx.ffp.invalidateProgram();
RENDER_BACKEND.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, glCtx.drawFramebuffer);
RENDER_BACKEND.bindFramebuffer(GL30.GL_READ_FRAMEBUFFER, glCtx.readFramebuffer);
glCtx.dirtyColorAttrib = true;
glCtx.dirtyNormalAttrib = true;
glCtx.dirtyTexCoordAttrib = true;
glCtx.dirtyLightmapAttrib = true;
glCtx.dirtyEntityIdsAttrib = true;
}
private static void applyPolygonOffset(GLContextState glCtx) {
final float clamp = glCtx.polygonState.getOffsetClamp();
if (clamp == 0.0f) {
RENDER_BACKEND.polygonOffset(glCtx.polygonState.getOffsetFactor(), glCtx.polygonState.getOffsetUnits());
} else {
RENDER_BACKEND.polygonOffsetClamp(glCtx.polygonState.getOffsetFactor(), glCtx.polygonState.getOffsetUnits(), clamp);
}
}
private static void issueRestoredBackendState(GLContextState glCtx, int restore) {
final int changed = glCtx.restoreChangedMask;
if ((restore & StateSet.R_DEPTH) != 0 && (changed & StateSet.R_DEPTH) != 0) {
attribValueRestores++;
RENDER_BACKEND.depthFunc(glCtx.depthState.getFunc());
attribBackendCalls++;
if (!isDepthColorOverridden()) {
RENDER_BACKEND.depthMask(glCtx.depthState.isEnabled());
attribBackendCalls++;
}
RENDER_BACKEND.clearDepth(glCtx.depthState.getClearValue());
attribBackendCalls++;
}
if ((restore & StateSet.R_BLEND) != 0) {
final BlendStateStack blend = glCtx.blendState;
if ((changed & StateSet.R_BLEND) != 0 || blend.isFuncUnknown()) {
attribValueRestores++;
final DeferredBlendHandler restoreBlendHandler = GLSMHooks.blendHandler;
if (restoreBlendHandler == null || !restoreBlendHandler.isOverrideHeld()) {
GLSMBlend.issueBlendFunc(blend);
attribBackendCalls++;
blend.clearFuncUnknownState();
}
if ((changed & StateSet.R_BLEND) != 0) {
RENDER_BACKEND.blendEquationSeparate(blend.getEquationRgb(), blend.getEquationAlpha());
attribBackendCalls++;
RENDER_BACKEND.blendColor(
blend.getBlendColorR(), blend.getBlendColorG(), blend.getBlendColorB(), blend.getBlendColorA());
attribBackendCalls++;
}
}
}
if ((restore & StateSet.R_COLOR_MASK) != 0 && (changed & StateSet.R_COLOR_MASK) != 0 && !isDepthColorOverridden()) {
attribValueRestores++;
RENDER_BACKEND.colorMask(glCtx.colorMask.red, glCtx.colorMask.green, glCtx.colorMask.blue, glCtx.colorMask.alpha);
attribBackendCalls++;
}
if ((restore & StateSet.R_CLEAR_COLOR) != 0 && (changed & StateSet.R_CLEAR_COLOR) != 0) {
attribValueRestores++;
RENDER_BACKEND.clearColor(glCtx.clearColor.getRed(), glCtx.clearColor.getGreen(), glCtx.clearColor.getBlue(), glCtx.clearColor.getAlpha());
attribBackendCalls++;
}
if ((restore & StateSet.R_DRAW_BUFFER) != 0 && (changed & StateSet.R_DRAW_BUFFER) != 0 && glCtx.drawFramebuffer == 0) {
attribValueRestores++;
RENDER_BACKEND.drawBuffer(glCtx.drawBuffer.getValue());
attribBackendCalls++;
}
if ((restore & StateSet.R_LOGIC_OP) != 0 && (changed & StateSet.R_LOGIC_OP) != 0) {
attribValueRestores++;
RENDER_BACKEND.logicOp(glCtx.logicOpMode.getValue());
attribBackendCalls++;
}
if ((restore & StateSet.R_STENCIL) != 0 && (changed & StateSet.R_STENCIL) != 0) {
attribValueRestores++;
RENDER_BACKEND.stencilFuncSeparate(GL11.GL_FRONT, glCtx.stencilState.getFuncFront(), glCtx.stencilState.getRefFront(), glCtx.stencilState.getValueMaskFront());
RENDER_BACKEND.stencilFuncSeparate(GL11.GL_BACK, glCtx.stencilState.getFuncBack(), glCtx.stencilState.getRefBack(), glCtx.stencilState.getValueMaskBack());
RENDER_BACKEND.stencilOpSeparate(GL11.GL_FRONT, glCtx.stencilState.getFailOpFront(), glCtx.stencilState.getZFailOpFront(), glCtx.stencilState.getZPassOpFront());
RENDER_BACKEND.stencilOpSeparate(GL11.GL_BACK, glCtx.stencilState.getFailOpBack(), glCtx.stencilState.getZFailOpBack(), glCtx.stencilState.getZPassOpBack());
RENDER_BACKEND.stencilMaskSeparate(GL11.GL_FRONT, glCtx.stencilState.getWriteMaskFront());
RENDER_BACKEND.stencilMaskSeparate(GL11.GL_BACK, glCtx.stencilState.getWriteMaskBack());
RENDER_BACKEND.clearStencil(glCtx.stencilState.getClearValue());
attribBackendCalls += 7;
}
if ((restore & StateSet.R_VIEWPORT) != 0 && (changed & StateSet.R_VIEWPORT) != 0) {
attribValueRestores++;
RENDER_BACKEND.viewport(glCtx.viewportState.x, glCtx.viewportState.y, glCtx.viewportState.width, glCtx.viewportState.height);
RENDER_BACKEND.depthRange(glCtx.viewportState.depthRangeNear, glCtx.viewportState.depthRangeFar);
attribBackendCalls += 2;
}
if ((restore & StateSet.R_SCISSOR) != 0 && (changed & StateSet.R_SCISSOR) != 0) {
attribValueRestores++;
RENDER_BACKEND.scissor(glCtx.scissorState.x, glCtx.scissorState.y, glCtx.scissorState.width, glCtx.scissorState.height);
attribBackendCalls++;
}
if ((restore & StateSet.R_LINE) != 0 && (changed & StateSet.R_LINE) != 0) {
attribValueRestores++;
RENDER_BACKEND.lineWidth(Math.clamp(glCtx.lineState.getWidth(), GLSMRasterizer.lineWidthMin, GLSMRasterizer.lineWidthMax));
attribBackendCalls++;
}
if ((restore & StateSet.R_POINT) != 0 && (changed & StateSet.R_POINT) != 0) {
attribValueRestores++;
GLSMRasterizer.applyPointState(glCtx);
attribBackendCalls++;
}
if ((restore & StateSet.R_HINT) != 0 && (changed & StateSet.R_HINT) != 0) {
attribValueRestores++;
GLSMRasterizer.applyHintState(glCtx);
attribBackendCalls++;
}
if ((restore & StateSet.R_POLYGON) != 0 && (changed & StateSet.R_POLYGON) != 0) {
attribValueRestores++;
RENDER_BACKEND.polygonMode(GL11.GL_FRONT_AND_BACK, glCtx.polygonState.getFrontMode());
applyPolygonOffset(glCtx);
RENDER_BACKEND.cullFace(glCtx.polygonState.getCullFaceMode());
RENDER_BACKEND.frontFace(glCtx.polygonState.getFrontFace());
attribBackendCalls += 4;
}
final boolean textureBitSet = (restore & StateSet.R_TEXTURE) != 0 && (changed & StateSet.R_TEXTURE) != 0;
final boolean activeUnitBitSet = (restore & StateSet.R_ACTIVE_UNIT) != 0;
if (textureBitSet || activeUnitBitSet) {
boolean unitTouched = false;
if (textureBitSet) {
final long unitsChanged = glCtx.restoreUnitChangedMask;
for (int i = 0; i < MAX_TEXTURE_UNITS; i++) {
if ((unitsChanged & (1L << Math.min(i, 63))) != 0) {
final TextureBinding restored = glCtx.textures.getTextureUnitBindings(i);
final int restoredTarget = restored.getTarget() != 0 ? restored.getTarget() : GL11.GL_TEXTURE_2D;
RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + i);
RENDER_BACKEND.bindTexture(restoredTarget, restored.getBinding());
attribValueRestores++;
attribBackendCalls += 2;
unitTouched = true;
}
}
}
if (unitTouched || (activeUnitBitSet && (changed & StateSet.R_ACTIVE_UNIT) != 0)) {
RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + glCtx.activeTextureUnit.getValue());
attribValueRestores++;
attribBackendCalls++;
}
}
}
/**
* After popping GLSM stacks, apply restored state to the GL driver.
*/
private static void applyRestoredState(StateSet set, boolean blendSnapshotted) {
final GLContextState glCtx = ctx();
final int restore = set.restore;
final int changed = glCtx.restoreChangedMask;
issueRestoredBackendState(glCtx, restore);
final int bump = set.bump;
final int depth = glCtx.attribDepth;
if ((bump & StateSet.B_LIGHTING) != 0 && glCtx.lightingGeneration != glCtx.savedLightingGen[depth]) glCtx.lightingGeneration++;
if ((bump & StateSet.B_FRAG_FOG) != 0 && glCtx.fragmentGeneration != glCtx.savedFragmentGen[depth]) glCtx.fragmentGeneration++;
if ((bump & StateSet.B_FRAG_COLORBUF) != 0 && glCtx.fragmentGeneration != glCtx.savedFragmentGen[depth]) glCtx.fragmentGeneration++;
if ((bump & StateSet.B_FRAG_TEXTURE) != 0 && glCtx.fragmentGeneration != glCtx.savedFragmentGen[depth]) glCtx.fragmentGeneration++;
if ((bump & StateSet.B_TRANSFORM) != 0) {
if (glCtx.mvGeneration != glCtx.savedMvGen[depth]) glCtx.mvGeneration++;
if (glCtx.mvLinearGeneration != glCtx.savedMvLinearGen[depth]) glCtx.mvLinearGeneration++;
if (glCtx.projGeneration != glCtx.savedProjGen[depth]) glCtx.projGeneration++;
if (glCtx.texMatrixGeneration != glCtx.savedTexMatGen[depth]) glCtx.texMatrixGeneration++;
}
if ((bump & StateSet.B_CURRENT) != 0) {
if (glCtx.colorGeneration != glCtx.savedColorGen[depth]) {
glCtx.colorGeneration++;
glCtx.dirtyColorAttrib = true;
}
if (glCtx.ffp.normalGeneration != glCtx.savedNormalGen[depth]) {
glCtx.ffp.normalGeneration++;
glCtx.dirtyNormalAttrib = true;
}
if (glCtx.ffp.texCoordGeneration != glCtx.savedTexCoordGen[depth]) {
glCtx.ffp.texCoordGeneration++;
glCtx.dirtyTexCoordAttrib = true;
}
if ((restore & StateSet.R_SECONDARY_COLOR) != 0 && (changed & StateSet.R_SECONDARY_COLOR) != 0) glCtx.fragmentGeneration++;
}
GLSMBlend.postVanillaBlendChangeIfMoved(blendSnapshotted);
if ((restore & StateSet.R_PROGRAM) != 0 && (changed & StateSet.R_PROGRAM) != 0) {
GLSMPrograms.glUseProgram(glCtx.programStack.getValue());
attribValueRestores++;
attribBackendCalls++;
}
}
public static void glPushAttrib(int mask) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPushAttrib(mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
GLDebug.pushGroup("pushState");
pushState(mask);
}
public static void glPopAttrib() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPopAttrib();
if (mode == RecordMode.COMPILE) {
return;
}
}
if (ctx().attribDepth == 0) {
rejectExitCapture();
warnOnce("popattrib-underflow", "glPopAttrib called with an empty attrib stack; ignoring");
return;
}
GLDebug.popGroup();
GLDebug.pushGroup("popState");
try {
popState();
} finally {
GLDebug.popGroup();
}
}
public static boolean isPoppingAttributes() {
return ctx().poppingAttributes;
}
public static int getAttribDepth() {
return ctx().attribDepth;
}
}
@@ -0,0 +1,335 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredBlendHandler;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredDepthColorHandler;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMConfig;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
import com.gtnewhorizons.angelica.glsm.stacks.BlendStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.Color4Stack;
import com.gtnewhorizons.angelica.glsm.stacks.ColorMaskStack;
import com.gtnewhorizons.angelica.glsm.stacks.IntegerStateStack;
import com.gtnewhorizons.angelica.glsm.states.BlendState;
import com.gtnewhorizons.angelica.glsm.states.ColorMask;
import org.lwjgl.opengl.GL11;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMBlend {
private GLSMBlend() {}
public static void glBlendColor(float red, float green, float blue, float alpha) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordBlendColor(red, green, blue, alpha);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
final boolean bypass = !caching;
if (bypass || red != glCtx.blendState.getBlendColorR() || green != glCtx.blendState.getBlendColorG() || blue != glCtx.blendState.getBlendColorB() || alpha != glCtx.blendState.getBlendColorA()) {
mod(glCtx.blendState);
beforeUncapturedStateChange();
glCtx.blendState.setBlendColorR(red);
glCtx.blendState.setBlendColorG(green);
glCtx.blendState.setBlendColorB(blue);
glCtx.blendState.setBlendColorA(alpha);
RENDER_BACKEND.blendColor(red, green, blue, alpha);
}
}
public static void glBlendFuncSeparatei(int buf, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) {
rejectExitCapture();
RENDER_BACKEND.blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
ctx().blendState.setFuncUnknownState();
}
public static void enableBlend() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_BLEND);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableBlend(ctx());
}
static void enableBlend(GLContextState glCtx) {
final BooleanStateStack blend = glCtx.blendMode;
final boolean wasEnabled = blend.isEffectivelyEnabled();
final DeferredBlendHandler bh = GLSMHooks.blendHandler;
if (bh != null && bh.isBlendLocked()) {
glCtx.exitCapture.capability(GL11.GL_BLEND, -1);
blend.beforeModify();
bh.deferBlendModeToggle(true);
} else {
blend.enable();
}
if (!wasEnabled && blend.isEffectivelyEnabled()) postVanillaBlendChange();
}
public static void disableBlend() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_BLEND);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableBlend(ctx());
}
static void disableBlend(GLContextState glCtx) {
final BooleanStateStack blend = glCtx.blendMode;
final boolean wasEnabled = blend.isEffectivelyEnabled();
final DeferredBlendHandler bh = GLSMHooks.blendHandler;
if (bh != null && bh.isBlendLocked()) {
glCtx.exitCapture.capability(GL11.GL_BLEND, -1);
blend.beforeModify();
bh.deferBlendModeToggle(false);
} else {
blend.disable();
}
if (wasEnabled && !blend.isEffectivelyEnabled()) postVanillaBlendChange();
}
private static void postVanillaBlendChange() {
if (GLSMHooks.VANILLA_BLEND_CHANGE.hasListeners()) {
GLSMHooks.VANILLA_BLEND_CHANGE.post(GLSMHooks.vanillaBlendChangeEvent);
}
}
static boolean snapshotVanillaBlendFunc() {
if (!GLSMHooks.VANILLA_BLEND_CHANGE.hasListeners()) return false;
final GLContextState glCtx = ctx();
glCtx.blendState.readEffective(glCtx.vanillaBlendBefore);
glCtx.vanillaBlendEnabledBefore = glCtx.blendMode.isEffectivelyEnabled();
return true;
}
static void postVanillaBlendChangeIfMoved(boolean snapshotted) {
if (!snapshotted) return;
final GLContextState glCtx = ctx();
final BlendState before = glCtx.vanillaBlendBefore;
final BlendState after = glCtx.blendState.readEffective(glCtx.vanillaBlendAfter);
if (glCtx.blendMode.isEffectivelyEnabled() != glCtx.vanillaBlendEnabledBefore
|| after.getSrcRgb() != before.getSrcRgb()
|| after.getDstRgb() != before.getDstRgb()
|| after.getSrcAlpha() != before.getSrcAlpha()
|| after.getDstAlpha() != before.getDstAlpha()) {
postVanillaBlendChange();
}
}
public static boolean isEffectiveBlendEnabled() {
return ctx().blendMode.isEffectivelyEnabled();
}
public static BlendState getEffectiveBlendState(BlendState out) {
return ctx().blendState.readEffective(out);
}
public static ColorMask getEffectiveColorMask(ColorMask out) {
return ctx().colorMask.readEffective(out);
}
public static void glBlendFunc(int srcFactor, int dstFactor) {
tryBlendFuncSeparate(srcFactor, dstFactor, srcFactor, dstFactor);
}
static void issueBlendFunc(BlendStateStack blend) {
if (GLSMConfig.hudCacheOverride) {
RENDER_BACKEND.blendFuncSeparate(blend.getSrcRgb(), blend.getDstRgb(), GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
} else {
RENDER_BACKEND.blendFuncSeparate(blend.getSrcRgb(), blend.getDstRgb(), blend.getSrcAlpha(), blend.getDstAlpha());
}
}
public static void setHudCacheOverride(boolean enabled) {
if (GLSMConfig.hudCacheOverride == enabled) return;
GLSMConfig.hudCacheOverride = enabled;
final DeferredBlendHandler bh = GLSMHooks.blendHandler;
if (bh != null && bh.isOverrideHeld()) return;
final BlendStateStack blend = ctx().blendState;
issueBlendFunc(blend);
blend.clearFuncUnknownState();
}
public static void glBlendEquation(int mode) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (DisplayListManager.isRecording()) {
throw DisplayListManager.unsupportedInList("glBlendEquation");
}
final boolean caching = isCachingEnabled();
final boolean bypass = !caching;
if (bypass || glCtx.blendState.getEquationRgb() != mode || glCtx.blendState.getEquationAlpha() != mode) {
mod(glCtx.blendState);
beforeUncapturedStateChange();
glCtx.blendState.setEquationRgb(mode);
glCtx.blendState.setEquationAlpha(mode);
RENDER_BACKEND.blendEquation(mode);
}
}
public static void glBlendEquationSeparate(int modeRGB, int modeAlpha) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (DisplayListManager.isRecording()) {
throw DisplayListManager.unsupportedInList("glBlendEquationSeparate");
}
final boolean caching = isCachingEnabled();
final boolean bypass = !caching;
if (bypass || glCtx.blendState.getEquationRgb() != modeRGB || glCtx.blendState.getEquationAlpha() != modeAlpha) {
mod(glCtx.blendState);
beforeUncapturedStateChange();
glCtx.blendState.setEquationRgb(modeRGB);
glCtx.blendState.setEquationAlpha(modeAlpha);
RENDER_BACKEND.blendEquationSeparate(modeRGB, modeAlpha);
}
}
public static void tryBlendFuncSeparate(int srcRgb, int dstRgb, int srcAlpha, int dstAlpha) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.writeBlend();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordBlendFunc(srcRgb, dstRgb, srcAlpha, dstAlpha);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean snapshotted = snapshotVanillaBlendFunc();
final DeferredBlendHandler bh = GLSMHooks.blendHandler;
if (bh != null && bh.isBlendLocked()) {
mod(glCtx.blendState);
bh.deferBlendFunc(srcRgb, dstRgb, srcAlpha, dstAlpha);
postVanillaBlendChangeIfMoved(snapshotted);
return;
}
final boolean caching = isCachingEnabled();
final boolean bypass = !caching;
if (bypass || glCtx.blendState.getSrcRgb() != srcRgb || glCtx.blendState.getDstRgb() != dstRgb || glCtx.blendState.getSrcAlpha() != srcAlpha || glCtx.blendState.getDstAlpha() != dstAlpha || glCtx.blendState.isFuncUnknown()) {
mod(glCtx.blendState);
glCtx.blendState.setAll(srcRgb, dstRgb, srcAlpha, dstAlpha);
glCtx.blendState.clearFuncUnknownState();
issueBlendFunc(glCtx.blendState);
if (GLSMHooks.BLEND_FUNC_CHANGE.hasListeners()) {
final boolean hudCache = GLSMConfig.hudCacheOverride;
GLSMHooks.blendFuncChangeEvent.srcRgb = srcRgb;
GLSMHooks.blendFuncChangeEvent.dstRgb = dstRgb;
GLSMHooks.blendFuncChangeEvent.srcAlpha = hudCache ? GL11.GL_ONE : srcAlpha;
GLSMHooks.blendFuncChangeEvent.dstAlpha = hudCache ? GL11.GL_ONE_MINUS_SRC_ALPHA : dstAlpha;
GLSMHooks.BLEND_FUNC_CHANGE.post(GLSMHooks.blendFuncChangeEvent);
}
}
postVanillaBlendChangeIfMoved(snapshotted);
}
public static void glBlendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) {
tryBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
public static void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.writeDepthColor(ExitStateCapture.COLOR_MASK);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColorMask(red, green, blue, alpha);
if (mode == RecordMode.COMPILE) {
return;
}
}
final DeferredDepthColorHandler dch = GLSMHooks.depthColorHandler;
if (dch != null && dch.isDepthColorLocked()) {
mod(glCtx.colorMask);
dch.deferColorMask(red, green, blue, alpha);
return;
}
final boolean caching = isCachingEnabled();
final boolean bypass = !caching;
if (bypass || red != glCtx.colorMask.red || green != glCtx.colorMask.green || blue != glCtx.colorMask.blue || alpha != glCtx.colorMask.alpha) {
mod(glCtx.colorMask);
glCtx.colorMask.setAll(red, green, blue, alpha);
RENDER_BACKEND.colorMask(red, green, blue, alpha);
}
}
public static void glClearColor(float red, float green, float blue, float alpha) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordClearColor(red, green, blue, alpha);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || red != glCtx.clearColor.getRed() || green != glCtx.clearColor.getGreen() || blue != glCtx.clearColor.getBlue() || alpha != glCtx.clearColor.getAlpha()) {
mod(glCtx.clearColor);
glCtx.clearColor.setRed(red);
glCtx.clearColor.setGreen(green);
glCtx.clearColor.setBlue(blue);
glCtx.clearColor.setAlpha(alpha);
RENDER_BACKEND.clearColor(red, green, blue, alpha);
}
}
public static void glLogicOp(int opcode) {
rejectExitCapture();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLogicOp(opcode);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (!isCachingEnabled() || ctx().logicOpMode.getValue() != opcode) beforeUncapturedStateChange();
if (isCachingEnabled()) mod(ctx().logicOpMode).setValue(opcode);
RENDER_BACKEND.logicOp(opcode);
}
public static void defaultBlendFunc() {
tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
}
public static BlendStateStack getBlendState() {
return ctx().blendState;
}
public static BooleanStateStack getBlendMode() {
return ctx().blendMode;
}
public static Color4Stack getClearColor() {
return ctx().clearColor;
}
public static ColorMaskStack getColorMask() {
return ctx().colorMask;
}
public static IntegerStateStack getLogicOpMode() {
return ctx().logicOpMode;
}
public static BooleanStateStack getColorLogicOpState() {
return ctx().colorLogicOpState;
}
public static BooleanStateStack getIndexLogicOpState() {
return ctx().indexLogicOpState;
}
}
@@ -0,0 +1,628 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizons.angelica.glsm.ffp.FfpExtendedAttribs;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL21;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL43;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.INDEXED_BUFFER_SLOTS;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.LOGGER;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.acquireDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.initConfig;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.releaseDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.requireContext;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMBuffers {
private GLSMBuffers() {}
private static final IntOpenHashSet writeMappedBuffers = new IntOpenHashSet();
public static void glDeleteBuffers(int buffer) {
rejectExitCapture();
if (buffer == 0) return;
invalidateDeletedBuffer(buffer);
RENDER_BACKEND.deleteBuffers(buffer);
}
public static void glDeleteSync(long sync) {
rejectExitCapture();
RENDER_BACKEND.deleteSync(sync);
}
public static long glFenceSync(int condition, int flags) { rejectExitCapture(); return RENDER_BACKEND.fenceSync(condition, flags); }
public static int glClientWaitSync(long sync, int flags, long timeout) { rejectExitCapture(); return RENDER_BACKEND.clientWaitSync(sync, flags, timeout); }
public static void glWaitSync(long sync, int flags, long timeout) { rejectExitCapture(); RENDER_BACKEND.waitSync(sync, flags, timeout); }
public static int glGetSynci(long sync, int pname, IntBuffer length) { rejectExitCapture(); return RENDER_BACKEND.getSynci(sync, pname, length); }
public static void glDeleteBuffers(IntBuffer buffers) {
rejectExitCapture();
for (int i = buffers.position(); i < buffers.limit(); i++) {
invalidateDeletedBuffer(buffers.get(i));
}
RENDER_BACKEND.deleteBuffers(buffers);
}
public static void glDeleteBuffers(int[] buffers) {
for (int buffer : buffers) {
glDeleteBuffers(buffer);
}
}
private static void invalidateDeletedBuffer(int buffer) {
final GLContextState glCtx = ctx();
if (buffer == 0) return;
final boolean locked = acquireDrawLock();
try {
FfpExtendedAttribs.onDeleteBuffer(glCtx, buffer);
if (glCtx.boundVBO == buffer) glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
if (glCtx.vaos.boundEBO == buffer) glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
if (glCtx.boundPixelUnpackBuffer == buffer) glBindBuffer(GL21.GL_PIXEL_UNPACK_BUFFER, 0);
if (glCtx.boundPixelPackBuffer == buffer) glBindBuffer(GL21.GL_PIXEL_PACK_BUFFER, 0);
if (glCtx.boundCopyReadBuffer == buffer) glBindBuffer(GL31.GL_COPY_READ_BUFFER, 0);
if (glCtx.boundCopyWriteBuffer == buffer) glBindBuffer(GL31.GL_COPY_WRITE_BUFFER, 0);
for (Int2IntMap.Entry e : glCtx.boundOtherBuffers.int2IntEntrySet()) {
if (e.getIntValue() != buffer) continue;
e.setValue(0);
RENDER_BACKEND.bindBuffer(e.getIntKey(), 0);
}
for (int i = 0; i < INDEXED_BUFFER_SLOTS; i++) {
if (glCtx.uniformBufferBindings[i] == buffer) glCtx.uniformBufferBindings[i] = 0;
if (glCtx.storageBufferBindings[i] == buffer) glCtx.storageBufferBindings[i] = 0;
}
writeMappedBuffers.remove(buffer);
glCtx.vaos.onDeleteBuffer(buffer);
} finally {
if (locked) releaseDrawLock();
}
}
/** glBindBufferBase/Range also set the generic binding point, so they share this. */
private static void trackBufferBinding(GLContextState glCtx, int target, int buffer) {
if (target == GL15.GL_ARRAY_BUFFER) {
// if (boundVBO == buffer) return; TODO figure out why this breaks switching async occlusion mode
glCtx.boundVBO = buffer;
} else if (target == GL15.GL_ELEMENT_ARRAY_BUFFER) {
glCtx.vaos.onBindEBO(buffer);
} else if (target == GL21.GL_PIXEL_UNPACK_BUFFER) {
glCtx.boundPixelUnpackBuffer = buffer;
} else if (target == GL21.GL_PIXEL_PACK_BUFFER) {
glCtx.boundPixelPackBuffer = buffer;
} else if (target == GL31.GL_COPY_READ_BUFFER) {
glCtx.boundCopyReadBuffer = buffer;
} else if (target == GL31.GL_COPY_WRITE_BUFFER) {
glCtx.boundCopyWriteBuffer = buffer;
} else {
glCtx.boundOtherBuffers.put(target, buffer);
}
}
public static void glBindBuffer(int target, int buffer) {
rejectExitCapture();
final boolean locked = acquireDrawLock();
try {
trackBufferBinding(ctx(), target, buffer);
RENDER_BACKEND.bindBuffer(target, buffer);
} finally {
if (locked) releaseDrawLock();
}
}
private static boolean warnedUntrackedPixelBuffer;
private static void warnUntrackedPixelBuffer(int binding, String name) {
if (warnedUntrackedPixelBuffer || initConfig == null || !initConfig.isLwjglDebug()) return;
final int actual = RENDER_BACKEND.getInteger(binding);
if (actual == 0) return;
warnedUntrackedPixelBuffer = true;
LOGGER.warn("{} is bound to {} but GLSM's cache says 0; a call site bypassed GLSMBuffers.glBindBuffer", name, actual, new Throwable());
}
static void suspendPixelUnpackBuffer() {
if (ctx().boundPixelUnpackBuffer != 0) {
RENDER_BACKEND.bindBuffer(GL21.GL_PIXEL_UNPACK_BUFFER, 0);
} else {
warnUntrackedPixelBuffer(GL21.GL_PIXEL_UNPACK_BUFFER_BINDING, "GL_PIXEL_UNPACK_BUFFER");
}
}
static void restorePixelUnpackBuffer() {
final GLContextState glCtx = ctx();
if (glCtx.boundPixelUnpackBuffer != 0) {
RENDER_BACKEND.bindBuffer(GL21.GL_PIXEL_UNPACK_BUFFER, glCtx.boundPixelUnpackBuffer);
}
}
static void suspendPixelPackBuffer() {
if (ctx().boundPixelPackBuffer != 0) {
RENDER_BACKEND.bindBuffer(GL21.GL_PIXEL_PACK_BUFFER, 0);
} else {
warnUntrackedPixelBuffer(GL21.GL_PIXEL_PACK_BUFFER_BINDING, "GL_PIXEL_PACK_BUFFER");
}
}
static void restorePixelPackBuffer() {
final GLContextState glCtx = ctx();
if (glCtx.boundPixelPackBuffer != 0) {
RENDER_BACKEND.bindBuffer(GL21.GL_PIXEL_PACK_BUFFER, glCtx.boundPixelPackBuffer);
}
}
public static int glGenBuffers() {
requireContext("glGenBuffers");
return RENDER_BACKEND.genBuffers();
}
public static void glGenBuffers(IntBuffer buffers) {
requireContext("glGenBuffers");
for (int i = buffers.position(); i < buffers.limit(); i++) buffers.put(i, RENDER_BACKEND.genBuffers());
}
public static void glGenBuffers(int[] buffers) {
requireContext("glGenBuffers");
for (int i = 0; i < buffers.length; i++) buffers[i] = RENDER_BACKEND.genBuffers();
}
public static int glCreateBuffers() {
requireContext("glCreateBuffers");
return RENDER_BACKEND.createBuffers();
}
public static void glCreateBuffers(IntBuffer buffers) {
requireContext("glCreateBuffers");
for (int i = buffers.position(); i < buffers.limit(); i++) buffers.put(i, RENDER_BACKEND.createBuffers());
}
public static void glCreateBuffers(int[] buffers) {
requireContext("glCreateBuffers");
for (int i = 0; i < buffers.length; i++) buffers[i] = RENDER_BACKEND.createBuffers();
}
private static final int MAP_PERSISTENT_BIT = 0x40;
private static int bufferForTarget(GLContextState glCtx, int target) {
if (target == GL15.GL_ARRAY_BUFFER) return glCtx.boundVBO;
if (target == GL15.GL_ELEMENT_ARRAY_BUFFER) return glCtx.vaos.boundEBO;
if (target == GL31.GL_COPY_READ_BUFFER) return glCtx.boundCopyReadBuffer;
if (target == GL31.GL_COPY_WRITE_BUFFER) return glCtx.boundCopyWriteBuffer;
if (target == GL21.GL_PIXEL_UNPACK_BUFFER) return glCtx.boundPixelUnpackBuffer;
if (target == GL21.GL_PIXEL_PACK_BUFFER) return glCtx.boundPixelPackBuffer;
return glCtx.boundOtherBuffers.get(target);
}
private static void onBufferRespec(int target) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final int buffer = bufferForTarget(glCtx, target);
if (buffer != 0) onNamedBufferRespec(glCtx, buffer);
}
private static void onNamedBufferRespec(GLContextState glCtx, int buffer) {
rejectExitCapture();
final boolean locked = acquireDrawLock();
try {
if (!FfpExtendedAttribs.isEmpty()) FfpExtendedAttribs.onBufferRespecified(glCtx, buffer);
} finally {
if (locked) releaseDrawLock();
}
}
private static void onBufferMap(int target, int access) {
if (access == GL15.GL_READ_ONLY) return;
onBufferWriteMap(target);
}
private static void onBufferMapRange(int target, int access) {
if ((access & GL30.GL_MAP_WRITE_BIT) == 0) return;
if ((access & MAP_PERSISTENT_BIT) != 0) {
markPersistentlyMapped(target);
return;
}
onBufferWriteMap(target);
}
private static void onBufferWriteMap(int target) {
final GLContextState glCtx = ctx();
final int buffer = bufferForTarget(glCtx, target);
if (buffer == 0) return;
final boolean locked = acquireDrawLock();
try {
writeMappedBuffers.add(buffer);
if (!FfpExtendedAttribs.isEmpty()) FfpExtendedAttribs.onBufferRespecified(glCtx, buffer);
} finally {
if (locked) releaseDrawLock();
}
}
private static void onBufferUnmap(int target) {
final GLContextState glCtx = ctx();
final int buffer = bufferForTarget(glCtx, target);
if (buffer == 0) return;
final boolean locked = acquireDrawLock();
try {
if (writeMappedBuffers.remove(buffer) && !FfpExtendedAttribs.isEmpty()) FfpExtendedAttribs.onBufferRespecified(glCtx, buffer);
} finally {
if (locked) releaseDrawLock();
}
}
private static void onBufferStorage(int target, int flags) {
rejectExitCapture();
if ((flags & MAP_PERSISTENT_BIT) != 0) {
if (!RENDER_BACKEND.isBufferImmutable(bufferForTarget(ctx(), target))) markPersistentlyMapped(target);
return;
}
onBufferRespec(target);
}
private static void markPersistentlyMapped(int target) {
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
FfpExtendedAttribs.markPersistent(glCtx, bufferForTarget(glCtx, target));
} finally {
if (locked) releaseDrawLock();
}
}
public static void glBufferData(int target, long size, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, size, usage); }
public static void glBufferData(int target, ByteBuffer data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, ShortBuffer data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, IntBuffer data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, FloatBuffer data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, DoubleBuffer data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, LongBuffer data, int usage) { glBufferData(target, MemoryUtilities.memByteBuffer(data), usage); }
public static void glBufferData(int target, int[] data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, float[] data, int usage) { onBufferRespec(target); RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, short[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glBufferData(target, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glBufferData(int target, long[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glBufferData(target, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glBufferData(int target, double[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glBufferData(target, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void nglBufferData(int target, long size, long data, int usage) {
if (data == 0L) {
glBufferData(target, size, usage);
return;
}
glBufferData(target, MemoryUtilities.memByteBuffer(data, checkedSize(size)), usage);
}
public static void glBufferSubData(int target, long offset, ByteBuffer data) { onBufferRespec(target); RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, ShortBuffer data) { onBufferRespec(target); RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, IntBuffer data) { onBufferRespec(target); RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, FloatBuffer data) { onBufferRespec(target); RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, DoubleBuffer data) { onBufferRespec(target); RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, LongBuffer data) { glBufferSubData(target, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glBufferSubData(int target, long offset, short[] data) {
final ByteBuffer copy = copyOf(data);
glBufferSubData(target, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glBufferSubData(int target, long offset, int[] data) {
final ByteBuffer copy = copyOf(data);
glBufferSubData(target, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glBufferSubData(int target, long offset, long[] data) {
final ByteBuffer copy = copyOf(data);
glBufferSubData(target, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glBufferSubData(int target, long offset, float[] data) {
final ByteBuffer copy = copyOf(data);
glBufferSubData(target, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glBufferSubData(int target, long offset, double[] data) {
final ByteBuffer copy = copyOf(data);
glBufferSubData(target, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void nglBufferSubData(int target, long offset, long size, long data) { glBufferSubData(target, offset, MemoryUtilities.memByteBuffer(data, checkedSize(size))); }
public static ByteBuffer glMapBuffer(int target, int access) {
rejectExitCapture();
final ByteBuffer buf = RENDER_BACKEND.mapBuffer(target, access);
if (buf != null) onBufferMap(target, access);
return buf;
}
public static ByteBuffer glMapBuffer(int target, int access, ByteBuffer old_buffer) { return glMapBuffer(target, access); }
public static ByteBuffer glMapBuffer(int target, int access, long length, ByteBuffer old_buffer) {
rejectExitCapture();
final ByteBuffer buf = RENDER_BACKEND.mapBuffer(target, access, length, old_buffer);
if (buf != null) onBufferMap(target, access);
return buf;
}
public static ByteBuffer glMapBufferRange(int target, long offset, long length, int access) {
rejectExitCapture();
final ByteBuffer buf = RENDER_BACKEND.mapBufferRange(target, offset, length, access);
if (buf != null) onBufferMapRange(target, access);
return buf;
}
public static ByteBuffer glMapBufferRange(int target, long offset, long length, int access, ByteBuffer old_buffer) { return glMapBufferRange(target, offset, length, access); }
public static long glMapBufferRangeAddress(int target, long offset, long length, int access) {
rejectExitCapture();
final long address = RENDER_BACKEND.mapBufferRangeAddress(target, offset, length, access);
if (address != 0L) onBufferMapRange(target, access);
return address;
}
public static void glFlushMappedBufferRange(int target, long offset, long length) { rejectExitCapture(); RENDER_BACKEND.flushMappedBufferRange(target, offset, length); }
public static boolean glUnmapBuffer(int target) {
rejectExitCapture();
onBufferUnmap(target);
return RENDER_BACKEND.unmapBuffer(target);
}
public static void glGetBufferSubData(int target, long offset, ByteBuffer data) { rejectExitCapture(); RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, ShortBuffer data) { rejectExitCapture(); RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, IntBuffer data) { rejectExitCapture(); RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, FloatBuffer data) { rejectExitCapture(); RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, DoubleBuffer data) { rejectExitCapture(); RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, LongBuffer data) { glGetBufferSubData(target, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glGetBufferSubData(int target, long offset, short[] data) {
final ByteBuffer copy = MemoryUtilities.memAlloc(data.length << 1);
glGetBufferSubData(target, offset, copy);
copy.asShortBuffer().get(data);
MemoryUtilities.memFree(copy);
}
public static void glGetBufferSubData(int target, long offset, int[] data) {
final ByteBuffer copy = MemoryUtilities.memAlloc(data.length << 2);
glGetBufferSubData(target, offset, copy);
copy.asIntBuffer().get(data);
MemoryUtilities.memFree(copy);
}
public static void glGetBufferSubData(int target, long offset, long[] data) {
final ByteBuffer copy = MemoryUtilities.memAlloc(data.length << 3);
glGetBufferSubData(target, offset, copy);
copy.asLongBuffer().get(data);
MemoryUtilities.memFree(copy);
}
public static void glGetBufferSubData(int target, long offset, float[] data) {
final ByteBuffer copy = MemoryUtilities.memAlloc(data.length << 2);
glGetBufferSubData(target, offset, copy);
copy.asFloatBuffer().get(data);
MemoryUtilities.memFree(copy);
}
public static void glGetBufferSubData(int target, long offset, double[] data) {
final ByteBuffer copy = MemoryUtilities.memAlloc(data.length << 3);
glGetBufferSubData(target, offset, copy);
copy.asDoubleBuffer().get(data);
MemoryUtilities.memFree(copy);
}
public static void nglGetBufferSubData(int target, long offset, long size, long data) { glGetBufferSubData(target, offset, MemoryUtilities.memByteBuffer(data, checkedSize(size))); }
public static int glGetBufferParameteri(int target, int pname) { rejectExitCapture(); return RENDER_BACKEND.getBufferParameteri(target, pname); }
public static int glGetBufferParameter(int target, int pname) { return glGetBufferParameteri(target, pname); }
public static void glGetBufferParameter(int target, int pname, IntBuffer params) { params.put(params.position(), glGetBufferParameteri(target, pname)); }
public static void glGetBufferParameteriv(int target, int pname, IntBuffer params) { params.put(params.position(), glGetBufferParameteri(target, pname)); }
public static void glGetBufferParameteriv(int target, int pname, int[] params) { params[0] = glGetBufferParameteri(target, pname); }
public static void glBufferStorage(int target, long size, int flags) { onBufferStorage(target, flags); RENDER_BACKEND.bufferStorage(target, size, flags); }
public static void glBufferStorage(int target, ByteBuffer data, int flags) { onBufferStorage(target, flags); RENDER_BACKEND.bufferStorage(target, data, flags); }
public static void glBufferStorage(int target, ShortBuffer data, int flags) { glBufferStorage(target, MemoryUtilities.memByteBuffer(data), flags); }
public static void glBufferStorage(int target, IntBuffer data, int flags) { glBufferStorage(target, MemoryUtilities.memByteBuffer(data), flags); }
public static void glBufferStorage(int target, FloatBuffer data, int flags) { glBufferStorage(target, MemoryUtilities.memByteBuffer(data), flags); }
public static void glBufferStorage(int target, DoubleBuffer data, int flags) { glBufferStorage(target, MemoryUtilities.memByteBuffer(data), flags); }
public static void glBufferStorage(int target, short[] data, int flags) {
final ByteBuffer copy = copyOf(data);
glBufferStorage(target, copy, flags);
MemoryUtilities.memFree(copy);
}
public static void glBufferStorage(int target, int[] data, int flags) {
final ByteBuffer copy = copyOf(data);
glBufferStorage(target, copy, flags);
MemoryUtilities.memFree(copy);
}
public static void glBufferStorage(int target, float[] data, int flags) {
final ByteBuffer copy = copyOf(data);
glBufferStorage(target, copy, flags);
MemoryUtilities.memFree(copy);
}
public static void glBufferStorage(int target, double[] data, int flags) {
final ByteBuffer copy = copyOf(data);
glBufferStorage(target, copy, flags);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferData(int buffer, long size, int usage) { onNamedBufferRespec(ctx(), buffer); RENDER_BACKEND.namedBufferData(buffer, size, usage); }
public static void glNamedBufferData(int buffer, ByteBuffer data, int usage) { onNamedBufferRespec(ctx(), buffer); RENDER_BACKEND.namedBufferData(buffer, data, usage); }
public static void glNamedBufferData(int buffer, FloatBuffer data, int usage) { onNamedBufferRespec(ctx(), buffer); RENDER_BACKEND.namedBufferData(buffer, data, usage); }
public static void glNamedBufferData(int buffer, ShortBuffer data, int usage) { glNamedBufferData(buffer, MemoryUtilities.memByteBuffer(data), usage); }
public static void glNamedBufferData(int buffer, IntBuffer data, int usage) { glNamedBufferData(buffer, MemoryUtilities.memByteBuffer(data), usage); }
public static void glNamedBufferData(int buffer, LongBuffer data, int usage) { glNamedBufferData(buffer, MemoryUtilities.memByteBuffer(data), usage); }
public static void glNamedBufferData(int buffer, DoubleBuffer data, int usage) { glNamedBufferData(buffer, MemoryUtilities.memByteBuffer(data), usage); }
public static void glNamedBufferData(int buffer, short[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glNamedBufferData(buffer, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferData(int buffer, int[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glNamedBufferData(buffer, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferData(int buffer, long[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glNamedBufferData(buffer, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferData(int buffer, float[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glNamedBufferData(buffer, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferData(int buffer, double[] data, int usage) {
final ByteBuffer copy = copyOf(data);
glNamedBufferData(buffer, copy, usage);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferSubData(int buffer, long offset, ByteBuffer data) { onNamedBufferRespec(ctx(), buffer); RENDER_BACKEND.namedBufferSubData(buffer, offset, data); }
public static void glNamedBufferSubData(int buffer, long offset, ShortBuffer data) { glNamedBufferSubData(buffer, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glNamedBufferSubData(int buffer, long offset, IntBuffer data) { glNamedBufferSubData(buffer, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glNamedBufferSubData(int buffer, long offset, LongBuffer data) { glNamedBufferSubData(buffer, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glNamedBufferSubData(int buffer, long offset, FloatBuffer data) { glNamedBufferSubData(buffer, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glNamedBufferSubData(int buffer, long offset, DoubleBuffer data) { glNamedBufferSubData(buffer, offset, MemoryUtilities.memByteBuffer(data)); }
public static void glNamedBufferSubData(int buffer, long offset, short[] data) {
final ByteBuffer copy = copyOf(data);
glNamedBufferSubData(buffer, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferSubData(int buffer, long offset, int[] data) {
final ByteBuffer copy = copyOf(data);
glNamedBufferSubData(buffer, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferSubData(int buffer, long offset, long[] data) {
final ByteBuffer copy = copyOf(data);
glNamedBufferSubData(buffer, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferSubData(int buffer, long offset, float[] data) {
final ByteBuffer copy = copyOf(data);
glNamedBufferSubData(buffer, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glNamedBufferSubData(int buffer, long offset, double[] data) {
final ByteBuffer copy = copyOf(data);
glNamedBufferSubData(buffer, offset, copy);
MemoryUtilities.memFree(copy);
}
public static void glClearBufferSubData(int target, int internalFormat, long offset, long size, int format, int type, ByteBuffer data) { onBufferRespec(target); RENDER_BACKEND.clearBufferSubData(target, internalFormat, offset, size, format, type, data); }
public static void glClearBufferData(int target, int internalformat, int format, int type, ByteBuffer data) { onBufferRespec(target); RENDER_BACKEND.clearBufferData(target, internalformat, format, type, data); }
public static boolean glIsBuffer(int buffer) { rejectExitCapture(); return RENDER_BACKEND.isBuffer(buffer); }
public static void glCopyBufferSubData(int readTarget, int writeTarget, long readOffset, long writeOffset, long size) { onBufferRespec(writeTarget); RENDER_BACKEND.copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); }
private static int checkedSize(long size) {
if (size < 0 || size > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Buffer range does not fit a ByteBuffer wrapper: " + size);
}
return (int) size;
}
private static ByteBuffer copyOf(short[] data) {
final ByteBuffer bb = MemoryUtilities.memAlloc(data.length << 1);
bb.asShortBuffer().put(data);
return bb;
}
private static ByteBuffer copyOf(int[] data) {
final ByteBuffer bb = MemoryUtilities.memAlloc(data.length << 2);
bb.asIntBuffer().put(data);
return bb;
}
private static ByteBuffer copyOf(long[] data) {
final ByteBuffer bb = MemoryUtilities.memAlloc(data.length << 3);
bb.asLongBuffer().put(data);
return bb;
}
private static ByteBuffer copyOf(float[] data) {
final ByteBuffer bb = MemoryUtilities.memAlloc(data.length << 2);
bb.asFloatBuffer().put(data);
return bb;
}
private static ByteBuffer copyOf(double[] data) {
final ByteBuffer bb = MemoryUtilities.memAlloc(data.length << 3);
bb.asDoubleBuffer().put(data);
return bb;
}
public static void glBindBufferBase(int target, int index, int buffer) {
rejectExitCapture();
final boolean locked = acquireDrawLock();
try {
final GLContextState glCtx = ctx();
trackBufferBinding(glCtx, target, buffer);
trackIndexedBufferBinding(glCtx, target, index, buffer);
RENDER_BACKEND.bindBufferBase(target, index, buffer);
} finally {
if (locked) releaseDrawLock();
}
}
public static void glBindBufferRange(int target, int index, int buffer, long offset, long size) {
rejectExitCapture();
final boolean locked = acquireDrawLock();
try {
final GLContextState glCtx = ctx();
trackBufferBinding(glCtx, target, buffer);
trackIndexedBufferBinding(glCtx, target, index, buffer);
RENDER_BACKEND.bindBufferRange(target, index, buffer, offset, size);
} finally {
if (locked) releaseDrawLock();
}
}
private static int[] indexedBufferBindings(GLContextState glCtx, int target, int index) {
if (index < 0 || index >= INDEXED_BUFFER_SLOTS) return null;
if (target == GL31.GL_UNIFORM_BUFFER) return glCtx.uniformBufferBindings;
if (target == GL43.GL_SHADER_STORAGE_BUFFER) return glCtx.storageBufferBindings;
return null;
}
private static void trackIndexedBufferBinding(GLContextState glCtx, int target, int index, int buffer) {
final int[] bindings = indexedBufferBindings(glCtx, target, index);
if (bindings != null) bindings[index] = buffer;
}
public static int getIndexedBufferBinding(int target, int index) {
if (isCachingEnabled()) {
final int[] bindings = indexedBufferBindings(ctx(), target, index);
if (bindings != null) return bindings[index];
}
return RENDER_BACKEND.getIndexedBufferBinding(target, index);
}
public static long nglMapBuffer(int target, int access) {
rejectExitCapture();
final ByteBuffer buf = RENDER_BACKEND.mapBuffer(target, access);
if (buf != null) onBufferMap(target, access);
return buf == null ? 0L : MemoryUtilities.memAddress0(buf);
}
public static void glMemoryBarrier(int barriers) { rejectExitCapture(); RENDER_BACKEND.memoryBarrier(barriers); }
public static int getBoundVBO() {
return ctx().boundVBO;
}
public static int getBoundCopyReadBuffer() {
return ctx().boundCopyReadBuffer;
}
public static int getBoundCopyWriteBuffer() {
return ctx().boundCopyWriteBuffer;
}
}
@@ -0,0 +1,524 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.ffp.InstancedAttribs;
import com.gtnewhorizons.angelica.glsm.ffp.ShaderManager;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
import com.gtnewhorizons.angelica.glsm.hooks.GlintColorHandler;
import com.gtnewhorizons.angelica.glsm.hooks.ImmediateExtendedAttribHandler;
import com.gtnewhorizons.angelica.glsm.recording.ImmediateModeRecorder;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.Color4Stack;
import com.gtnewhorizons.angelica.glsm.streaming.TessellatorEntityIds;
import org.lwjgl.opengl.GL13;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isMainThread;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMCurrentAttribs {
private GLSMCurrentAttribs() {}
public static void setOverlayColor(float r, float g, float b, float a) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.OVERLAY_COLOR);
if (r == glCtx.overlayR && g == glCtx.overlayG && b == glCtx.overlayB && a == glCtx.overlayA) return;
glCtx.overlayR = r; glCtx.overlayG = g; glCtx.overlayB = b; glCtx.overlayA = a;
glCtx.fragmentGeneration++;
}
public static void setShaderColor(float r, float g, float b, float a) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.SHADER_COLOR);
if (r == glCtx.shaderColorR && g == glCtx.shaderColorG && b == glCtx.shaderColorB && a == glCtx.shaderColorA) return;
glCtx.shaderColorR = r; glCtx.shaderColorG = g; glCtx.shaderColorB = b; glCtx.shaderColorA = a;
if (GLSMHooks.SHADER_COLOR_CHANGE.hasListeners()) {
GLSMHooks.shaderColorChangeEvent.red = r;
GLSMHooks.shaderColorChangeEvent.green = g;
GLSMHooks.shaderColorChangeEvent.blue = b;
GLSMHooks.shaderColorChangeEvent.alpha = a;
GLSMHooks.SHADER_COLOR_CHANGE.post(GLSMHooks.shaderColorChangeEvent);
}
}
public static boolean consumeUnit23TexCoordSetDuringDraw(GLContextState glCtx) {
boolean v = glCtx.unit23TexCoordSetDuringDraw;
glCtx.unit23TexCoordSetDuringDraw = false;
return v;
}
public static void forceAttribDefaultsDirty() {
final GLContextState glCtx = ctx();
glCtx.dirtyNormalAttrib = true;
glCtx.dirtyTexCoordAttrib = true;
}
// has* 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(GLContextState glCtx, boolean hasColor, boolean hasNormal, boolean hasTexCoord, boolean hasLightmap) {
final ShaderManager sm = glCtx.ffp;
final boolean ffpWillHandle = sm.isActive() || (sm.isEnabled() && glCtx.activeProgram == 0);
if (!hasColor && glCtx.dirtyColorAttrib && !ffpWillHandle) {
RENDER_BACKEND.vertexAttrib4f(Usage.COLOR.getAttributeLocation(), glCtx.color.getRed(), glCtx.color.getGreen(), glCtx.color.getBlue(), glCtx.color.getAlpha());
glCtx.dirtyColorAttrib = false;
}
if (!hasNormal && glCtx.dirtyNormalAttrib && !ffpWillHandle) {
final var n = sm.currentNormal;
RENDER_BACKEND.vertexAttrib3f(Usage.NORMAL.getAttributeLocation(), n.x, n.y, n.z);
glCtx.dirtyNormalAttrib = false;
}
if (!hasTexCoord && glCtx.dirtyTexCoordAttrib && !ffpWillHandle) {
final var tc = sm.currentTexCoords[0];
RENDER_BACKEND.vertexAttrib4f(Usage.PRIMARY_UV.getAttributeLocation(), tc.x, tc.y, tc.z, tc.w);
glCtx.dirtyTexCoordAttrib = false;
}
if (!hasLightmap && glCtx.dirtyLightmapAttrib && !ffpWillHandle) {
RENDER_BACKEND.vertexAttrib4f(Usage.SECONDARY_UV.getAttributeLocation(), glCtx.lastBrightnessX, glCtx.lastBrightnessY, 0.0f, 1.0f);
glCtx.dirtyLightmapAttrib = false;
}
}
public static void setEntityIds(int entity, int blockEntity, int item) {
rejectExitCapture();
if (!isMainThread()) return;
final GLContextState glCtx = ctx();
final long ids = InstancedAttribs.packEntityInfo(entity, blockEntity, item);
if (ids == glCtx.entityIds) return;
TessellatorEntityIds.onIdsChanged(glCtx.entityIds, ids);
glCtx.entityIds = ids;
glCtx.dirtyEntityIdsAttrib = true;
}
public static void flushEntityIds(GLContextState glCtx) {
if (!glCtx.dirtyEntityIdsAttrib || glCtx.activeProgram == 0) return;
final ImmediateExtendedAttribHandler handler = GLSMHooks.immediateExtendedHandler;
if (handler == null || !handler.wantsEntityIds()) return;
final long ids = glCtx.entityIds;
RENDER_BACKEND.vertexAttrib4f(ImmediateExtendedAttribHandler.LOC_ENTITY_IDS,
InstancedAttribs.normalizedId(ids, 0), InstancedAttribs.normalizedId(ids, 16), InstancedAttribs.normalizedId(ids, 32), 0.0f);
glCtx.dirtyEntityIdsAttrib = false;
}
public static void glNormal3b(byte nx, byte ny, byte nz) {
final float fnx = b2f(nx), fny = b2f(ny), fnz = b2f(nz);
final GLContextState glCtx = ctx();
glCtx.ffp.setNormal(fnx, fny, fnz);
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setNormal(fnx, fny, fnz);
return;
}
glCtx.dirtyNormalAttrib = true;
}
public static void glNormal3d(double nx, double ny, double nz) {
final float fnx = (float) nx, fny = (float) ny, fnz = (float) nz;
final GLContextState glCtx = ctx();
glCtx.ffp.setNormal(fnx, fny, fnz);
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setNormal(fnx, fny, fnz);
return;
}
glCtx.dirtyNormalAttrib = true;
}
public static void glNormal3f(float nx, float ny, float nz) {
final GLContextState glCtx = ctx();
glCtx.ffp.setNormal(nx, ny, nz);
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setNormal(nx, ny, nz);
return;
}
glCtx.dirtyNormalAttrib = true;
}
public static void glNormal3i(int nx, int ny, int nz) {
final float fnx = nx / 2147483647.0f, fny = ny / 2147483647.0f, fnz = nz / 2147483647.0f;
final GLContextState glCtx = ctx();
glCtx.ffp.setNormal(fnx, fny, fnz);
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setNormal(fnx, fny, fnz);
return;
}
glCtx.dirtyNormalAttrib = true;
}
public static void glEdgeFlag(boolean flag) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStateCommand(() -> glEdgeFlag(flag));
if (mode == RecordMode.COMPILE) return;
}
ctx().edgeFlagState.setEnabled(flag);
}
public static void glColor4f(float red, float green, float blue, float alpha) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor(red, green, blue, alpha);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor(red, green, blue, alpha);
}
public static void glColor4d(double red, double green, double blue, double alpha) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor((float) red, (float) green, (float) blue, (float) alpha);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor((float) red, (float) green, (float) blue, (float) alpha);
}
public static void glColor4b(byte red, byte green, byte blue, byte alpha) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor(b2f(red), b2f(green), b2f(blue), b2f(alpha));
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor(b2f(red), b2f(green), b2f(blue), b2f(alpha));
}
public static void glColor4ub(byte red, byte green, byte blue, byte alpha) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor(ub2f(red), ub2f(green), ub2f(blue), ub2f(alpha));
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor(ub2f(red), ub2f(green), ub2f(blue), ub2f(alpha));
}
public static void glColor3f(float red, float green, float blue) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor(red, green, blue, 1.0F);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor(red, green, blue, 1.0F);
}
public static void glColor3d(double red, double green, double blue) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor((float) red, (float) green, (float) blue, 1.0F);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor((float) red, (float) green, (float) blue, 1.0F);
}
public static void glColor3b(byte red, byte green, byte blue) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor(b2f(red), b2f(green), b2f(blue), 1.0F);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor(b2f(red), b2f(green), b2f(blue), 1.0F);
}
public static void glColor3ub(byte red, byte green, byte blue) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordColor(ub2f(red), ub2f(green), ub2f(blue), 1.0F);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeColor(ub2f(red), ub2f(green), ub2f(blue), 1.0F);
}
private static float ub2f(byte b) {
return (b & 0xFF) / 255.0F;
}
private static float b2f(byte b) {
return ((b - Byte.MIN_VALUE) & 0xFF) / 255.0F;
}
private static boolean changeColor(float red, float green, float blue, float alpha) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.COLOR);
// Helper function for glColor*
final boolean caching = isCachingEnabled();
if (!caching || red != glCtx.color.getRed() || green != glCtx.color.getGreen() || blue != glCtx.color.getBlue() || alpha != glCtx.color.getAlpha()) {
mod(glCtx.color);
glCtx.color.setRed(red);
glCtx.color.setGreen(green);
glCtx.color.setBlue(blue);
glCtx.color.setAlpha(alpha);
glCtx.colorGeneration++;
if (ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setColor(red, green, blue, alpha);
}
glCtx.dirtyColorAttrib = true;
// Only set while an enchantment-glint span is active
final GlintColorHandler glintHandler = GLSMHooks.glintColorHandler;
if (glintHandler != null) {
glintHandler.onColorChanged(red, green, blue, alpha);
}
return true;
}
return false;
}
public static void glSecondaryColor3f(float red, float green, float blue) {
rejectExitCapture();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordSecondaryColor(red, green, blue);
if (mode == RecordMode.COMPILE) {
return;
}
}
changeSecondaryColor(red, green, blue);
}
public static void glSecondaryColor3d(double red, double green, double blue) {
glSecondaryColor3f((float) red, (float) green, (float) blue);
}
public static void glSecondaryColor3b(byte red, byte green, byte blue) {
glSecondaryColor3f(b2f(red), b2f(green), b2f(blue));
}
public static void glSecondaryColor3ub(byte red, byte green, byte blue) {
glSecondaryColor3f(ub2f(red), ub2f(green), ub2f(blue));
}
/** Helper for glSecondaryColor* - the color sum is emulated by the FFP shaders, nothing is sent to the driver. */
private static void changeSecondaryColor(float red, float green, float blue) {
final GLContextState glCtx = ctx();
if (!isCachingEnabled() || red != glCtx.secondaryColor.getRed() || green != glCtx.secondaryColor.getGreen() || blue != glCtx.secondaryColor.getBlue()) {
if (glCtx.colorSumState.isEnabled()) beforeUncapturedStateChange();
mod(glCtx.secondaryColor);
glCtx.secondaryColor.setRed(red);
glCtx.secondaryColor.setGreen(green);
glCtx.secondaryColor.setBlue(blue);
glCtx.fragmentGeneration++;
}
}
public static void glTexCoord1f(float s) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord(s, 0.0f);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord(s, 0.0f, 0.0f, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord1d(double s) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord((float) s, 0.0f);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord((float) s, 0.0f, 0.0f, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord2f(float s, float t) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord(s, t);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord(s, t, 0.0f, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord2d(double s, double t) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord((float) s, (float) t);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord((float) s, (float) t, 0.0f, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord3f(float s, float t, float r) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord(s, t); // Only track s,t for 2D textures
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord(s, t, r, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord3d(double s, double t, double r) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord((float) s, (float) t);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord((float) s, (float) t, (float) r, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord4f(float s, float t, float r, float q) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord(s, t);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord(s, t, r, q);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glTexCoord4d(double s, double t, double r, double q) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord((float) s, (float) t);
return;
}
final GLContextState glCtx = ctx();
glCtx.ffp.setTexCoord((float) s, (float) t, (float) r, (float) q);
glCtx.dirtyTexCoordAttrib = true;
}
public static void glVertexAttrib2f(int index, float v0, float v1) {
glVertexAttrib4f(index, v0, v1, 0.0f, 1.0f);
}
public static void glVertexAttrib2s(int index, short v0, short v1) {
glVertexAttrib4f(index, v0, v1, 0.0f, 1.0f);
}
public static void glVertexAttrib3f(int index, float v0, float v1, float v2) {
glVertexAttrib4f(index, v0, v1, v2, 1.0f);
}
public static void glVertexAttrib4f(int index, float v0, float v1, float v2, float v3) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordVertexAttrib(index, v0, v1, v2, v3);
if (mode == RecordMode.COMPILE) return;
}
beforeUncapturedStateChange();
RENDER_BACKEND.vertexAttrib4f(index, v0, v1, v2, v3);
}
public static void glMultiTexCoord2f(int target, float s, float t) {
final GLContextState glCtx = ctx();
if (target == GL13.GL_TEXTURE0) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setTexCoord(s, t);
return;
}
glCtx.ffp.setTexCoord(s, t, 0.0f, 1.0f);
glCtx.dirtyTexCoordAttrib = true;
} else if (target == GL13.GL_TEXTURE1) {
if (ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.setLightmapCoord(s, t);
return;
}
setLightmapTextureCoords(target, s, t);
} else {
final int unit = target - GL13.GL_TEXTURE0;
if (unit >= 2 && unit < 4) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
glCtx.unit23TexCoordSetDuringDraw = true;
}
beforeUncapturedStateChange();
glCtx.ffp.setTexCoord(unit, s, t, 0.0f, 1.0f);
} else {
glCtx.exitCapture.reject();
}
}
}
public static void glMultiTexCoord2d(int target, double s, double t) {
glMultiTexCoord2f(target, (float) s, (float) t);
}
public static void glMultiTexCoord2s(int target, short s, short t) {
glMultiTexCoord2f(target, s, t);
}
public static void setLightmapTextureCoords(int unit, float x, float y) {
if (unit != GL13.GL_TEXTURE1) {
rejectExitCapture();
return;
}
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.LIGHTMAP);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStateCommand(() -> setLightmapTextureCoords(unit, x, y));
if (mode == RecordMode.COMPILE) return;
}
glCtx.lastBrightnessX = x;
glCtx.lastBrightnessY = y;
glCtx.dirtyLightmapAttrib = true;
if (GLSMHooks.LIGHTMAP_COORDS.hasListeners()) {
GLSMHooks.lightmapCoordsEvent.x = x;
GLSMHooks.lightmapCoordsEvent.y = y;
GLSMHooks.LIGHTMAP_COORDS.post(GLSMHooks.lightmapCoordsEvent);
}
}
public static float getOverlayR() {
return ctx().overlayR;
}
public static float getOverlayG() {
return ctx().overlayG;
}
public static float getOverlayB() {
return ctx().overlayB;
}
public static float getOverlayA() {
return ctx().overlayA;
}
public static float getShaderColorR() {
return ctx().shaderColorR;
}
public static float getShaderColorG() {
return ctx().shaderColorG;
}
public static float getShaderColorB() {
return ctx().shaderColorB;
}
public static float getShaderColorA() {
return ctx().shaderColorA;
}
public static Color4Stack getColor() {
return ctx().color;
}
public static Color4Stack getSecondaryColor() {
return ctx().secondaryColor;
}
public static BooleanStateStack getColorSumState() {
return ctx().colorSumState;
}
}
@@ -0,0 +1,427 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredAlphaHandler;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredDepthColorHandler;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
import com.gtnewhorizons.angelica.glsm.stacks.AlphaStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.DepthStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.StencilStateStack;
import com.gtnewhorizons.angelica.glsm.states.AlphaState;
import org.lwjgl.opengl.GL11;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMDepthStencilAlpha {
private GLSMDepthStencilAlpha() {}
public static boolean isEffectiveDepthMaskEnabled() {
return ctx().depthState.isEffectiveMaskEnabled();
}
public static boolean isEffectiveAlphaTestEnabled() {
return ctx().alphaTest.isEffectivelyEnabled();
}
public static AlphaState getEffectiveAlphaState(AlphaState out) {
return ctx().alphaState.readEffective(out);
}
public static void glDepthFunc(int func) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.DEPTH_FUNC);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDepthFunc(func);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || func != glCtx.depthState.getFunc()) {
mod(glCtx.depthState);
glCtx.depthState.setFunc(func);
RENDER_BACKEND.depthFunc(func);
}
}
public static void glDepthMask(boolean mask) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.writeDepthColor(ExitStateCapture.DEPTH_MASK);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDepthMask(mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
final DeferredDepthColorHandler dch = GLSMHooks.depthColorHandler;
if (dch != null && dch.isDepthColorLocked()) {
mod(glCtx.depthState);
dch.deferDepthEnable(mask);
return;
}
final boolean caching = isCachingEnabled();
if (!caching || mask != glCtx.depthState.isEnabled()) {
mod(glCtx.depthState);
glCtx.depthState.setEnabled(mask);
RENDER_BACKEND.depthMask(mask);
}
}
public static void glClearDepth(double depth) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordClearDepth(depth);
if (mode == RecordMode.COMPILE) {
return;
}
}
depth = Math.min(1.0, Math.max(0.0, depth));
mod(glCtx.depthState);
if (isCachingEnabled()) glCtx.depthState.setClearValue(depth);
RENDER_BACKEND.clearDepth(depth);
}
public static void enableAlphaTest() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_ALPHA_TEST);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableAlphaTest(ctx());
}
static void enableAlphaTest(GLContextState glCtx) {
final DeferredAlphaHandler ah = GLSMHooks.alphaHandler;
if (ah != null && ah.isAlphaTestLocked()) {
glCtx.exitCapture.capability(GL11.GL_ALPHA_TEST, -1);
glCtx.alphaTest.beforeModify();
if (ah.deferAlphaTestToggle(true) && GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
return;
}
final boolean wasEnabled = glCtx.alphaTest.isEnabled();
glCtx.alphaTest.enable();
if (glCtx.alphaTest.isEnabled() != wasEnabled) {
glCtx.fragmentGeneration++;
if (GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
}
}
public static void disableAlphaTest() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_ALPHA_TEST);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableAlphaTest(ctx());
}
static void disableAlphaTest(GLContextState glCtx) {
final DeferredAlphaHandler ah = GLSMHooks.alphaHandler;
if (ah != null && ah.isAlphaTestLocked()) {
glCtx.exitCapture.capability(GL11.GL_ALPHA_TEST, -1);
glCtx.alphaTest.beforeModify();
if (ah.deferAlphaTestToggle(false) && GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
return;
}
final boolean wasEnabled = glCtx.alphaTest.isEnabled();
glCtx.alphaTest.disable();
if (glCtx.alphaTest.isEnabled() != wasEnabled) {
glCtx.fragmentGeneration++;
if (GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
}
}
public static void glAlphaFunc(int function, float reference) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.writeAlpha();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordAlphaFunc(function, reference);
if (mode == RecordMode.COMPILE) {
return;
}
}
final DeferredAlphaHandler ah = GLSMHooks.alphaHandler;
if (ah != null && ah.isAlphaTestLocked()) {
mod(glCtx.alphaState);
if (ah.deferAlphaFunc(function, reference) && GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
return;
}
if (isCachingEnabled()
&& (function != glCtx.alphaState.getFunction() || Float.compare(reference, glCtx.alphaState.getReference()) != 0)) {
mod(glCtx.alphaState);
glCtx.alphaState.setFunction(function);
glCtx.alphaState.setReference(reference);
glCtx.fragmentGeneration++;
if (GLSMHooks.ALPHA_STATE_CHANGE.hasListeners()) {
GLSMHooks.ALPHA_STATE_CHANGE.post(GLSMHooks.alphaStateChangeEvent);
}
}
}
public static void enableDepthTest() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_DEPTH_TEST);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableDepthTest(ctx());
}
static void enableDepthTest(GLContextState glCtx) {
glCtx.depthTest.enable();
}
public static void disableDepthTest() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_DEPTH_TEST);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableDepthTest(ctx());
}
static void disableDepthTest(GLContextState glCtx) {
glCtx.depthTest.disable();
}
public static void glDepthRange(double near, double far) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (!isCachingEnabled() || glCtx.viewportState.depthRangeNear != near || glCtx.viewportState.depthRangeFar != far) beforeUncapturedStateChange();
if (isCachingEnabled()) mod(glCtx.viewportState).setDepthRange(near, far);
RENDER_BACKEND.depthRange(near, far);
}
public static void glStencilFunc(int func, int ref, int mask) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStencilFunc(func, ref, mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
final int clampedMask = mask & glCtx.stencilBitMask;
final boolean caching = isCachingEnabled();
if (!caching || glCtx.stencilState.getFuncFront() != func || glCtx.stencilState.getRefFront() != ref || glCtx.stencilState.getValueMaskFront() != clampedMask) {
beforeUncapturedStateChange();
mod(glCtx.stencilState).setFunc(func, ref, clampedMask);
RENDER_BACKEND.stencilFunc(func, ref, clampedMask);
}
}
public static void glStencilMask(int mask) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStencilMask(mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
final int clampedMask = mask & glCtx.stencilBitMask;
final boolean caching = isCachingEnabled();
if (!caching || glCtx.stencilState.getWriteMaskFront() != clampedMask) {
beforeUncapturedStateChange();
mod(glCtx.stencilState).setWriteMask(clampedMask);
RENDER_BACKEND.stencilMask(clampedMask);
}
}
public static void glStencilOp(int fail, int zfail, int zpass) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStencilOp(fail, zfail, zpass);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.stencilState.getFailOpFront() != fail || glCtx.stencilState.getZFailOpFront() != zfail || glCtx.stencilState.getZPassOpFront() != zpass) {
beforeUncapturedStateChange();
mod(glCtx.stencilState).setOp(fail, zfail, zpass);
RENDER_BACKEND.stencilOp(fail, zfail, zpass);
}
}
public static void glClearStencil(int s) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordClearStencil(s);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.stencilState.getClearValue() != s) {
mod(glCtx.stencilState).setClearValue(s);
RENDER_BACKEND.clearStencil(s);
}
}
public static void glStencilFuncSeparate(int face, int func, int ref, int mask) {
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStencilFuncSeparate(face, func, ref, mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
final int clampedMask = mask & glCtx.stencilBitMask;
final boolean caching = isCachingEnabled();
boolean needsUpdate = !caching;
if (!needsUpdate) {
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
needsUpdate = glCtx.stencilState.getFuncFront() != func || glCtx.stencilState.getRefFront() != ref || glCtx.stencilState.getValueMaskFront() != clampedMask;
}
if (!needsUpdate && (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK)) {
needsUpdate = glCtx.stencilState.getFuncBack() != func || glCtx.stencilState.getRefBack() != ref || glCtx.stencilState.getValueMaskBack() != clampedMask;
}
}
if (needsUpdate) {
mod(glCtx.stencilState);
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
glCtx.stencilState.setFuncFront(func);
glCtx.stencilState.setRefFront(ref);
glCtx.stencilState.setValueMaskFront(clampedMask);
}
if (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK) {
glCtx.stencilState.setFuncBack(func);
glCtx.stencilState.setRefBack(ref);
glCtx.stencilState.setValueMaskBack(clampedMask);
}
RENDER_BACKEND.stencilFuncSeparate(face, func, ref, clampedMask);
}
}
public static void glStencilMaskSeparate(int face, int mask) {
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStencilMaskSeparate(face, mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
final int clampedMask = mask & glCtx.stencilBitMask;
final boolean caching = isCachingEnabled();
boolean needsUpdate = !caching;
if (!needsUpdate) {
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
needsUpdate = glCtx.stencilState.getWriteMaskFront() != clampedMask;
}
if (!needsUpdate && (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK)) {
needsUpdate = glCtx.stencilState.getWriteMaskBack() != clampedMask;
}
}
if (needsUpdate) {
mod(glCtx.stencilState);
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
glCtx.stencilState.setWriteMaskFront(clampedMask);
}
if (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK) {
glCtx.stencilState.setWriteMaskBack(clampedMask);
}
RENDER_BACKEND.stencilMaskSeparate(face, clampedMask);
}
}
public static void glStencilOpSeparate(int face, int sfail, int dpfail, int dppass) {
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordStencilOpSeparate(face, sfail, dpfail, dppass);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
final boolean caching = isCachingEnabled();
boolean needsUpdate = !caching;
if (!needsUpdate) {
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
needsUpdate = glCtx.stencilState.getFailOpFront() != sfail || glCtx.stencilState.getZFailOpFront() != dpfail || glCtx.stencilState.getZPassOpFront() != dppass;
}
if (!needsUpdate && (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK)) {
needsUpdate = glCtx.stencilState.getFailOpBack() != sfail || glCtx.stencilState.getZFailOpBack() != dpfail || glCtx.stencilState.getZPassOpBack() != dppass;
}
}
if (needsUpdate) {
mod(glCtx.stencilState);
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
glCtx.stencilState.setFailOpFront(sfail);
glCtx.stencilState.setZFailOpFront(dpfail);
glCtx.stencilState.setZPassOpFront(dppass);
}
if (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK) {
glCtx.stencilState.setFailOpBack(sfail);
glCtx.stencilState.setZFailOpBack(dpfail);
glCtx.stencilState.setZPassOpBack(dppass);
}
RENDER_BACKEND.stencilOpSeparate(face, sfail, dpfail, dppass);
}
}
public static DepthStateStack getDepthState() {
return ctx().depthState;
}
public static BooleanStateStack getDepthTest() {
return ctx().depthTest;
}
public static AlphaStateStack getAlphaState() {
return ctx().alphaState;
}
public static BooleanStateStack getAlphaTest() {
return ctx().alphaTest;
}
public static BooleanStateStack getStencilTest() {
return ctx().stencilTest;
}
public static StencilStateStack getStencilState() {
return ctx().stencilState;
}
}
@@ -0,0 +1,713 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizon.gtnhlib.client.renderer.DirectTessellator;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.backend.GLDebugMessageListener;
import com.gtnewhorizons.angelica.glsm.ffp.FfpExtendedAttribs;
import com.gtnewhorizons.angelica.glsm.ffp.VAOManager;
import com.gtnewhorizons.angelica.glsm.recording.CommandRecorder;
import com.gtnewhorizons.angelica.glsm.recording.CompiledDisplayList;
import com.gtnewhorizons.angelica.glsm.recording.ImmediateModeRecorder;
import com.gtnewhorizons.angelica.glsm.recording.commands.IndexedDrawCapture;
import com.gtnewhorizons.angelica.glsm.streaming.LineQuads;
import com.gtnewhorizons.angelica.glsm.streaming.TessellatorStreamingDrawer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.KHRDebugCallback;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.LOGGER;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.acquireDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.guardUnsupportedFFP;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.initConfig;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.releaseDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.warnOnce;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMDraws {
private GLSMDraws() {}
public static long drawCalls;
/**
* Check if a display list exists (has been compiled and stored). Delegates to DisplayListManager.
*
* @param list The display list ID to check
* @return true if the display list exists, false otherwise
*/
public static boolean displayListExists(int list) {
return DisplayListManager.displayListExists(list);
}
private static final String PIXELTRANSFER_MSG = "glPixelTransfer is not available in GL 3.3 core profile.";
public static void glPixelTransferf(int pname, float param) {
guardUnsupportedFFP("glPixelTransfer", PIXELTRANSFER_MSG);
}
public static void glPixelTransferi(int pname, int param) {
guardUnsupportedFFP("glPixelTransfer", PIXELTRANSFER_MSG);
}
private static final String RASTERPOS_MSG = "glRasterPos is not available in GL 3.3 core profile.";
public static void glRasterPos2f(float x, float y) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos2d(double x, double y) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos2i(int x, int y) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos3f(float x, float y, float z) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos3d(double x, double y, double z) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos3i(int x, int y, int z) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos4f(float x, float y, float z, float w) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos4d(double x, double y, double z, double w) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glRasterPos4i(int x, int y, int z, int w) { guardUnsupportedFFP("glRasterPos", RASTERPOS_MSG); }
public static void glBegin(int mode) {
rejectExitCapture();
ctx().unit23TexCoordSetDuringDraw = false;
if (DisplayListManager.isRecording()) {
ImmediateModeRecorder.begin(mode);
return;
}
ImmediateModeRecorder.beginLive(mode);
}
public static void glEnd() {
rejectExitCapture();
final DirectTessellator result = ImmediateModeRecorder.end();
if (result != null) {
if (DisplayListManager.isRecording()) {
if (DisplayListManager.isCompileAndExecute() && initConfig != null && initConfig.getDirectDrawer() != null) {
final CommandRecorder recorder = DisplayListManager.pauseRecording();
initConfig.getDirectDrawer().accept(result);
DisplayListManager.resumeRecording(recorder);
}
DisplayListManager.addImmediateModeDraw(result);
return;
}
if (initConfig != null && initConfig.getDirectDrawer() != null) {
initConfig.getDirectDrawer().accept(result);
}
}
}
public static void glVertex2f(float x, float y) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.vertex(x, y, 0.0f);
}
}
public static void glVertex2i(int x, int y) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.vertex((float) x, (float) y, 0.0f);
}
}
public static void glVertex2d(double x, double y) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.vertex((float) x, (float) y, 0.0f);
}
}
public static void glVertex3f(float x, float y, float z) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.vertex(x, y, z);
}
}
public static void glVertex3d(double x, double y, double z) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.vertex((float) x, (float) y, (float) z);
}
}
public static void glVertex3i(int x, int y, int z) {
if (DisplayListManager.isRecording() || ImmediateModeRecorder.isDrawing()) {
ImmediateModeRecorder.vertex((float) x, (float) y, (float) z);
}
}
public static void preDraw(GLContextState glCtx, int drawMode) {
prepareLineEmulation(glCtx, drawMode);
glCtx.ffp.preDraw(glCtx);
GLSMVertexInput.prepareClientArrays(glCtx);
}
public static void glDrawElements(int mode, ByteBuffer indices) {
rejectExitCapture();
drawCalls++;
CommandRecorder savedRecorder = null;
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
final IndexedDrawCapture capture = IndexedDrawCapture.createFromClientIndices(mode, indices.remaining(), GL11.GL_UNSIGNED_BYTE, MemoryUtilities.memAddress(indices), indices.remaining());
if (capture != null) DisplayListManager.recordIndexedDrawCapture(capture);
if (recordMode == RecordMode.COMPILE) return;
savedRecorder = DisplayListManager.pauseRecording();
} else if (FeedbackManager.isFeedbackMode()) {
FeedbackManager.processDrawElements(mode, indices);
return;
}
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTriangles(glCtx, indices.remaining(), GL11.GL_UNSIGNED_BYTE, indices);
return;
}
if (widensLineDraw(mode, indices.remaining())) {
drawLinesAsQuads(glCtx, ImmediateModeRecorder.processDrawElementsFromAttribs(mode, indices.remaining(), GL11.GL_UNSIGNED_BYTE, MemoryUtilities.memAddress(indices)));
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.drawElements(mode, indices);
} finally {
if (locked) releaseDrawLock();
if (savedRecorder != null) DisplayListManager.resumeRecording(savedRecorder);
}
}
public static void glDrawElements(int mode, IntBuffer indices) {
rejectExitCapture();
drawCalls++;
CommandRecorder savedRecorder = null;
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
final IndexedDrawCapture capture = IndexedDrawCapture.createFromClientIndices(mode, indices.remaining(), GL11.GL_UNSIGNED_INT, MemoryUtilities.memAddress(indices), (long) indices.remaining() << 2);
if (capture != null) DisplayListManager.recordIndexedDrawCapture(capture);
if (recordMode == RecordMode.COMPILE) return;
savedRecorder = DisplayListManager.pauseRecording();
} else if (FeedbackManager.isFeedbackMode()) {
FeedbackManager.processDrawElements(mode, indices);
return;
}
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTriangles(glCtx, indices);
return;
}
if (widensLineDraw(mode, indices.remaining())) {
drawLinesAsQuads(glCtx, ImmediateModeRecorder.processDrawElementsFromAttribs(mode, indices.remaining(), GL11.GL_UNSIGNED_INT, MemoryUtilities.memAddress(indices)));
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.drawElements(mode, indices);
} finally {
if (locked) releaseDrawLock();
if (savedRecorder != null) DisplayListManager.resumeRecording(savedRecorder);
}
}
public static void glDrawElements(int mode, ShortBuffer indices) {
rejectExitCapture();
drawCalls++;
CommandRecorder savedRecorder = null;
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
final IndexedDrawCapture capture = IndexedDrawCapture.createFromClientIndices(mode, indices.remaining(), GL11.GL_UNSIGNED_SHORT, MemoryUtilities.memAddress(indices), (long) indices.remaining() << 1);
if (capture != null) DisplayListManager.recordIndexedDrawCapture(capture);
if (recordMode == RecordMode.COMPILE) return;
savedRecorder = DisplayListManager.pauseRecording();
} else if (FeedbackManager.isFeedbackMode()) {
FeedbackManager.processDrawElements(mode, indices);
return;
}
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTriangles(glCtx, indices);
return;
}
if (widensLineDraw(mode, indices.remaining())) {
drawLinesAsQuads(glCtx, ImmediateModeRecorder.processDrawElementsFromAttribs(mode, indices.remaining(), GL11.GL_UNSIGNED_SHORT, MemoryUtilities.memAddress(indices)));
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.drawElements(mode, indices);
} finally {
if (locked) releaseDrawLock();
if (savedRecorder != null) DisplayListManager.resumeRecording(savedRecorder);
}
}
public static void glDrawElements(int mode, int count, int type, ByteBuffer indices) {
rejectExitCapture();
drawCalls++;
CommandRecorder savedRecorder = null;
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
final IndexedDrawCapture capture = IndexedDrawCapture.createFromClientIndices(mode, count, type, MemoryUtilities.memAddress(indices), indices.remaining());
if (capture != null) DisplayListManager.recordIndexedDrawCapture(capture);
if (recordMode == RecordMode.COMPILE) return;
savedRecorder = DisplayListManager.pauseRecording();
} else if (FeedbackManager.isFeedbackMode()) {
FeedbackManager.processDrawElements(mode, count, type, indices);
return;
}
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTriangles(glCtx, count, type, indices);
return;
}
if (widensLineDraw(mode, count)) {
drawLinesAsQuads(glCtx, ImmediateModeRecorder.processDrawElementsFromAttribs(mode, count, type, MemoryUtilities.memAddress(indices)));
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.drawElements(mode, count, type, indices);
} finally {
if (locked) releaseDrawLock();
if (savedRecorder != null) DisplayListManager.resumeRecording(savedRecorder);
}
}
public static void glDrawElements(int mode, int indices_count, int type, long indices_buffer_offset) {
rejectExitCapture();
final GLContextState glCtx = ctx();
drawCalls++;
CommandRecorder savedRecorder = null;
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
// Core profile: a default VAO is generated at init and glBindVertexArray(0)
// is redirected to it, so a VAO is always bound here -- no fallback branches.
final IndexedDrawCapture capture = IndexedDrawCapture.create(mode, indices_count, type, indices_buffer_offset, glCtx.vaos.boundEBO);
if (capture != null) {
DisplayListManager.recordIndexedDrawCapture(capture);
}
if (recordMode == RecordMode.COMPILE) {
return;
}
savedRecorder = DisplayListManager.pauseRecording();
} else if (FeedbackManager.isFeedbackMode()) {
FeedbackManager.processDrawElements(mode, indices_count, type, indices_buffer_offset);
return;
}
final boolean locked = acquireDrawLock();
try {
if (widensLineDraw(mode, indices_count)) {
drawLinesAsQuads(glCtx, lineElementsFromBuffer(glCtx, mode, indices_count, type, indices_buffer_offset));
return;
}
final boolean ffpExt = FfpExtendedAttribs.maybeBindIndexed(glCtx, mode, indices_count, type, indices_buffer_offset);
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTriangles(glCtx, indices_count, type, indices_buffer_offset);
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.drawElements(mode, indices_count, type, indices_buffer_offset);
} finally {
if (ffpExt) FfpExtendedAttribs.unbind();
}
} finally {
if (locked) releaseDrawLock();
if (savedRecorder != null) DisplayListManager.resumeRecording(savedRecorder);
}
}
public static void glMultiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride) {
rejectExitCapture();
drawCalls += drawcount;
RENDER_BACKEND.multiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
}
public static void glMultiDrawElementsBaseVertex(int mode, long pCount, int type, long pIndices, int drawcount, long pBaseVertex) {
rejectExitCapture();
drawCalls += drawcount;
RENDER_BACKEND.multiDrawElementsBaseVertex(mode, pCount, type, pIndices, drawcount, pBaseVertex);
}
public static void glDrawElementsBaseVertex(int mode, int count, int type, long indices, int basevertex) {
rejectExitCapture();
drawCalls++;
RENDER_BACKEND.drawElementsBaseVertex(mode, count, type, indices, basevertex);
}
public static void glDrawElementsInstanced(int mode, int count, int type, long indices, int primcount) {
rejectExitCapture();
drawCalls++;
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadElementsAsTrianglesInstanced(glCtx, count, type, indices, primcount);
return;
}
warnIfInstancedWideLines(mode);
preDraw(glCtx, mode);
RENDER_BACKEND.drawElementsInstanced(mode, count, type, indices, primcount);
} finally {
if (locked) releaseDrawLock();
}
}
public static void glDrawArraysInstanced(int mode, int first, int count, int primcount) {
rejectExitCapture();
drawCalls++;
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadsAsTrianglesInstanced(glCtx, first, count, primcount);
} else if (mode == GL11.GL_QUAD_STRIP) {
preDraw(glCtx, GL11.GL_TRIANGLES);
RENDER_BACKEND.drawArraysInstanced(GL11.GL_TRIANGLE_STRIP, first, count & ~1, primcount);
} else if (mode == GL11.GL_POLYGON) {
preDraw(glCtx, GL11.GL_TRIANGLES);
RENDER_BACKEND.drawArraysInstanced(GL11.GL_TRIANGLE_FAN, first, count, primcount);
} else {
warnIfInstancedWideLines(mode);
preDraw(glCtx, mode);
RENDER_BACKEND.drawArraysInstanced(mode, first, count, primcount);
}
} finally {
if (locked) releaseDrawLock();
}
}
public static void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (widensLineDraw(mode, count)) {
drawLinesAsQuads(glCtx, lineElementsFromBuffer(glCtx, mode, count, type, indices));
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.drawRangeElements(mode, start, end, count, type, indices);
} finally {
if (locked) releaseDrawLock();
}
}
public static void glDrawRangeElementsBaseVertex(int mode, int start, int end, int count, int type, long indices, int baseVertex) {
rejectExitCapture();
RENDER_BACKEND.drawRangeElementsBaseVertex(mode, start, end, count, type, indices, baseVertex);
}
public static void glMultiDrawArrays(int mode, IntBuffer firsts, IntBuffer counts) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (LineQuads.isLineMode(mode) && ffpWidensLineQuads()) {
for (int i = firsts.position(); i < firsts.limit(); i++) {
final int count = counts.get(counts.position() + i - firsts.position());
if (LineQuads.segmentCount(mode, count) == 0) continue;
drawLinesAsQuads(glCtx, ImmediateModeRecorder.processDrawArraysFromAttribs(mode, firsts.get(i), count));
}
return;
}
preDraw(glCtx, mode);
RENDER_BACKEND.multiDrawArrays(mode, firsts, counts);
} finally {
if (locked) releaseDrawLock();
}
}
public static void glPrimitiveRestartIndex(int index) {
rejectExitCapture();
RENDER_BACKEND.primitiveRestartIndex(index);
}
public static void glDrawArrays(int mode, int first, int count) {
rejectExitCapture();
drawCalls++;
CommandRecorder savedRecorder = null;
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
final DirectTessellator result = ImmediateModeRecorder.processDrawArraysFromAttribs(mode, first, count);
if (result != null) {
DisplayListManager.addImmediateModeDraw(result);
}
if (recordMode == RecordMode.COMPILE) {
return;
}
DisplayListManager.flushAll();
savedRecorder = DisplayListManager.pauseRecording();
} else if (FeedbackManager.isFeedbackMode()) {
FeedbackManager.processDrawArrays(mode, first, count);
return;
}
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
if (widensLineDraw(mode, count)) {
drawLinesAsQuads(glCtx, ImmediateModeRecorder.processDrawArraysFromAttribs(mode, first, count));
return;
}
final boolean ffpExt = FfpExtendedAttribs.maybeBind(glCtx, mode, first, count);
try {
if (mode == GL11.GL_QUADS) {
QuadConverter.drawQuadsAsTriangles(glCtx, first, count);
} else if (mode == GL11.GL_QUAD_STRIP) {
preDraw(glCtx, GL11.GL_TRIANGLES);
RENDER_BACKEND.drawArrays(GL11.GL_TRIANGLE_STRIP, first, count & ~1);
} else if (mode == GL11.GL_POLYGON) {
preDraw(glCtx, GL11.GL_TRIANGLES);
RENDER_BACKEND.drawArrays(GL11.GL_TRIANGLE_FAN, first, count);
} else {
preDraw(glCtx, mode);
RENDER_BACKEND.drawArrays(mode, first, count);
}
} finally {
if (ffpExt) FfpExtendedAttribs.unbind();
}
} finally {
if (locked) releaseDrawLock();
if (savedRecorder != null) DisplayListManager.resumeRecording(savedRecorder);
}
}
public static void glNewList(int list, int mode) {
rejectExitCapture();
DisplayListManager.glNewList(list, mode);
}
public static void glEndList() {
rejectExitCapture();
DisplayListManager.glEndList();
}
private static final DisplayListIDAllocator displayListIdAllocator = new DisplayListIDAllocator();
public static int glGenLists(int range) {
rejectExitCapture();
return displayListIdAllocator.allocRange(range);
}
public static boolean glIsList(int list) {
rejectExitCapture();
return displayListIdAllocator.isAllocated(list);
}
/**
* Delete display lists and free their VBO resources.
*/
public static void glDeleteLists(int list, int range) {
rejectExitCapture();
final boolean locked = acquireDrawLock();
try {
synchronized (displayListIdAllocator) {
DisplayListManager.glDeleteLists(list, range);
displayListIdAllocator.freeRange(list, range);
}
} finally {
if (locked) releaseDrawLock();
}
}
/**
* Get a compiled display list from the cache. Used for executing nested display lists.
*
* @param list The display list ID
* @return The CompiledDisplayList, or null if not found
*/
public static CompiledDisplayList getDisplayList(int list) {
return DisplayListManager.getDisplayList(list);
}
public static void glCallList(int list) {
rejectExitCapture();
if (!GLDebug.isActive()) {
DisplayListManager.glCallList(list);
return;
}
GLDebug.pushGroup("glCallList ", list);
try {
DisplayListManager.glCallList(list);
} finally {
GLDebug.popGroup();
}
}
public static int getListMode() {
return DisplayListManager.getListMode();
}
public static boolean ffpWidensLineQuads() {
final GLContextState glCtx = ctx();
return GLSMRasterizer.wideLineEmulationEnabled && glCtx.activeProgram == 0 && glCtx.lineState.getWidth() > 1.0f
&& !DisplayListManager.isRecording();
}
private static boolean widensLineDraw(int mode, int count) {
return LineQuads.isLineMode(mode) && LineQuads.segmentCount(mode, count) > 0 && ffpWidensLineQuads();
}
private static void drawLinesAsQuads(GLContextState glCtx, DirectTessellator lines) {
if (lines == null) return;
if (readsBufferObject(glCtx.vaos)) {
warnOnce("line-readback", "Wide GL_LINES drawn from a buffer object; widening them reads the buffer back, which waits for the GPU");
}
final int vao = glCtx.boundVAO;
final int vbo = glCtx.boundVBO;
TessellatorStreamingDrawer.drawDirect(lines);
GLSMVertexInput.glBindVertexArray(vao);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
}
private static DirectTessellator lineElementsFromBuffer(GLContextState glCtx, int mode, int count, int type, long offset) {
if (glCtx.vaos.boundEBO == 0) return null;
final ByteBuffer indices = MemoryUtilities.memAlloc(count * GLTypes.sizeBytes(type));
try {
GLSMBuffers.glGetBufferSubData(GL15.GL_ELEMENT_ARRAY_BUFFER, offset, indices);
return ImmediateModeRecorder.processDrawElementsFromAttribs(mode, count, type, MemoryUtilities.memAddress0(indices));
} finally {
MemoryUtilities.memFree(indices);
}
}
private static void warnIfInstancedWideLines(int mode) {
if (LineQuads.isLineMode(mode) && ffpWidensLineQuads()) {
warnOnce("instanced-wide-lines", "Instanced wide GL_LINES are not widened and draw 1 px wide");
}
}
private static boolean readsBufferObject(VAOManager vaos) {
for (int i = 0; i < VAOManager.MAX_ATTRIBS; i++) {
final VAOManager.Attrib attrib = vaos.attrib(i);
if (attrib != null && attrib.enabled && attrib.vboId != 0) return true;
}
return false;
}
private static void prepareLineEmulation(GLContextState glCtx, int drawMode) {
setLineStippleActive(glCtx, (LineQuads.isLineMode(drawMode) || glCtx.lineQuadsActive) && glCtx.lineStippleState.isEnabled());
}
private static void setLineStippleActive(GLContextState glCtx, boolean active) {
if (glCtx.lineStippleActive == active) return;
glCtx.lineStippleActive = active;
RENDER_BACKEND.provokingVertex(active ? GL32.GL_FIRST_VERTEX_CONVENTION : GL32.GL_LAST_VERTEX_CONVENTION);
}
public static void glFlush() {
rejectExitCapture();
RENDER_BACKEND.flush();
}
public static void glFinish() {
rejectExitCapture();
RENDER_BACKEND.finish();
}
public static void glMultiDrawArraysIndirectCount(int mode, long indirect, long drawcount, int maxdrawcount, int stride) {
rejectExitCapture();
RENDER_BACKEND.multiDrawArraysIndirectCount(mode, indirect, drawcount, maxdrawcount, stride);
}
public static void glMultiDrawElementsIndirectCount(int mode, int type, long indirect, long drawcount, int maxdrawcount, int stride) {
rejectExitCapture();
RENDER_BACKEND.multiDrawElementsIndirectCount(mode, type, indirect, drawcount, maxdrawcount, stride);
}
public static void glCallLists(IntBuffer lists) {
while (lists.hasRemaining()) {
final int listId = lists.get() + ctx().listBase;
glCallList(listId);
}
}
public static void glCallLists(ShortBuffer lists) {
while (lists.hasRemaining()) {
final int listId = (lists.get() & 0xFFFF) + ctx().listBase;
glCallList(listId);
}
}
public static void glCallLists(ByteBuffer lists) {
while (lists.hasRemaining()) {
final int listId = (lists.get() & 0xFF) + ctx().listBase;
glCallList(listId);
}
}
public static void glListBase(int base) {
rejectExitCapture();
ctx().listBase = base;
}
public static void nglMultiDrawElementsBaseVertex(int mode, long count, int type, long indices, int primcount, long basevertex) {
rejectExitCapture();
RENDER_BACKEND.multiDrawElementsBaseVertex(mode, count, type, indices, primcount, basevertex);
}
public static void glObjectLabel(int identifier, int name, CharSequence label) { RENDER_BACKEND.objectLabel(identifier, name, label); }
public static String glGetObjectLabel(int identifier, int name, int bufSize) { rejectExitCapture(); return RENDER_BACKEND.getObjectLabel(identifier, name); }
public static void glPushDebugGroup(int source, int id, CharSequence message) { RENDER_BACKEND.pushDebugGroup(source, id, message); }
public static void glPopDebugGroup() { RENDER_BACKEND.popDebugGroup(); }
public static void glDebugMessageInsert(int source, int type, int id, int severity, CharSequence buf) { RENDER_BACKEND.debugMessageInsert(source, type, id, severity, buf); }
public static void glDebugMessageControl(int source, int type, int severity, IntBuffer ids, boolean enabled) { RENDER_BACKEND.debugMessageControl(source, type, severity, ids, enabled); }
public static int glGetDebugMessageLog(int count, IntBuffer sources, IntBuffer types, IntBuffer ids, IntBuffer severities, IntBuffer lengths, ByteBuffer messageLog) {
rejectExitCapture();
return RENDER_BACKEND.getDebugMessageLog(count, sources, types, ids, severities, lengths, messageLog);
}
public static void registerDebugMessageListener(GLDebugMessageListener listener, long userParam) {
RENDER_BACKEND.debugMessageCallback(listener, userParam);
}
public static void glDebugMessageCallback(KHRDebugCallback callback) {
RENDER_BACKEND.debugMessageCallback(GLDebug.adaptDebugCallback(callback), 0L);
}
public static void glAccum(int op, float value) {
guardUnsupportedFFP("glAccum", "The accumulation buffer is not available in GL 3.3 core profile.");
}
public static void glFeedbackBuffer(int type, FloatBuffer buffer) {
rejectExitCapture();
FeedbackManager.glFeedbackBuffer(type, buffer);
}
public static int glRenderMode(int mode) {
rejectExitCapture();
return FeedbackManager.glRenderMode(mode);
}
public static void glPassThrough(float token) {
rejectExitCapture();
FeedbackManager.glPassThrough(token);
}
private static boolean selectWarned = false;
public static void glSelectBuffer(IntBuffer buffer) {
rejectExitCapture();
if (!selectWarned) {
LOGGER.warn("glSelectBuffer: selection mode not emulated");
selectWarned = true;
}
}
public static void glInitNames() { /* no-op: ignored outside GL_SELECT */ }
public static void glPushName(int name) { /* no-op */ }
public static void glPopName() { /* no-op */ }
public static void glLoadName(int name) { /* no-op */ }
/**
* Draw modes that rely on the previous vertex data cannot be merged currently.
* It is possible to merge them using Index Buffers, but currently unimplemented.
*/
public static boolean isContinuousDraw(int drawMode) {
return drawMode == GL11.GL_TRIANGLE_STRIP || drawMode == GL11.GL_TRIANGLE_FAN
|| drawMode == GL11.GL_LINE_STRIP || drawMode == GL11.GL_LINE_LOOP
|| drawMode == GL11.GL_QUAD_STRIP || drawMode == GL11.GL_POLYGON;
}
}
@@ -0,0 +1,302 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_CLIP_PLANES;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMEnable {
private GLSMEnable() {}
public static void glEnable(int cap) {
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(cap);
if (mode == RecordMode.COMPILE) {
return;
}
}
// Handle clip planes dynamically (supports up to MAX_CLIP_PLANES)
if (cap >= GL11.GL_CLIP_PLANE0 && cap < GL11.GL_CLIP_PLANE0 + MAX_CLIP_PLANES) {
glCtx.clipPlaneStates[cap - GL11.GL_CLIP_PLANE0].enable();
glCtx.clipPlaneGeneration++;
return;
}
switch (cap) {
case GL11.GL_ALPHA_TEST -> GLSMDepthStencilAlpha.enableAlphaTest(glCtx);
case GL11.GL_AUTO_NORMAL -> glCtx.autoNormalState.enable();
case GL11.GL_BLEND -> GLSMBlend.enableBlend(glCtx);
case GL11.GL_COLOR_MATERIAL -> GLSMLighting.enableColorMaterial(glCtx);
case GL11.GL_COLOR_LOGIC_OP -> glCtx.colorLogicOpState.enable();
case GL14.GL_COLOR_SUM -> glCtx.colorSumState.enable();
case GL11.GL_CULL_FACE -> GLSMRasterizer.enableCull(glCtx);
case GL11.GL_DEPTH_TEST -> GLSMDepthStencilAlpha.enableDepthTest(glCtx);
case GL11.GL_DITHER -> glCtx.ditherState.enable();
case GL11.GL_FOG -> GLSMFog.enableFog(glCtx);
case GL11.GL_INDEX_LOGIC_OP -> glCtx.indexLogicOpState.enable();
case GL11.GL_LIGHTING -> GLSMLighting.enableLighting(glCtx);
case GL11.GL_LIGHT0 -> GLSMLighting.enableLight(glCtx, 0);
case GL11.GL_LIGHT1 -> GLSMLighting.enableLight(glCtx, 1);
case GL11.GL_LIGHT2 -> GLSMLighting.enableLight(glCtx, 2);
case GL11.GL_LIGHT3 -> GLSMLighting.enableLight(glCtx, 3);
case GL11.GL_LIGHT4 -> GLSMLighting.enableLight(glCtx, 4);
case GL11.GL_LIGHT5 -> GLSMLighting.enableLight(glCtx, 5);
case GL11.GL_LIGHT6 -> GLSMLighting.enableLight(glCtx, 6);
case GL11.GL_LIGHT7 -> GLSMLighting.enableLight(glCtx, 7);
case GL11.GL_LINE_SMOOTH -> glCtx.lineSmoothState.enable();
case GL11.GL_LINE_STIPPLE -> glCtx.lineStippleState.enable();
case GL11.GL_MAP1_COLOR_4 -> glCtx.map1Color4State.enable();
case GL11.GL_MAP1_INDEX -> glCtx.map1IndexState.enable();
case GL11.GL_MAP1_NORMAL -> glCtx.map1NormalState.enable();
case GL11.GL_MAP1_TEXTURE_COORD_1 -> glCtx.map1TextureCoord1State.enable();
case GL11.GL_MAP1_TEXTURE_COORD_2 -> glCtx.map1TextureCoord2State.enable();
case GL11.GL_MAP1_TEXTURE_COORD_3 -> glCtx.map1TextureCoord3State.enable();
case GL11.GL_MAP1_TEXTURE_COORD_4 -> glCtx.map1TextureCoord4State.enable();
case GL11.GL_MAP1_VERTEX_3 -> glCtx.map1Vertex3State.enable();
case GL11.GL_MAP1_VERTEX_4 -> glCtx.map1Vertex4State.enable();
case GL11.GL_MAP2_COLOR_4 -> glCtx.map2Color4State.enable();
case GL11.GL_MAP2_INDEX -> glCtx.map2IndexState.enable();
case GL11.GL_MAP2_NORMAL -> glCtx.map2NormalState.enable();
case GL11.GL_MAP2_TEXTURE_COORD_1 -> glCtx.map2TextureCoord1State.enable();
case GL11.GL_MAP2_TEXTURE_COORD_2 -> glCtx.map2TextureCoord2State.enable();
case GL11.GL_MAP2_TEXTURE_COORD_3 -> glCtx.map2TextureCoord3State.enable();
case GL11.GL_MAP2_TEXTURE_COORD_4 -> glCtx.map2TextureCoord4State.enable();
case GL11.GL_MAP2_VERTEX_3 -> glCtx.map2Vertex3State.enable();
case GL11.GL_MAP2_VERTEX_4 -> glCtx.map2Vertex4State.enable();
case GL13.GL_MULTISAMPLE -> glCtx.multisampleState.enable();
case GL11.GL_NORMALIZE -> glCtx.normalizeState.enable();
case GL11.GL_POINT_SMOOTH -> glCtx.pointSmoothState.enable();
case GL20.GL_POINT_SPRITE -> glCtx.pointSpriteState.enable();
case GL20.GL_VERTEX_PROGRAM_TWO_SIDE -> glCtx.vertexProgramTwoSideState.enable();
case GL11.GL_POLYGON_OFFSET_POINT -> glCtx.polygonOffsetPointState.enable();
case GL11.GL_POLYGON_OFFSET_LINE -> glCtx.polygonOffsetLineState.enable();
case GL11.GL_POLYGON_OFFSET_FILL -> glCtx.polygonOffsetFillState.enable();
case GL11.GL_POLYGON_SMOOTH -> glCtx.polygonSmoothState.enable();
case GL11.GL_POLYGON_STIPPLE -> glCtx.polygonStippleState.enable();
case GL12.GL_RESCALE_NORMAL -> GLSMLighting.enableRescaleNormal(glCtx);
case GL13.GL_SAMPLE_ALPHA_TO_COVERAGE -> glCtx.sampleAlphaToCoverageState.enable();
case GL13.GL_SAMPLE_ALPHA_TO_ONE -> glCtx.sampleAlphaToOneState.enable();
case GL13.GL_SAMPLE_COVERAGE -> glCtx.sampleCoverageState.enable();
case GL30.GL_RASTERIZER_DISCARD -> glCtx.rasterizerDiscard.enable();
case GL11.GL_SCISSOR_TEST -> GLSMRasterizer.enableScissorTest(glCtx);
case GL11.GL_STENCIL_TEST -> glCtx.stencilTest.enable();
case GL11.GL_TEXTURE_1D -> glCtx.textures.getTexture1DStates(glCtx.activeTextureUnit.getValue()).enable();
case GL11.GL_TEXTURE_2D -> GLSMTextures.enableTexture(glCtx);
case GL12.GL_TEXTURE_3D -> glCtx.textures.getTexture3DStates(glCtx.activeTextureUnit.getValue()).enable();
case GL13.GL_TEXTURE_CUBE_MAP -> glCtx.textures.getTextureCubeMapStates(glCtx.activeTextureUnit.getValue()).enable();
case GL11.GL_TEXTURE_GEN_S -> glCtx.textures.getTexGenSStates(glCtx.activeTextureUnit.getValue()).enable();
case GL11.GL_TEXTURE_GEN_T -> glCtx.textures.getTexGenTStates(glCtx.activeTextureUnit.getValue()).enable();
case GL11.GL_TEXTURE_GEN_R -> glCtx.textures.getTexGenRStates(glCtx.activeTextureUnit.getValue()).enable();
case GL11.GL_TEXTURE_GEN_Q -> glCtx.textures.getTexGenQStates(glCtx.activeTextureUnit.getValue()).enable();
default -> {
glCtx.exitCapture.reject();
if (!GLSMVertexInput.setClientArrayCap(glCtx, cap, true)) RENDER_BACKEND.enable(cap);
}
}
}
public static void glDisable(int cap) {
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(cap);
if (mode == RecordMode.COMPILE) {
return;
}
}
// Handle clip planes dynamically (supports up to MAX_CLIP_PLANES)
if (cap >= GL11.GL_CLIP_PLANE0 && cap < GL11.GL_CLIP_PLANE0 + MAX_CLIP_PLANES) {
glCtx.clipPlaneStates[cap - GL11.GL_CLIP_PLANE0].disable();
glCtx.clipPlaneGeneration++;
return;
}
switch (cap) {
case GL11.GL_ALPHA_TEST -> GLSMDepthStencilAlpha.disableAlphaTest(glCtx);
case GL11.GL_AUTO_NORMAL -> glCtx.autoNormalState.disable();
case GL11.GL_BLEND -> GLSMBlend.disableBlend(glCtx);
case GL11.GL_COLOR_MATERIAL -> GLSMLighting.disableColorMaterial(glCtx);
case GL11.GL_COLOR_LOGIC_OP -> glCtx.colorLogicOpState.disable();
case GL14.GL_COLOR_SUM -> glCtx.colorSumState.disable();
case GL11.GL_CULL_FACE -> GLSMRasterizer.disableCull(glCtx);
case GL11.GL_DEPTH_TEST -> GLSMDepthStencilAlpha.disableDepthTest(glCtx);
case GL11.GL_DITHER -> glCtx.ditherState.disable();
case GL11.GL_FOG -> GLSMFog.disableFog(glCtx);
case GL11.GL_INDEX_LOGIC_OP -> glCtx.indexLogicOpState.disable();
case GL11.GL_LIGHTING -> GLSMLighting.disableLighting(glCtx);
case GL11.GL_LIGHT0 -> GLSMLighting.disableLight(glCtx, 0);
case GL11.GL_LIGHT1 -> GLSMLighting.disableLight(glCtx, 1);
case GL11.GL_LIGHT2 -> GLSMLighting.disableLight(glCtx, 2);
case GL11.GL_LIGHT3 -> GLSMLighting.disableLight(glCtx, 3);
case GL11.GL_LIGHT4 -> GLSMLighting.disableLight(glCtx, 4);
case GL11.GL_LIGHT5 -> GLSMLighting.disableLight(glCtx, 5);
case GL11.GL_LIGHT6 -> GLSMLighting.disableLight(glCtx, 6);
case GL11.GL_LIGHT7 -> GLSMLighting.disableLight(glCtx, 7);
case GL11.GL_LINE_SMOOTH -> glCtx.lineSmoothState.disable();
case GL11.GL_LINE_STIPPLE -> glCtx.lineStippleState.disable();
case GL11.GL_MAP1_COLOR_4 -> glCtx.map1Color4State.disable();
case GL11.GL_MAP1_INDEX -> glCtx.map1IndexState.disable();
case GL11.GL_MAP1_NORMAL -> glCtx.map1NormalState.disable();
case GL11.GL_MAP1_TEXTURE_COORD_1 -> glCtx.map1TextureCoord1State.disable();
case GL11.GL_MAP1_TEXTURE_COORD_2 -> glCtx.map1TextureCoord2State.disable();
case GL11.GL_MAP1_TEXTURE_COORD_3 -> glCtx.map1TextureCoord3State.disable();
case GL11.GL_MAP1_TEXTURE_COORD_4 -> glCtx.map1TextureCoord4State.disable();
case GL11.GL_MAP1_VERTEX_3 -> glCtx.map1Vertex3State.disable();
case GL11.GL_MAP1_VERTEX_4 -> glCtx.map1Vertex4State.disable();
case GL11.GL_MAP2_COLOR_4 -> glCtx.map2Color4State.disable();
case GL11.GL_MAP2_INDEX -> glCtx.map2IndexState.disable();
case GL11.GL_MAP2_NORMAL -> glCtx.map2NormalState.disable();
case GL11.GL_MAP2_TEXTURE_COORD_1 -> glCtx.map2TextureCoord1State.disable();
case GL11.GL_MAP2_TEXTURE_COORD_2 -> glCtx.map2TextureCoord2State.disable();
case GL11.GL_MAP2_TEXTURE_COORD_3 -> glCtx.map2TextureCoord3State.disable();
case GL11.GL_MAP2_TEXTURE_COORD_4 -> glCtx.map2TextureCoord4State.disable();
case GL11.GL_MAP2_VERTEX_3 -> glCtx.map2Vertex3State.disable();
case GL11.GL_MAP2_VERTEX_4 -> glCtx.map2Vertex4State.disable();
case GL13.GL_MULTISAMPLE -> glCtx.multisampleState.disable();
case GL11.GL_NORMALIZE -> glCtx.normalizeState.disable();
case GL11.GL_POINT_SMOOTH -> glCtx.pointSmoothState.disable();
case GL20.GL_POINT_SPRITE -> glCtx.pointSpriteState.disable();
case GL20.GL_VERTEX_PROGRAM_TWO_SIDE -> glCtx.vertexProgramTwoSideState.disable();
case GL11.GL_POLYGON_OFFSET_POINT -> glCtx.polygonOffsetPointState.disable();
case GL11.GL_POLYGON_OFFSET_LINE -> glCtx.polygonOffsetLineState.disable();
case GL11.GL_POLYGON_OFFSET_FILL -> glCtx.polygonOffsetFillState.disable();
case GL11.GL_POLYGON_SMOOTH -> glCtx.polygonSmoothState.disable();
case GL11.GL_POLYGON_STIPPLE -> glCtx.polygonStippleState.disable();
case GL12.GL_RESCALE_NORMAL -> GLSMLighting.disableRescaleNormal(glCtx);
case GL13.GL_SAMPLE_ALPHA_TO_COVERAGE -> glCtx.sampleAlphaToCoverageState.disable();
case GL13.GL_SAMPLE_ALPHA_TO_ONE -> glCtx.sampleAlphaToOneState.disable();
case GL13.GL_SAMPLE_COVERAGE -> glCtx.sampleCoverageState.disable();
case GL30.GL_RASTERIZER_DISCARD -> glCtx.rasterizerDiscard.disable();
case GL11.GL_SCISSOR_TEST -> GLSMRasterizer.disableScissorTest(glCtx);
case GL11.GL_STENCIL_TEST -> glCtx.stencilTest.disable();
case GL11.GL_TEXTURE_1D -> glCtx.textures.getTexture1DStates(glCtx.activeTextureUnit.getValue()).disable();
case GL11.GL_TEXTURE_2D -> GLSMTextures.disableTexture(glCtx);
case GL12.GL_TEXTURE_3D -> glCtx.textures.getTexture3DStates(glCtx.activeTextureUnit.getValue()).disable();
case GL13.GL_TEXTURE_CUBE_MAP -> glCtx.textures.getTextureCubeMapStates(glCtx.activeTextureUnit.getValue()).disable();
case GL11.GL_TEXTURE_GEN_S -> glCtx.textures.getTexGenSStates(glCtx.activeTextureUnit.getValue()).disable();
case GL11.GL_TEXTURE_GEN_T -> glCtx.textures.getTexGenTStates(glCtx.activeTextureUnit.getValue()).disable();
case GL11.GL_TEXTURE_GEN_R -> glCtx.textures.getTexGenRStates(glCtx.activeTextureUnit.getValue()).disable();
case GL11.GL_TEXTURE_GEN_Q -> glCtx.textures.getTexGenQStates(glCtx.activeTextureUnit.getValue()).disable();
default -> {
glCtx.exitCapture.reject();
if (!GLSMVertexInput.setClientArrayCap(glCtx, cap, false)) RENDER_BACKEND.disable(cap);
}
}
}
public static boolean glIsEnabled(int cap) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) {
return RENDER_BACKEND.getBoolean(cap);
}
// Handle clip planes dynamically (supports up to MAX_CLIP_PLANES)
if (cap >= GL11.GL_CLIP_PLANE0 && cap < GL11.GL_CLIP_PLANE0 + MAX_CLIP_PLANES) {
return glCtx.clipPlaneStates[cap - GL11.GL_CLIP_PLANE0].isEnabled();
}
return switch (cap) {
case GL11.GL_ALPHA_TEST -> glCtx.alphaTest.isEnabled();
case GL11.GL_AUTO_NORMAL -> glCtx.autoNormalState.isEnabled();
case GL11.GL_BLEND -> glCtx.blendMode.isEnabled();
case GL11.GL_COLOR_MATERIAL -> glCtx.colorMaterial.isEnabled();
case GL11.GL_COLOR_LOGIC_OP -> glCtx.colorLogicOpState.isEnabled();
case GL14.GL_COLOR_SUM -> glCtx.colorSumState.isEnabled();
case GL11.GL_CULL_FACE -> glCtx.cullState.isEnabled();
case GL11.GL_DEPTH_TEST -> glCtx.depthTest.isEnabled();
case GL11.GL_DITHER -> glCtx.ditherState.isEnabled();
case GL11.GL_FOG -> glCtx.fogMode.isEnabled();
case GL11.GL_INDEX_LOGIC_OP -> glCtx.indexLogicOpState.isEnabled();
case GL11.GL_LIGHTING -> glCtx.lightingState.isEnabled();
case GL11.GL_LIGHT0 -> glCtx.lightStates[0].isEnabled();
case GL11.GL_LIGHT1 -> glCtx.lightStates[1].isEnabled();
case GL11.GL_LIGHT2 -> glCtx.lightStates[2].isEnabled();
case GL11.GL_LIGHT3 -> glCtx.lightStates[3].isEnabled();
case GL11.GL_LIGHT4 -> glCtx.lightStates[4].isEnabled();
case GL11.GL_LIGHT5 -> glCtx.lightStates[5].isEnabled();
case GL11.GL_LIGHT6 -> glCtx.lightStates[6].isEnabled();
case GL11.GL_LIGHT7 -> glCtx.lightStates[7].isEnabled();
case GL11.GL_LINE_SMOOTH -> glCtx.lineSmoothState.isEnabled();
case GL11.GL_LINE_STIPPLE -> glCtx.lineStippleState.isEnabled();
case GL11.GL_MAP1_COLOR_4 -> glCtx.map1Color4State.isEnabled();
case GL11.GL_MAP1_INDEX -> glCtx.map1IndexState.isEnabled();
case GL11.GL_MAP1_NORMAL -> glCtx.map1NormalState.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_1 -> glCtx.map1TextureCoord1State.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_2 -> glCtx.map1TextureCoord2State.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_3 -> glCtx.map1TextureCoord3State.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_4 -> glCtx.map1TextureCoord4State.isEnabled();
case GL11.GL_MAP1_VERTEX_3 -> glCtx.map1Vertex3State.isEnabled();
case GL11.GL_MAP1_VERTEX_4 -> glCtx.map1Vertex4State.isEnabled();
case GL11.GL_MAP2_COLOR_4 -> glCtx.map2Color4State.isEnabled();
case GL11.GL_MAP2_INDEX -> glCtx.map2IndexState.isEnabled();
case GL11.GL_MAP2_NORMAL -> glCtx.map2NormalState.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_1 -> glCtx.map2TextureCoord1State.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_2 -> glCtx.map2TextureCoord2State.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_3 -> glCtx.map2TextureCoord3State.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_4 -> glCtx.map2TextureCoord4State.isEnabled();
case GL11.GL_MAP2_VERTEX_3 -> glCtx.map2Vertex3State.isEnabled();
case GL11.GL_MAP2_VERTEX_4 -> glCtx.map2Vertex4State.isEnabled();
case GL13.GL_MULTISAMPLE -> glCtx.multisampleState.isEnabled();
case GL11.GL_NORMALIZE -> glCtx.normalizeState.isEnabled();
case GL11.GL_POINT_SMOOTH -> glCtx.pointSmoothState.isEnabled();
case GL20.GL_POINT_SPRITE -> glCtx.pointSpriteState.isEnabled();
case GL20.GL_VERTEX_PROGRAM_TWO_SIDE -> glCtx.vertexProgramTwoSideState.isEnabled();
case GL11.GL_POLYGON_OFFSET_POINT -> glCtx.polygonOffsetPointState.isEnabled();
case GL11.GL_POLYGON_OFFSET_LINE -> glCtx.polygonOffsetLineState.isEnabled();
case GL11.GL_POLYGON_OFFSET_FILL -> glCtx.polygonOffsetFillState.isEnabled();
case GL11.GL_POLYGON_SMOOTH -> glCtx.polygonSmoothState.isEnabled();
case GL11.GL_POLYGON_STIPPLE -> glCtx.polygonStippleState.isEnabled();
case GL12.GL_RESCALE_NORMAL -> glCtx.rescaleNormalState.isEnabled();
case GL13.GL_SAMPLE_ALPHA_TO_COVERAGE -> glCtx.sampleAlphaToCoverageState.isEnabled();
case GL13.GL_SAMPLE_ALPHA_TO_ONE -> glCtx.sampleAlphaToOneState.isEnabled();
case GL13.GL_SAMPLE_COVERAGE -> glCtx.sampleCoverageState.isEnabled();
case GL30.GL_RASTERIZER_DISCARD -> glCtx.rasterizerDiscard.isEnabled();
case GL11.GL_SCISSOR_TEST -> glCtx.scissorTest.isEnabled();
case GL11.GL_STENCIL_TEST -> glCtx.stencilTest.isEnabled();
case GL11.GL_TEXTURE_1D -> glCtx.textures.getTexture1DStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_2D -> glCtx.textures.getTextureUnitStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL12.GL_TEXTURE_3D -> glCtx.textures.getTexture3DStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL13.GL_TEXTURE_CUBE_MAP -> glCtx.textures.getTextureCubeMapStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_S -> glCtx.textures.getTexGenSStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_T -> glCtx.textures.getTexGenTStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_R -> glCtx.textures.getTexGenRStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_Q -> glCtx.textures.getTexGenQStates(glCtx.activeTextureUnit.getValue()).isEnabled();
default -> {
final int conv = GLSMVertexInput.clientStateToConventional(glCtx, cap);
yield conv >= 0 ? glCtx.vaos.isConventionalEnabled(conv) : LegacyQueries.desc(cap) == 0 && RENDER_BACKEND.getBoolean(cap);
}
};
}
public static void glEnablei(int cap, int index) {
rejectExitCapture();
RENDER_BACKEND.enablei(cap, index);
markIndexedCapUnknown(cap);
}
public static void glDisablei(int cap, int index) {
rejectExitCapture();
RENDER_BACKEND.disablei(cap, index);
markIndexedCapUnknown(cap);
}
private static void markIndexedCapUnknown(int cap) {
if (cap == GL11.GL_BLEND) {
ctx().blendMode.setUnknownState();
} else if (cap == GL11.GL_SCISSOR_TEST) {
ctx().scissorTest.setUnknownState();
}
}
}
@@ -0,0 +1,169 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.FogStateStack;
import org.joml.Vector3d;
import org.lwjgl.opengl.GL11;
import java.nio.FloatBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.HAS_MULTIPLE_SET;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
public final class GLSMFog {
private GLSMFog() {}
public static void enableFog() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_FOG);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableFog(ctx());
}
static void enableFog(GLContextState glCtx) {
glCtx.fogMode.enable();
if (GLSMHooks.FOG_STATE_CHANGE.hasListeners()) {
GLSMHooks.FOG_STATE_CHANGE.post(GLSMHooks.fogStateChangeEvent);
}
}
public static void disableFog() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_FOG);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableFog(ctx());
}
static void disableFog(GLContextState glCtx) {
glCtx.fogMode.disable();
if (GLSMHooks.FOG_STATE_CHANGE.hasListeners()) {
GLSMHooks.FOG_STATE_CHANGE.post(GLSMHooks.fogStateChangeEvent);
}
}
public static void glFog(int pname, FloatBuffer param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordFog(pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (HAS_MULTIPLE_SET.contains(pname)) {
if (pname == GL11.GL_FOG_COLOR && isCachingEnabled()) {
final float red = param.get(0);
final float green = param.get(1);
final float blue = param.get(2);
beforeUncapturedStateChange();
mod(glCtx.fogState);
glCtx.fogState.getFogColor().set(red, green, blue);
glCtx.fogState.setFogAlpha(param.get(3));
glCtx.fogState.getFogColorBuffer().clear();
glCtx.fogState.getFogColorBuffer().put((FloatBuffer) param.position(0)).flip();
glCtx.fragmentGeneration++;
if (GLSMHooks.FOG_STATE_CHANGE.hasListeners()) {
GLSMHooks.FOG_STATE_CHANGE.post(GLSMHooks.fogStateChangeEvent);
}
}
} else {
glFogf(pname, param.get(0));
}
}
public static Vector3d getFogColor() {
return ctx().fogState.getFogColor();
}
public static void fogColor(float red, float green, float blue, float alpha) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final boolean caching = isCachingEnabled();
if (!caching || red != glCtx.fogState.getFogColor().x || green != glCtx.fogState.getFogColor().y || blue != glCtx.fogState.getFogColor().z || alpha != glCtx.fogState.getFogAlpha()) {
beforeUncapturedStateChange();
mod(glCtx.fogState);
glCtx.fogState.getFogColor().set(red, green, blue);
glCtx.fogState.setFogAlpha(alpha);
glCtx.fogState.getFogColorBuffer().clear();
glCtx.fogState.getFogColorBuffer().put(red).put(green).put(blue).put(alpha).flip();
glCtx.fragmentGeneration++;
if (GLSMHooks.FOG_STATE_CHANGE.hasListeners()) {
GLSMHooks.FOG_STATE_CHANGE.post(GLSMHooks.fogStateChangeEvent);
}
}
}
public static void glFogf(int pname, float param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordFogf(pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
// Update cached state (FFP shader reads from cache)
if (isCachingEnabled()) {
boolean changed = false;
switch (pname) {
case GL11.GL_FOG_DENSITY -> { if (!isCachingEnabled() || glCtx.fogState.getDensity() != param) { beforeUncapturedStateChange(); mod(glCtx.fogState).setDensity(param); changed = true; } }
case GL11.GL_FOG_START -> { if (!isCachingEnabled() || glCtx.fogState.getStart() != param) { beforeUncapturedStateChange(); mod(glCtx.fogState).setStart(param); changed = true; } }
case GL11.GL_FOG_END -> { if (!isCachingEnabled() || glCtx.fogState.getEnd() != param) { beforeUncapturedStateChange(); mod(glCtx.fogState).setEnd(param); changed = true; } }
case GL11.GL_FOG_MODE -> { if (!isCachingEnabled() || glCtx.fogState.getFogMode() != (int) param) { beforeUncapturedStateChange(); mod(glCtx.fogState).setFogMode((int) param); changed = true; } }
default -> {}
}
if (changed) {
glCtx.fragmentGeneration++;
if (GLSMHooks.FOG_STATE_CHANGE.hasListeners()) {
GLSMHooks.FOG_STATE_CHANGE.post(GLSMHooks.fogStateChangeEvent);
}
}
}
}
public static void glFogi(int pname, int param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordFogi(pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
// Update cached state (FFP shader reads from cache)
if (isCachingEnabled() && pname == GL11.GL_FOG_MODE && (!isCachingEnabled() || glCtx.fogState.getFogMode() != param)) {
beforeUncapturedStateChange();
mod(glCtx.fogState).setFogMode(param);
glCtx.fragmentGeneration++;
if (GLSMHooks.FOG_STATE_CHANGE.hasListeners()) {
GLSMHooks.FOG_STATE_CHANGE.post(GLSMHooks.fogStateChangeEvent);
}
}
}
public static FogStateStack getFogState() {
return ctx().fogState;
}
public static BooleanStateStack getFogMode() {
return ctx().fogMode;
}
}
@@ -0,0 +1,344 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.stacks.IntegerStateStack;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MainThread;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.requireContext;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMFramebuffer {
private GLSMFramebuffer() {}
// This setting varies depending on driver, so it gets queried at runtime
public static int DEFAULT_DRAW_BUFFER = GL11.GL_BACK;
public static boolean framebufferCompletenessIsMeaningful() { return RENDER_BACKEND.framebufferCompletenessIsMeaningful(); }
static int drawFramebufferBits(GLContextState glCtx, boolean stencil) {
final int sizePname = stencil ? GL30.GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE : GL30.GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
if (glCtx.drawFramebuffer == 0) {
return RENDER_BACKEND.getFramebufferAttachmentParameteri(GL30.GL_DRAW_FRAMEBUFFER, stencil ? GL11.GL_STENCIL : GL11.GL_DEPTH, sizePname);
}
final int attachment = stencil ? GL30.GL_STENCIL_ATTACHMENT : GL30.GL_DEPTH_ATTACHMENT;
if (RENDER_BACKEND.getFramebufferAttachmentParameteri(GL30.GL_DRAW_FRAMEBUFFER, attachment, GL30.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) == GL11.GL_NONE) {
return 0;
}
return RENDER_BACKEND.getFramebufferAttachmentParameteri(GL30.GL_DRAW_FRAMEBUFFER, attachment, sizePname);
}
static void queryDefaultDrawBuffer() {
DEFAULT_DRAW_BUFFER = RENDER_BACKEND.getInteger(GL11.GL_DRAW_BUFFER);
}
static void armFirstClear() {
firstClearPending = true;
}
public static void glDrawBuffer(int mode) {
rejectExitCapture();
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
DisplayListManager.recordDrawBuffer(mode);
if (recordMode == RecordMode.COMPILE) {
return;
}
}
if (!isCachingEnabled() || ctx().drawBuffer.getValue() != mode) beforeUncapturedStateChange();
if (isCachingEnabled()) mod(ctx().drawBuffer).setValue(mode);
RENDER_BACKEND.drawBuffer(mode);
}
private static boolean firstClearPending;
private static long firstClearBlockNanos;
public static void glClear(int mask) {
rejectExitCapture();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordClear(mask);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (ctx().rasterizerDiscard.isEnabled() || FeedbackManager.getRenderMode() != GL11.GL_RENDER) {
return;
}
if (firstClearPending && Thread.currentThread() == MainThread && getDrawFramebuffer() == 0) {
firstClearPending = false;
final long start = System.nanoTime();
RENDER_BACKEND.clear(mask);
final long end = System.nanoTime();
if (end - start > 0) {
firstClearBlockNanos += end - start;
RENDER_BACKEND.recordGate(end - start, end);
}
return;
}
RENDER_BACKEND.clear(mask);
}
public static long takeFirstClearBlockNanos() {
final long value = firstClearBlockNanos;
firstClearBlockNanos = 0L;
return value;
}
public static void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer pixels) {
rejectExitCapture();
type = GLSMTextures.remapPixelTypeForGLES(format, type);
GLSMBuffers.suspendPixelPackBuffer();
RENDER_BACKEND.readPixels(x, y, width, height, format, type, pixels);
GLSMBuffers.restorePixelPackBuffer();
}
public static void glReadPixels(int x, int y, int width, int height, int format, int type, FloatBuffer pixels) {
rejectExitCapture();
type = GLSMTextures.remapPixelTypeForGLES(format, type);
GLSMBuffers.suspendPixelPackBuffer();
RENDER_BACKEND.readPixels(x, y, width, height, format, type, pixels);
GLSMBuffers.restorePixelPackBuffer();
}
public static void glReadPixels(int x, int y, int width, int height, int format, int type, IntBuffer pixels) {
rejectExitCapture();
type = GLSMTextures.remapPixelTypeForGLES(format, type);
GLSMBuffers.suspendPixelPackBuffer();
RENDER_BACKEND.readPixels(x, y, width, height, format, type, pixels);
GLSMBuffers.restorePixelPackBuffer();
}
public static void glReadBuffer(int mode) {
rejectExitCapture();
if (DisplayListManager.isRecording()) {
throw DisplayListManager.unsupportedInList("glReadBuffer");
}
RENDER_BACKEND.readBuffer(mode);
}
public static void glDrawBuffers(int buffer) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDrawBuffers(1, buffer);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
RENDER_BACKEND.drawBuffers(buffer);
}
public static void glDrawBuffers(IntBuffer bufs) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDrawBuffers(bufs.remaining(), bufs);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
RENDER_BACKEND.drawBuffers(bufs);
}
public static boolean glIsFramebuffer(int framebuffer) { rejectExitCapture(); return RENDER_BACKEND.isFramebuffer(framebuffer); }
public static boolean glIsRenderbuffer(int renderbuffer) { rejectExitCapture(); return RENDER_BACKEND.isRenderbuffer(renderbuffer); }
public static void glBindFramebuffer(int target, int framebuffer) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (target == GL30.GL_FRAMEBUFFER) {
if (glCtx.drawFramebuffer == framebuffer && glCtx.readFramebuffer == framebuffer) return;
if (glCtx.drawFramebuffer != framebuffer) glCtx.drawFramebufferGeneration++;
glCtx.drawFramebuffer = framebuffer;
glCtx.readFramebuffer = framebuffer;
} else if (target == GL30.GL_DRAW_FRAMEBUFFER) {
if (glCtx.drawFramebuffer == framebuffer) return;
glCtx.drawFramebufferGeneration++;
glCtx.drawFramebuffer = framebuffer;
} else if (target == GL30.GL_READ_FRAMEBUFFER) {
if (glCtx.readFramebuffer == framebuffer) return;
glCtx.readFramebuffer = framebuffer;
}
RENDER_BACKEND.bindFramebuffer(target, framebuffer);
}
public static void glDeleteFramebuffers(int framebuffer) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (glCtx.drawFramebuffer == framebuffer) { glCtx.drawFramebuffer = 0; glCtx.drawFramebufferGeneration++; }
if (glCtx.readFramebuffer == framebuffer) glCtx.readFramebuffer = 0;
final int[] slots = glCtx.framebufferTextures.remove(framebuffer);
if (slots != null) {
for (int slot = 0; slot < slots.length; slot++) GLSMTextureLifetime.setFramebufferSlot(slots, slot, 0);
}
RENDER_BACKEND.deleteFramebuffers(framebuffer);
}
public static void glDeleteFramebuffers(IntBuffer framebuffers) {
for (int i = framebuffers.position(); i < framebuffers.limit(); i++) glDeleteFramebuffers(framebuffers.get(i));
}
public static void glDeleteFramebuffers(int[] framebuffers) {
for (int framebuffer : framebuffers) glDeleteFramebuffers(framebuffer);
}
public static int glGenFramebuffers() {
requireContext("glGenFramebuffers");
return RENDER_BACKEND.genFramebuffers();
}
public static int glCheckFramebufferStatus(int target) {
rejectExitCapture();
return RENDER_BACKEND.checkFramebufferStatus(target);
}
public static int glGetFramebufferAttachmentParameteri(int target, int attachment, int pname) {
rejectExitCapture();
return RENDER_BACKEND.getFramebufferAttachmentParameteri(target, attachment, pname);
}
public static void glFramebufferTexture2D(int target, int attachment, int textarget, int texture, int level) {
rejectExitCapture();
if (!GLSMTextureLifetime.beginAttach(target, attachment, texture)) return;
RENDER_BACKEND.framebufferTexture2D(target, attachment, textarget, texture, level);
}
public static void glFramebufferTexture1D(int target, int attachment, int textarget, int texture, int level) {
rejectExitCapture();
if (!GLSMTextureLifetime.beginAttach(target, attachment, texture)) return;
RENDER_BACKEND.framebufferTexture1D(target, attachment, textarget, texture, level);
}
public static void glFramebufferTexture3D(int target, int attachment, int textarget, int texture, int level, int zoffset) {
rejectExitCapture();
if (!GLSMTextureLifetime.beginAttach(target, attachment, texture)) return;
RENDER_BACKEND.framebufferTexture3D(target, attachment, textarget, texture, level, zoffset);
}
public static void glFramebufferTextureLayer(int target, int attachment, int texture, int level, int layer) {
rejectExitCapture();
if (!GLSMTextureLifetime.beginAttach(target, attachment, texture)) return;
RENDER_BACKEND.framebufferTextureLayer(target, attachment, texture, level, layer);
}
public static void glFramebufferTexture(int target, int attachment, int texture, int level) {
rejectExitCapture();
if (!GLSMTextureLifetime.beginAttach(target, attachment, texture)) return;
RENDER_BACKEND.framebufferTexture(target, attachment, texture, level);
}
public static void glFramebufferTextureFace(int target, int attachment, int texture, int level, int face) {
glFramebufferTexture2D(target, attachment, face, texture, level);
}
public static void glNamedFramebufferTexture(int framebuffer, int attachment, int texture, int level) {
rejectExitCapture();
if (!GLSMTextureLifetime.beginAttach(ctx(), framebuffer, attachment, texture)) return;
RENDER_BACKEND.namedFramebufferTexture(framebuffer, attachment, texture, level);
}
private static int swapDrawFramebuffer(int framebuffer) {
final GLContextState glCtx = ctx();
final int previous = glCtx.drawFramebuffer;
glCtx.drawFramebuffer = framebuffer;
RENDER_BACKEND.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, framebuffer);
return previous;
}
public static void glNamedFramebufferTextureLayer(int framebuffer, int attachment, int texture, int level, int layer) {
final int previous = swapDrawFramebuffer(framebuffer);
glFramebufferTextureLayer(GL30.GL_DRAW_FRAMEBUFFER, attachment, texture, level, layer);
swapDrawFramebuffer(previous);
}
public static void glNamedFramebufferRenderbuffer(int framebuffer, int attachment, int renderbuffertarget, int renderbuffer) {
final int previous = swapDrawFramebuffer(framebuffer);
glFramebufferRenderbuffer(GL30.GL_DRAW_FRAMEBUFFER, attachment, renderbuffertarget, renderbuffer);
swapDrawFramebuffer(previous);
}
public static void glNamedFramebufferTexture1DEXT(int framebuffer, int attachment, int textarget, int texture, int level) {
final int previous = swapDrawFramebuffer(framebuffer);
glFramebufferTexture1D(GL30.GL_DRAW_FRAMEBUFFER, attachment, textarget, texture, level);
swapDrawFramebuffer(previous);
}
public static void glNamedFramebufferTexture2DEXT(int framebuffer, int attachment, int textarget, int texture, int level) {
final int previous = swapDrawFramebuffer(framebuffer);
glFramebufferTexture2D(GL30.GL_DRAW_FRAMEBUFFER, attachment, textarget, texture, level);
swapDrawFramebuffer(previous);
}
public static void glNamedFramebufferTexture3DEXT(int framebuffer, int attachment, int textarget, int texture, int level, int zoffset) {
final int previous = swapDrawFramebuffer(framebuffer);
glFramebufferTexture3D(GL30.GL_DRAW_FRAMEBUFFER, attachment, textarget, texture, level, zoffset);
swapDrawFramebuffer(previous);
}
public static void glNamedFramebufferTextureEXT(int framebuffer, int attachment, int texture, int level) {
final int previous = swapDrawFramebuffer(framebuffer);
glFramebufferTexture(GL30.GL_DRAW_FRAMEBUFFER, attachment, texture, level);
swapDrawFramebuffer(previous);
}
public static void glNamedFramebufferTextureFaceEXT(int framebuffer, int attachment, int texture, int level, int face) {
glNamedFramebufferTexture2DEXT(framebuffer, attachment, face, texture, level);
}
public static void attachTextureForReading(int attachment, int texture) {
if (GLSMTextureLifetime.isDeferredDelete(texture)) return;
final GLContextState glCtx = ctx();
GLSMTextureLifetime.trackFramebufferAttachment(glCtx, glCtx.readFramebuffer, attachment, texture);
RENDER_BACKEND.framebufferTexture2D(GL30.GL_READ_FRAMEBUFFER, attachment, GL11.GL_TEXTURE_2D, texture, 0);
}
public static int glGenRenderbuffers() {
requireContext("glGenRenderbuffers");
return RENDER_BACKEND.genRenderbuffers();
}
public static void glDeleteRenderbuffers(int renderbuffer) { rejectExitCapture(); RENDER_BACKEND.deleteRenderbuffers(renderbuffer); }
public static void glBindRenderbuffer(int target, int renderbuffer) { rejectExitCapture(); RENDER_BACKEND.bindRenderbuffer(target, renderbuffer); }
public static void glRenderbufferStorage(int target, int internalformat, int width, int height) { rejectExitCapture(); RENDER_BACKEND.renderbufferStorage(target, internalformat, width, height); }
public static void glRenderbufferStorageMultisample(int target, int samples, int internalformat, int width, int height) { rejectExitCapture(); RENDER_BACKEND.renderbufferStorageMultisample(target, samples, internalformat, width, height); }
public static void glFramebufferRenderbuffer(int target, int attachment, int renderbuffertarget, int renderbuffer) {
rejectExitCapture();
GLSMTextureLifetime.beginAttach(target, attachment, 0);
RENDER_BACKEND.framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
}
public static void glBlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
rejectExitCapture();
RENDER_BACKEND.blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
public static boolean isFramebufferEnabled() {
return true;
}
public static void glReadPixels(int x, int y, int width, int height, int format, int type, long pixels) {
rejectExitCapture();
RENDER_BACKEND.readPixels(x, y, width, height, format, GLSMTextures.remapPixelTypeForGLES(format, type), pixels);
}
public static int getDrawFramebufferGeneration() {
return ctx().drawFramebufferGeneration;
}
public static IntegerStateStack getDrawBuffer() {
return ctx().drawBuffer;
}
public static int getDrawFramebuffer() {
return ctx().drawFramebuffer;
}
public static int getReadFramebuffer() {
return ctx().readFramebuffer;
}
}
@@ -0,0 +1,781 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.ffp.ShaderManager;
import com.gtnewhorizons.angelica.glsm.ffp.VertexKey;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.IntegerStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.LightModelStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.LightStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.MaterialStateStack;
import org.joml.Vector4f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.LOGGER;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
public final class GLSMLighting {
private GLSMLighting() {}
public static void glGetMaterial(int face, int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final MaterialStateStack state;
if (face == GL11.GL_FRONT) {
state = glCtx.frontMaterial;
} else if (face == GL11.GL_BACK) {
state = glCtx.backMaterial;
} else {
throw new RuntimeException("Invalid face parameter specified to glGetMaterial: " + face);
}
switch (pname) {
case GL11.GL_AMBIENT -> state.ambient.get(params.position(), params);
case GL11.GL_DIFFUSE -> state.diffuse.get(params.position(), params);
case GL11.GL_SPECULAR -> state.specular.get(params.position(), params);
case GL11.GL_EMISSION -> state.emission.get(params.position(), params);
case GL11.GL_SHININESS -> params.put(params.position(), state.shininess);
case GL11.GL_COLOR_INDEXES -> state.colorIndexes.get(params.position(), params);
default -> {
}
}
}
private static void putLightingInts(FloatBuffer values, int pname, boolean material, IntBuffer params) {
final int count = switch (pname) {
case GL11.GL_AMBIENT, GL11.GL_DIFFUSE, GL11.GL_SPECULAR -> 4;
case GL11.GL_EMISSION -> material ? 4 : 0;
case GL11.GL_COLOR_INDEXES -> material ? 3 : 0;
case GL11.GL_SHININESS -> material ? 1 : 0;
case GL11.GL_POSITION -> material ? 0 : 4;
case GL11.GL_SPOT_DIRECTION -> material ? 0 : 3;
case GL11.GL_SPOT_EXPONENT, GL11.GL_SPOT_CUTOFF, GL11.GL_CONSTANT_ATTENUATION, GL11.GL_LINEAR_ATTENUATION,
GL11.GL_QUADRATIC_ATTENUATION -> material ? 0 : 1;
default -> 0;
};
final boolean color = count == 4 && pname != GL11.GL_POSITION;
final int pos = params.position();
for (int i = 0; i < count; i++) {
final float value = values.get(i);
final int converted;
if (color) {
converted = LegacyQueries.floatToInt(value);
} else if (material) {
converted = LegacyQueries.lround(value);
} else {
converted = (int) value;
}
params.put(pos + i, converted);
}
}
public static void glGetMaterial(int face, int pname, IntBuffer params) {
final FloatBuffer scratch = ctx().queryScratch;
scratch.clear();
glGetMaterial(face, pname, scratch);
putLightingInts(scratch, pname, true, params);
}
public static void glGetLight(int light, int pname, IntBuffer params) {
final FloatBuffer scratch = ctx().queryScratch;
scratch.clear();
glGetLight(light, pname, scratch);
putLightingInts(scratch, pname, false, params);
}
public static void glGetLight(int light, int pname, FloatBuffer params) {
rejectExitCapture();
final LightStateStack state = ctx().lightDataStates[light - GL11.GL_LIGHT0];
switch (pname) {
case GL11.GL_AMBIENT -> state.ambient.get(params.position(), params);
case GL11.GL_DIFFUSE -> state.diffuse.get(params.position(), params);
case GL11.GL_SPECULAR -> state.specular.get(params.position(), params);
case GL11.GL_POSITION -> state.position.get(params.position(), params);
case GL11.GL_SPOT_DIRECTION -> state.spotDirection.get(params.position(), params);
case GL11.GL_SPOT_EXPONENT -> params.put(params.position(), state.spotExponent);
case GL11.GL_SPOT_CUTOFF -> params.put(params.position(), state.spotCutoff);
case GL11.GL_CONSTANT_ATTENUATION -> params.put(params.position(), state.constantAttenuation);
case GL11.GL_LINEAR_ATTENUATION -> params.put(params.position(), state.linearAttenuation);
case GL11.GL_QUADRATIC_ATTENUATION -> params.put(params.position(), state.quadraticAttenuation);
default -> {
}
}
}
public static float i2f(int i) {return ((i - Integer.MIN_VALUE) & 0xFFFFFFFFL) / 4294967295.0F;}
public static void enableLighting() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_LIGHTING);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableLighting(ctx());
}
static void enableLighting(GLContextState glCtx) {
glCtx.lightingState.enable();
}
public static void enableLight(int light) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_LIGHT0 + light);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableLight(ctx(), light);
}
static void enableLight(GLContextState glCtx, int light) {
if (light >= VertexKey.FFP_LIGHT_COUNT && (warnedFfpLightMask & (1 << light)) == 0 && ShaderManager.isEnabled()) {
warnedFfpLightMask |= (1 << light);
LOGGER.warn("GL_LIGHT{} enabled, but FFP shader emulation implements only GL_LIGHT0..{}", light, VertexKey.FFP_LIGHT_COUNT - 1, new Throwable("call site"));
}
glCtx.lightStates[light].enable();
}
private static int warnedFfpLightMask = 0;
public static void enableColorMaterial() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_COLOR_MATERIAL);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableColorMaterial(ctx());
}
static void enableColorMaterial(GLContextState glCtx) {
glCtx.colorMaterial.enable();
bakeCurrentColorIntoTrackedMaterial(glCtx);
}
public static void disableColorMaterial() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_COLOR_MATERIAL);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableColorMaterial(ctx());
}
static void disableColorMaterial(GLContextState glCtx) {
bakeCurrentColorIntoTrackedMaterial(glCtx);
glCtx.colorMaterial.disable();
}
private static void bakeCurrentColorIntoTrackedMaterial(GLContextState glCtx) {
glCtx.exitCapture.requireMaterialBakeInputs();
final float r = glCtx.color.getRed();
final float g = glCtx.color.getGreen();
final float b = glCtx.color.getBlue();
final float a = glCtx.color.getAlpha();
final int face = glCtx.colorMaterialFace.getValue();
final int param = glCtx.colorMaterialParameter.getValue();
if (face == GL11.GL_FRONT || face == GL11.GL_FRONT_AND_BACK) {
bakeMaterialColor(glCtx, glCtx.frontMaterial, param, r, g, b, a);
}
if (face == GL11.GL_BACK || face == GL11.GL_FRONT_AND_BACK) {
bakeMaterialColor(glCtx, glCtx.backMaterial, param, r, g, b, a);
}
}
private static boolean materialVectorDiffers(Vector4f vec, float r, float g, float b, float a) {
return vec.x != r || vec.y != g || vec.z != b || vec.w != a;
}
private static void bakeMaterialColor(GLContextState glCtx, MaterialStateStack material, int param, float r, float g, float b, float a) {
glCtx.exitCapture.material(material.face, param);
final boolean changed = switch (param) {
case GL11.GL_AMBIENT_AND_DIFFUSE -> materialVectorDiffers(material.ambient, r, g, b, a) || materialVectorDiffers(material.diffuse, r, g, b, a);
case GL11.GL_AMBIENT -> materialVectorDiffers(material.ambient, r, g, b, a);
case GL11.GL_DIFFUSE -> materialVectorDiffers(material.diffuse, r, g, b, a);
case GL11.GL_SPECULAR -> materialVectorDiffers(material.specular, r, g, b, a);
case GL11.GL_EMISSION -> materialVectorDiffers(material.emission, r, g, b, a);
default -> false;
};
if (!changed) return;
mod(material);
switch (param) {
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
material.ambient.set(r, g, b, a);
material.diffuse.set(r, g, b, a);
}
case GL11.GL_AMBIENT -> material.ambient.set(r, g, b, a);
case GL11.GL_DIFFUSE -> material.diffuse.set(r, g, b, a);
case GL11.GL_SPECULAR -> material.specular.set(r, g, b, a);
case GL11.GL_EMISSION -> material.emission.set(r, g, b, a);
default -> {}
}
}
public static void disableLighting() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_LIGHTING);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableLighting(ctx());
}
static void disableLighting(GLContextState glCtx) {
glCtx.lightingState.disable();
}
public static void disableLight(int light) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_LIGHT0 + light);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableLight(ctx(), light);
}
static void disableLight(GLContextState glCtx, int light) {
glCtx.lightStates[light].disable();
}
public static void enableRescaleNormal() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL12.GL_RESCALE_NORMAL);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableRescaleNormal(ctx());
}
static void enableRescaleNormal(GLContextState glCtx) {
glCtx.rescaleNormalState.enable();
}
public static void disableRescaleNormal() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL12.GL_RESCALE_NORMAL);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableRescaleNormal(ctx());
}
static void disableRescaleNormal(GLContextState glCtx) {
glCtx.rescaleNormalState.disable();
}
private static boolean glMaterialFront(int pname, FloatBuffer params) {
final GLContextState glCtx = ctx();
mod(glCtx.frontMaterial);
return switch (pname) {
case GL11.GL_AMBIENT -> glCtx.frontMaterial.setAmbient(params);
case GL11.GL_DIFFUSE -> glCtx.frontMaterial.setDiffuse(params);
case GL11.GL_SPECULAR -> glCtx.frontMaterial.setSpecular(params);
case GL11.GL_EMISSION -> glCtx.frontMaterial.setEmission(params);
case GL11.GL_SHININESS -> glCtx.frontMaterial.setShininess(params);
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
final boolean a = glCtx.frontMaterial.setAmbient(params);
final boolean d = glCtx.frontMaterial.setDiffuse(params);
yield a || d;
}
case GL11.GL_COLOR_INDEXES -> glCtx.frontMaterial.setColorIndexes(params);
default -> false;
};
}
private static boolean glMaterialBack(int pname, FloatBuffer params) {
final GLContextState glCtx = ctx();
mod(glCtx.backMaterial);
return switch (pname) {
case GL11.GL_AMBIENT -> glCtx.backMaterial.setAmbient(params);
case GL11.GL_DIFFUSE -> glCtx.backMaterial.setDiffuse(params);
case GL11.GL_SPECULAR -> glCtx.backMaterial.setSpecular(params);
case GL11.GL_EMISSION -> glCtx.backMaterial.setEmission(params);
case GL11.GL_SHININESS -> glCtx.backMaterial.setShininess(params);
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
final boolean a = glCtx.backMaterial.setAmbient(params);
final boolean d = glCtx.backMaterial.setDiffuse(params);
yield a || d;
}
case GL11.GL_COLOR_INDEXES -> glCtx.backMaterial.setColorIndexes(params);
default -> false;
};
}
private static boolean glMaterialFront(int pname, IntBuffer params) {
final GLContextState glCtx = ctx();
mod(glCtx.frontMaterial);
return switch (pname) {
case GL11.GL_AMBIENT -> glCtx.frontMaterial.setAmbient(params);
case GL11.GL_DIFFUSE -> glCtx.frontMaterial.setDiffuse(params);
case GL11.GL_SPECULAR -> glCtx.frontMaterial.setSpecular(params);
case GL11.GL_EMISSION -> glCtx.frontMaterial.setEmission(params);
case GL11.GL_SHININESS -> glCtx.frontMaterial.setShininess(params);
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
final boolean a = glCtx.frontMaterial.setAmbient(params);
final boolean d = glCtx.frontMaterial.setDiffuse(params);
yield a || d;
}
case GL11.GL_COLOR_INDEXES -> glCtx.frontMaterial.setColorIndexes(params);
default -> false;
};
}
private static boolean glMaterialBack(int pname, IntBuffer params) {
final GLContextState glCtx = ctx();
mod(glCtx.backMaterial);
return switch (pname) {
case GL11.GL_AMBIENT -> glCtx.backMaterial.setAmbient(params);
case GL11.GL_DIFFUSE -> glCtx.backMaterial.setDiffuse(params);
case GL11.GL_SPECULAR -> glCtx.backMaterial.setSpecular(params);
case GL11.GL_EMISSION -> glCtx.backMaterial.setEmission(params);
case GL11.GL_SHININESS -> glCtx.backMaterial.setShininess(params);
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
final boolean a = glCtx.backMaterial.setAmbient(params);
final boolean d = glCtx.backMaterial.setDiffuse(params);
yield a || d;
}
case GL11.GL_COLOR_INDEXES -> glCtx.backMaterial.setColorIndexes(params);
default -> false;
};
}
public static void glMaterial(int face, int pname, FloatBuffer params) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.material(face, pname);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordMaterial(face, pname, params);
if (mode == RecordMode.COMPILE) {
return;
}
}
boolean changed = false;
if (face == GL11.GL_FRONT) {
changed = glMaterialFront(pname, params);
} else if (face == GL11.GL_BACK) {
changed = glMaterialBack(pname, params);
} else if (face == GL11.GL_FRONT_AND_BACK) {
final boolean f = glMaterialFront(pname, params);
final boolean b = glMaterialBack(pname, params);
changed = f || b;
} else {
throw new RuntimeException("Unsupported face value for glMaterial: " + face);
}
if (changed) glCtx.lightingGeneration++;
}
public static void glMaterial(int face, int pname, IntBuffer params) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.material(face, pname);
// For IntBuffer version, we need to convert to float for recording
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
// Convert int params to float for recording
final float[] floatParams = new float[params.remaining()];
params.mark();
for (int i = 0; i < floatParams.length; i++) {
floatParams[i] = i2f(params.get());
}
params.reset();
DisplayListManager.recordMaterial(face, pname, FloatBuffer.wrap(floatParams));
if (mode == RecordMode.COMPILE) {
return;
}
}
boolean changed = false;
if (face == GL11.GL_FRONT) {
changed = glMaterialFront(pname, params);
} else if (face == GL11.GL_BACK) {
changed = glMaterialBack(pname, params);
} else if (face == GL11.GL_FRONT_AND_BACK) {
final boolean f = glMaterialFront(pname, params);
final boolean b = glMaterialBack(pname, params);
changed = f || b;
} else {
throw new RuntimeException("Unsupported face value for glMaterial: " + face);
}
if (changed) glCtx.lightingGeneration++;
}
public static void glMaterialf(int face, int pname, float val) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordMaterialf(face, pname, val);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (pname != GL11.GL_SHININESS) {
// it is only valid to call glMaterialf for the GL_SHININESS parameter
return;
}
boolean changed = false;
if (face == GL11.GL_FRONT) {
mod(glCtx.frontMaterial);
changed = glCtx.frontMaterial.setShininess(val);
} else if (face == GL11.GL_BACK) {
mod(glCtx.backMaterial);
changed = glCtx.backMaterial.setShininess(val);
} else if (face == GL11.GL_FRONT_AND_BACK) {
mod(glCtx.frontMaterial);
mod(glCtx.backMaterial);
final boolean f = glCtx.frontMaterial.setShininess(val);
final boolean b = glCtx.backMaterial.setShininess(val);
changed = f || b;
} else {
throw new RuntimeException("Unsupported face value for glMaterial: " + face);
}
if (changed) glCtx.lightingGeneration++;
}
public static void glMateriali(int face, int pname, int val) {
// This will end up no-opping if pname != GL_SHININESS, it is invalid to call this with another pname
// Command recording happens in glMaterialf
glMaterialf(face, pname, (float) val);
}
public static void glLight(int light, int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLight(light, pname, params);
if (mode == RecordMode.COMPILE) {
return;
}
}
final LightStateStack lightState = glCtx.lightDataStates[light - GL11.GL_LIGHT0];
mod(lightState);
final boolean changed = switch (pname) {
case GL11.GL_AMBIENT -> lightState.setAmbient(params);
case GL11.GL_DIFFUSE -> lightState.setDiffuse(params);
case GL11.GL_SPECULAR -> lightState.setSpecular(params);
case GL11.GL_POSITION -> lightState.setPosition(params);
case GL11.GL_SPOT_DIRECTION -> lightState.setSpotDirection(params);
case GL11.GL_SPOT_EXPONENT -> lightState.setSpotExponent(params);
case GL11.GL_SPOT_CUTOFF -> lightState.setSpotCutoff(params);
case GL11.GL_CONSTANT_ATTENUATION -> lightState.setConstantAttenuation(params);
case GL11.GL_LINEAR_ATTENUATION -> lightState.setLinearAttenuation(params);
case GL11.GL_QUADRATIC_ATTENUATION -> lightState.setQuadraticAttenuation(params);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
public static void glLight(int light, int pname, IntBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
// For IntBuffer version, we need to convert to float for recording
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
// Convert int params to float for recording
final float[] floatParams = new float[params.remaining()];
params.mark();
for (int i = 0; i < floatParams.length; i++) {
floatParams[i] = i2f(params.get());
}
params.reset();
DisplayListManager.recordLight(light, pname, FloatBuffer.wrap(floatParams));
if (mode == RecordMode.COMPILE) {
return;
}
}
final LightStateStack lightState = glCtx.lightDataStates[light - GL11.GL_LIGHT0];
mod(lightState);
final boolean changed = switch (pname) {
case GL11.GL_AMBIENT -> lightState.setAmbient(params);
case GL11.GL_DIFFUSE -> lightState.setDiffuse(params);
case GL11.GL_SPECULAR -> lightState.setSpecular(params);
case GL11.GL_POSITION -> lightState.setPosition(params);
case GL11.GL_SPOT_DIRECTION -> lightState.setSpotDirection(params);
case GL11.GL_SPOT_EXPONENT -> lightState.setSpotExponent(params);
case GL11.GL_SPOT_CUTOFF -> lightState.setSpotCutoff(params);
case GL11.GL_CONSTANT_ATTENUATION -> lightState.setConstantAttenuation(params);
case GL11.GL_LINEAR_ATTENUATION -> lightState.setLinearAttenuation(params);
case GL11.GL_QUADRATIC_ATTENUATION -> lightState.setQuadraticAttenuation(params);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
public static void glLightf(int light, int pname, float param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLightf(light, pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
final LightStateStack lightState = glCtx.lightDataStates[light - GL11.GL_LIGHT0];
mod(lightState);
final boolean changed = switch (pname) {
case GL11.GL_SPOT_EXPONENT -> lightState.setSpotExponent(param);
case GL11.GL_SPOT_CUTOFF -> lightState.setSpotCutoff(param);
case GL11.GL_CONSTANT_ATTENUATION -> lightState.setConstantAttenuation(param);
case GL11.GL_LINEAR_ATTENUATION -> lightState.setLinearAttenuation(param);
case GL11.GL_QUADRATIC_ATTENUATION -> lightState.setQuadraticAttenuation(param);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
public static void glLighti(int light, int pname, int param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLighti(light, pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
final LightStateStack lightState = glCtx.lightDataStates[light - GL11.GL_LIGHT0];
mod(lightState);
final boolean changed = switch (pname) {
case GL11.GL_SPOT_EXPONENT -> lightState.setSpotExponent(param);
case GL11.GL_SPOT_CUTOFF -> lightState.setSpotCutoff(param);
case GL11.GL_CONSTANT_ATTENUATION -> lightState.setConstantAttenuation(param);
case GL11.GL_LINEAR_ATTENUATION -> lightState.setLinearAttenuation(param);
case GL11.GL_QUADRATIC_ATTENUATION -> lightState.setQuadraticAttenuation(param);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
public static void glLightModel(int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLightModel(pname, params);
if (mode == RecordMode.COMPILE) {
return;
}
}
mod(glCtx.lightModel);
final boolean changed = switch (pname) {
case GL11.GL_LIGHT_MODEL_AMBIENT -> glCtx.lightModel.setAmbient(params);
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> glCtx.lightModel.setLocalViewer(params);
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> glCtx.lightModel.setTwoSide(params);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
public static void glLightModel(int pname, IntBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
// For IntBuffer version, we need to convert to float for recording
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
// Convert int params to float for recording
final float[] floatParams = new float[params.remaining()];
params.mark();
for (int i = 0; i < floatParams.length; i++) {
floatParams[i] = i2f(params.get());
}
params.reset();
DisplayListManager.recordLightModel(pname, FloatBuffer.wrap(floatParams));
if (mode == RecordMode.COMPILE) {
return;
}
}
mod(glCtx.lightModel);
final boolean changed = switch (pname) {
case GL11.GL_LIGHT_MODEL_AMBIENT -> glCtx.lightModel.setAmbient(params);
case GL12.GL_LIGHT_MODEL_COLOR_CONTROL -> glCtx.lightModel.setColorControl(params);
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> glCtx.lightModel.setLocalViewer(params);
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> glCtx.lightModel.setTwoSide(params);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
public static void glLightModelf(int pname, float param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLightModelf(pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (isCachingEnabled()) {
mod(glCtx.lightModel);
final boolean changed = switch (pname) {
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> glCtx.lightModel.setLocalViewer(param);
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> glCtx.lightModel.setTwoSide(param);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
}
public static void glLightModeli(int pname, int param) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLightModeli(pname, param);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (isCachingEnabled()) {
mod(glCtx.lightModel);
final boolean changed = switch (pname) {
case GL12.GL_LIGHT_MODEL_COLOR_CONTROL -> glCtx.lightModel.setColorControl(param);
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> glCtx.lightModel.setLocalViewer(param);
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> glCtx.lightModel.setTwoSide(param);
default -> false;
};
if (changed) glCtx.lightingGeneration++;
}
}
public static void glColorMaterial(int face, int mode) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.COLOR_MATERIAL_SETTINGS);
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
DisplayListManager.recordColorMaterial(face, mode);
if (recordMode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.colorMaterialFace.getValue() != face || glCtx.colorMaterialParameter.getValue() != mode) {
mod(glCtx.colorMaterialFace).setValue(face);
mod(glCtx.colorMaterialParameter).setValue(mode);
glCtx.lightingGeneration++;
}
}
public static int getLightingGeneration() {
return ctx().lightingGeneration;
}
public static BooleanStateStack getLightingState() {
return ctx().lightingState;
}
public static BooleanStateStack getRescaleNormalState() {
return ctx().rescaleNormalState;
}
public static BooleanStateStack getNormalizeState() {
return ctx().normalizeState;
}
public static BooleanStateStack[] getLightStates() {
return ctx().lightStates;
}
public static LightStateStack[] getLightDataStates() {
return ctx().lightDataStates;
}
public static BooleanStateStack getColorMaterial() {
return ctx().colorMaterial;
}
public static IntegerStateStack getColorMaterialFace() {
return ctx().colorMaterialFace;
}
public static IntegerStateStack getColorMaterialParameter() {
return ctx().colorMaterialParameter;
}
public static LightModelStateStack getLightModel() {
return ctx().lightModel;
}
public static MaterialStateStack getFrontMaterial() {
return ctx().frontMaterial;
}
public static MaterialStateStack getBackMaterial() {
return ctx().backMaterial;
}
public static void captureLighting(LightingSnapshot out) {
final GLContextState glCtx = ctx();
for (int i = 0; i < out.lights.length; i++) {
out.lightEnabled[i] = glCtx.lightStates[i].isEnabled();
out.lights[i].set(glCtx.lightDataStates[i]);
}
out.lightModel.set(glCtx.lightModel);
out.frontMaterial.set(glCtx.frontMaterial);
out.backMaterial.set(glCtx.backMaterial);
out.colorMaterial = glCtx.colorMaterial.isEnabled();
out.colorMaterialFace = glCtx.colorMaterialFace.getValue();
out.colorMaterialParameter = glCtx.colorMaterialParameter.getValue();
out.normalize = glCtx.normalizeState.isEnabled();
out.rescaleNormal = glCtx.rescaleNormalState.isEnabled();
}
public static void applyLighting(LightingSnapshot in) {
rejectExitCapture();
final GLContextState glCtx = ctx();
boolean changed = false;
for (int i = 0; i < in.lights.length; i++) {
glCtx.lightStates[i].setEnabled(in.lightEnabled[i]);
if (!glCtx.lightDataStates[i].sameAs(in.lights[i])) {
mod(glCtx.lightDataStates[i]).set(in.lights[i]);
changed = true;
}
}
if (!glCtx.lightModel.sameAs(in.lightModel)) {
mod(glCtx.lightModel).set(in.lightModel);
changed = true;
}
if (!glCtx.frontMaterial.sameAs(in.frontMaterial)) {
mod(glCtx.frontMaterial).set(in.frontMaterial);
changed = true;
}
if (!glCtx.backMaterial.sameAs(in.backMaterial)) {
mod(glCtx.backMaterial).set(in.backMaterial);
changed = true;
}
if (glCtx.colorMaterialFace.getValue() != in.colorMaterialFace || glCtx.colorMaterialParameter.getValue() != in.colorMaterialParameter) {
mod(glCtx.colorMaterialFace).setValue(in.colorMaterialFace);
mod(glCtx.colorMaterialParameter).setValue(in.colorMaterialParameter);
changed = true;
}
// Direct set: glEnable(GL_COLOR_MATERIAL) would bake the current color over the captured material.
glCtx.colorMaterial.setEnabled(in.colorMaterial);
glCtx.normalizeState.setEnabled(in.normalize);
glCtx.rescaleNormalState.setEnabled(in.rescaleNormal);
if (changed) glCtx.lightingGeneration++;
}
}
@@ -0,0 +1,504 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.stacks.MatrixModeStack;
import lombok.SneakyThrows;
import org.joml.Matrix4f;
import org.joml.Matrix4fStack;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.LOGGER;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.initConfig;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
public final class GLSMMatrices {
private GLSMMatrices() {}
private static void beforeMatrixChange(GLContextState c) {
beforeMatrixChange(c, false);
}
private static void beforeMatrixChange(GLContextState c, boolean absolute) {
c.exitCapture.matrixChange(absolute);
if (isUncapturedMatrix(c)) beforeUncapturedStateChange();
}
private static boolean isUncapturedMatrix(GLContextState c) {
final int mode = c.matrixMode.getMode();
return mode == GL11.GL_PROJECTION || (mode == GL11.GL_TEXTURE && c.activeTextureUnit.getValue() != 0);
}
private static final MethodHandle MAT4_STACK_CURR_DEPTH;
static {
try {
final Field curr = Matrix4fStack.class.getDeclaredField("curr");
curr.setAccessible(true);
MAT4_STACK_CURR_DEPTH = MethodHandles.lookup().unreflectGetter(curr);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@SneakyThrows
public static int getMatrixStackDepth(Matrix4fStack stack) {
// JOML's curr is 0-based (0 = no pushes), but OpenGL starts at 1 (base matrix counts)
return (int) MAT4_STACK_CURR_DEPTH.invokeExact(stack) + 1;
}
public static void glMatrixMode(int mode) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.MATRIX_MODE);
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
DisplayListManager.recordMatrixMode(mode);
if (recordMode == RecordMode.COMPILE) {
return;
}
}
mod(glCtx.matrixMode).setMode(mode);
}
public static void glLoadMatrix(FloatBuffer m) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx, true);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
final Matrix4f matrix = new Matrix4f().set(m);
m.rewind();
DisplayListManager.recordLoadMatrix(matrix);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (isCachingEnabled()) {
matrixStack(glCtx).set(m);
bumpMatrixGeneration(glCtx);
}
}
public static void glLoadMatrix(DoubleBuffer m) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx, true);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
// Convert double buffer to float buffer for recording
glCtx.conversionMatrix4d.set(m);
m.rewind();
final Matrix4f floatMatrix = new Matrix4f();
floatMatrix.set(glCtx.conversionMatrix4d);
DisplayListManager.recordLoadMatrix(floatMatrix);
if (mode == RecordMode.COMPILE) {
return;
}
}
if (isCachingEnabled()) {
glCtx.conversionMatrix4d.set(m);
matrixStack(glCtx).set(glCtx.conversionMatrix4d);
bumpMatrixGeneration(glCtx);
}
}
public static void setModelViewMatrix(Matrix4fc m) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.matrixChange(GL11.GL_MODELVIEW, 0, true);
if (isCachingEnabled()) {
glCtx.modelViewMatrix.set(m);
glCtx.mvGeneration++;
glCtx.mvLinearGeneration++;
}
}
public static void setTextureMatrix(int unit, Matrix4fc m) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.matrixChange(GL11.GL_TEXTURE, unit, true);
if (unit != 0) beforeUncapturedStateChange();
if (isCachingEnabled()) {
glCtx.textures.getTextureUnitMatrix(unit).set(m);
glCtx.texMatrixGeneration++;
}
}
public static void setProjectionMatrix(Matrix4fc m) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (isCachingEnabled()) {
glCtx.projectionMatrix.set(m);
glCtx.projGeneration++;
}
}
public static Matrix4fStack getMatrixStack() {
return matrixStack(ctx());
}
private static Matrix4fStack matrixStack(GLContextState glCtx) {
switch (glCtx.matrixMode.getMode()) {
case GL11.GL_MODELVIEW -> {
return glCtx.modelViewMatrix;
}
case GL11.GL_PROJECTION -> {
return glCtx.projectionMatrix;
}
case GL11.GL_TEXTURE -> {
return glCtx.textures.getTextureUnitMatrix(glCtx.activeTextureUnit.getValue());
}
default -> throw new IllegalStateException("Unknown matrix mode: " + glCtx.matrixMode.getMode());
}
}
/** Bump the generation counter for the currently active matrix mode. */
private static void bumpMatrixGeneration(GLContextState glCtx) {
bumpMatrixGeneration(glCtx, true);
}
private static void bumpMatrixGeneration(GLContextState glCtx, boolean linearChanged) {
switch (glCtx.matrixMode.getMode()) {
case GL11.GL_MODELVIEW -> {
glCtx.mvGeneration++;
if (linearChanged) glCtx.mvLinearGeneration++;
}
case GL11.GL_PROJECTION -> glCtx.projGeneration++;
case GL11.GL_TEXTURE -> glCtx.texMatrixGeneration++;
}
}
public static void glLoadIdentity() {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx, true);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLoadIdentity();
if (mode == RecordMode.COMPILE) {
return;
}
}
if (isCachingEnabled()) {
matrixStack(glCtx).identity();
bumpMatrixGeneration(glCtx);
}
}
public static void glTranslatef(float x, float y, float z) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (DisplayListManager.isRecording()) {
DisplayListManager.applyMatrixTranslation(x, y, z);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).translate(x, y, z);
bumpMatrixGeneration(glCtx, false);
}
}
public static void glTranslated(double x, double y, double z) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (DisplayListManager.isRecording()) {
DisplayListManager.applyMatrixTranslation((float) x, (float) y, (float) z);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).translate((float) x, (float) y, (float) z);
bumpMatrixGeneration(glCtx, false);
}
}
public static void glScalef(float x, float y, float z) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (DisplayListManager.isRecording()) {
DisplayListManager.applyMatrixScale(x, y, z);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).scale(x, y, z);
bumpMatrixGeneration(glCtx);
}
}
public static void glScaled(double x, double y, double z) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (DisplayListManager.isRecording()) {
DisplayListManager.applyMatrixScale((float) x, (float) y, (float) z);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).scale((float) x, (float) y, (float) z);
bumpMatrixGeneration(glCtx);
}
}
public static void glMultMatrix(FloatBuffer floatBuffer) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
glCtx.multMatrix.set(floatBuffer);
final int currentMode = glCtx.matrixMode.getMode();
if (DisplayListManager.isRecording()) {
DisplayListManager.updateRelativeTransform(glCtx.multMatrix);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).mul(glCtx.multMatrix);
bumpMatrixGeneration(glCtx);
}
}
public static void applyMultMatrix(Matrix4f multMatrix) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (isCachingEnabled()) {
matrixStack(glCtx).mul(multMatrix);
bumpMatrixGeneration(glCtx);
}
}
public static void glMultMatrix(DoubleBuffer matrix) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
glCtx.conversionMatrix4d.set(matrix);
glCtx.conversionMatrix4f.set(glCtx.conversionMatrix4d);
if (DisplayListManager.isRecording()) {
DisplayListManager.updateRelativeTransform(glCtx.conversionMatrix4f);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).mul(glCtx.conversionMatrix4f);
bumpMatrixGeneration(glCtx);
}
}
public static void glRotatef(float angle, float x, float y, float z) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
final float lenSq = x * x + y * y + z * z;
if (lenSq == 0.0f) return;
// Fast way to normalize rotation
final float scalar = 1.0f / (float) Math.sqrt(lenSq);
x *= scalar;
y *= scalar;
z *= scalar;
// Convert deg to rad
angle = (float) Math.toRadians(angle);
if (DisplayListManager.isRecording()) {
DisplayListManager.applyMatrixRotation(angle, x, y, z);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).rotate(angle, x, y, z);
bumpMatrixGeneration(glCtx);
}
}
public static void glRotated(double angle, double x, double y, double z) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
final double lenSq = x * x + y * y + z * z;
if (lenSq == 0.0) return;
// Fast way to normalize rotation
final double scalar = 1.0 / Math.sqrt(lenSq);
x *= scalar;
y *= scalar;
z *= scalar;
// Convert deg to rad
angle = Math.toRadians(angle);
if (DisplayListManager.isRecording()) {
DisplayListManager.applyMatrixRotation((float) angle, (float) x, (float) y, (float) z);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).rotate((float) angle, (float) x, (float) y, (float) z);
bumpMatrixGeneration(glCtx);
}
}
public static void glOrtho(double left, double right, double bottom, double top, double zNear, double zFar) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (DisplayListManager.isRecording()) {
DisplayListManager.updateRelativeTransformOrtho(left, right, bottom, top, zNear, zFar);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).ortho((float) left, (float) right, (float) bottom, (float) top, (float) zNear, (float) zFar);
bumpMatrixGeneration(glCtx);
}
}
public static void glFrustum(double left, double right, double bottom, double top, double zNear, double zFar) {
final GLContextState glCtx = ctx();
beforeMatrixChange(glCtx);
if (DisplayListManager.isRecording()) {
DisplayListManager.updateRelativeTransformFrustum(left, right, bottom, top, zNear, zFar);
return;
}
if (isCachingEnabled()) {
matrixStack(glCtx).frustum((float) left, (float) right, (float) bottom, (float) top, (float) zNear, (float) zFar);
bumpMatrixGeneration(glCtx);
}
}
public static void glPushMatrix() {
final GLContextState glCtx = ctx();
glCtx.exitCapture.pushMatrix();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPushMatrix(); // Handles flush + relativeTransform stack
if (mode == RecordMode.COMPILE) {
return;
}
}
// Only track stack on main thread (splash thread has separate GL context)
if (isCachingEnabled()) {
try {
matrixStack(glCtx).pushMatrix();
} catch (IllegalStateException ignored) {
glCtx.exitCapture.reject();
if (initConfig != null && initConfig.isLwjglDebug()) LOGGER.warn("Matrix stack overflow ", new Throwable());
}
}
}
public static void glPopMatrix() {
final GLContextState glCtx = ctx();
glCtx.exitCapture.popMatrix();
if (isUncapturedMatrix(glCtx)) beforeUncapturedStateChange();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPopMatrix(); // Handles flush + relativeTransform stack + lastRecordedTransform sync
if (mode == RecordMode.COMPILE) {
return;
}
}
// Only track stack on main thread (splash thread has separate GL context)
if (isCachingEnabled()) {
try {
matrixStack(glCtx).popMatrix();
bumpMatrixGeneration(glCtx);
} catch (IllegalStateException ignored) {
glCtx.exitCapture.reject();
if (initConfig != null && initConfig.isLwjglDebug()) LOGGER.warn("Matrix stack underflow ", new Throwable());
}
}
}
public static void gluPerspective(float fovy, float aspect, float zNear, float zFar) {
final GLContextState glCtx = ctx();
glCtx.gluMatrix.identity().perspective((float) Math.toRadians(fovy), aspect, zNear, zFar);
glCtx.gluMatrix.get(0, glCtx.gluBuffer);
glMultMatrix(glCtx.gluBuffer);
}
public static void gluLookAt(float eyex, float eyey, float eyez, float centerx, float centery, float centerz, float upx, float upy, float upz) {
final GLContextState glCtx = ctx();
glCtx.gluMatrix.identity().lookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
glCtx.gluMatrix.get(0, glCtx.gluBuffer);
glMultMatrix(glCtx.gluBuffer);
}
public static void gluOrtho2D(float left, float right, float bottom, float top) {
glOrtho(left, right, bottom, top, -1.0, 1.0);
}
public static void gluPickMatrix(float x, float y, float deltaX, float deltaY, IntBuffer viewport) {
rejectExitCapture();
if (deltaX <= 0 || deltaY <= 0) return;
glTranslatef(
(viewport.get(viewport.position() + 2) - 2 * (x - viewport.get(viewport.position() + 0))) / deltaX,
(viewport.get(viewport.position() + 3) - 2 * (y - viewport.get(viewport.position() + 1))) / deltaY,
0);
glScalef(viewport.get(viewport.position() + 2) / deltaX, viewport.get(viewport.position() + 3) / deltaY, 1.0f);
}
public static int gluBuild2DMipmaps(int target, int components, int width, int height, int format, int type, ByteBuffer data) {
if (width < 1 || height < 1) return GLU.GLU_INVALID_VALUE;
GLSMTextures.glTexImage2D(target, 0, components, width, height, 0, format, type, data);
GLSMTextures.glGenerateMipmap(target);
return 0;
}
public static String gluErrorString(int errorCode) {
return switch (errorCode) {
case GLU.GLU_INVALID_ENUM -> "Invalid enum (glu)";
case GLU.GLU_INVALID_VALUE -> "Invalid value (glu)";
case GLU.GLU_OUT_OF_MEMORY -> "Out of memory (glu)";
case GL11.GL_NO_ERROR -> "No error";
case GL11.GL_INVALID_ENUM -> "Invalid enum";
case GL11.GL_INVALID_VALUE -> "Invalid value";
case GL11.GL_INVALID_OPERATION -> "Invalid operation";
case GL11.GL_OUT_OF_MEMORY -> "Out of memory";
default -> "Unknown error: " + errorCode;
};
}
public static boolean gluUnProject(float winx, float winy, float winz, FloatBuffer modelMatrix, FloatBuffer projMatrix, IntBuffer viewport, FloatBuffer obj_pos) {
final GLContextState glCtx = ctx();
glCtx.gluMatrix.set(projMatrix).mul(glCtx.gluMatrix2.set(modelMatrix));
if (Math.abs(glCtx.gluMatrix.determinant()) < 1.0e-10f) return false;
glCtx.gluMatrix.invert(glCtx.gluMatrix);
float ndcX = (winx - viewport.get(viewport.position())) / viewport.get(viewport.position() + 2) * 2.0f - 1.0f;
float ndcY = (winy - viewport.get(viewport.position() + 1)) / viewport.get(viewport.position() + 3) * 2.0f - 1.0f;
float ndcZ = winz * 2.0f - 1.0f;
glCtx.gluVec4.set(ndcX, ndcY, ndcZ, 1.0f);
glCtx.gluMatrix.transform(glCtx.gluVec4);
if (glCtx.gluVec4.w == 0.0f) return false;
float invW = 1.0f / glCtx.gluVec4.w;
obj_pos.put(obj_pos.position(), glCtx.gluVec4.x * invW);
obj_pos.put(obj_pos.position() + 1, glCtx.gluVec4.y * invW);
obj_pos.put(obj_pos.position() + 2, glCtx.gluVec4.z * invW);
return true;
}
public static int getMvGeneration() {
return ctx().mvGeneration;
}
public static int getMvLinearGeneration() {
return ctx().mvLinearGeneration;
}
public static int getProjGeneration() {
return ctx().projGeneration;
}
public static int getTexMatrixGeneration() {
return ctx().texMatrixGeneration;
}
public static MatrixModeStack getMatrixMode() {
return ctx().matrixMode;
}
public static Matrix4fStack getModelViewMatrix() {
return ctx().modelViewMatrix;
}
public static Matrix4fStack getProjectionMatrix() {
return ctx().projectionMatrix;
}
}
@@ -0,0 +1,613 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizon.gtnhlib.bytebuf.Pointer;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.ffp.Instancing;
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
import com.gtnewhorizons.angelica.glsm.ffp.ShaderManager;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
import com.gtnewhorizons.angelica.glsm.shader.ProgramBinaryCache;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.IntegerStateStack;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import lombok.Getter;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.KHRDebug;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.charset.StandardCharsets;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.LOGGER;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.initConfig;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.requireContext;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.warnOnce;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMPrograms {
private GLSMPrograms() {}
public static long programSwitches;
private static final String TEXTURE = "texture";
private static final String TEXTURE_RENAMED = "gtexture";
public static void setFfpInstancing(Instancing mode) {
ctx().ffpInstancing = mode;
}
public static void glUseProgram(int program) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordUseProgram(program);
if (mode == RecordMode.COMPILE) {
return;
}
}
final ShaderManager ffp = glCtx.ffp;
if (program == 0 && ffp.isEnabled()) {
final int prev = glCtx.activeProgram;
final boolean changed = prev != 0;
if (changed) glCtx.programGeneration++;
glCtx.activeProgram = 0; // Track that FFP was requested
if (changed && GLSMHooks.PROGRAM_CHANGE.hasListeners()) {
GLSMHooks.programChangeEvent.previousProgram = prev;
GLSMHooks.programChangeEvent.newProgram = 0;
GLSMHooks.programChangeEvent.postBind = false;
GLSMHooks.PROGRAM_CHANGE.post(GLSMHooks.programChangeEvent);
}
ffp.activate();
if (changed && GLSMHooks.PROGRAM_CHANGE.hasListeners()) {
GLSMHooks.programChangeEvent.previousProgram = prev;
GLSMHooks.programChangeEvent.newProgram = 0;
GLSMHooks.programChangeEvent.postBind = true;
GLSMHooks.PROGRAM_CHANGE.post(GLSMHooks.programChangeEvent);
}
return;
}
// Non-zero program or FFP emulation not enabled
if (program == 0) {
warnOnce("useprogram-zero-ffp-disabled",
"[FFP] glUseProgram(0) reached the driver because emulation is disabled");
}
if (ffp.isActive()) {
ffp.deactivate();
}
final boolean caching = isCachingEnabled();
if (!caching || program != glCtx.activeProgram) {
if (Tracy.ENABLED) programSwitches++;
glCtx.programGeneration++;
final int prev = glCtx.activeProgram;
glCtx.activeProgram = program;
if (GLSMHooks.PROGRAM_CHANGE.hasListeners()) {
GLSMHooks.programChangeEvent.previousProgram = prev;
GLSMHooks.programChangeEvent.newProgram = program;
GLSMHooks.programChangeEvent.postBind = false;
GLSMHooks.PROGRAM_CHANGE.post(GLSMHooks.programChangeEvent);
}
if (initConfig != null && initConfig.isLwjglDebug()) {
final String programName = GLDebug.getObjectLabel(KHRDebug.GL_PROGRAM, program);
GLDebug.debugMessage("Activating Program - " + program + ":" + programName);
}
RENDER_BACKEND.useProgram(program);
if (GLSMHooks.PROGRAM_CHANGE.hasListeners()) {
GLSMHooks.programChangeEvent.previousProgram = prev;
GLSMHooks.programChangeEvent.newProgram = program;
GLSMHooks.programChangeEvent.postBind = true;
GLSMHooks.PROGRAM_CHANGE.post(GLSMHooks.programChangeEvent);
}
}
}
public static void glShaderSource(int shader, CharSequence source) {
rejectExitCapture();
String src = source.toString();
// Always rename reserved words for the target GLSL version (e.g. 'sampler' at 460)
src = GlslTransformUtils.renameReservedWords(src, RENDER_BACKEND.getMinGLSLVersion());
if (ShaderManager.isEnabled()) {
final int shaderType = RENDER_BACKEND.getShaderi(shader, GL20.GL_SHADER_TYPE);
src = CompatShaderTransformer.transform(src, shaderType, shaderType == GL20.GL_FRAGMENT_SHADER);
}
RENDER_BACKEND.shaderSource(shader, src);
}
public static void nglShaderSource(int shader, int count, long strings, long lengths) {
rejectExitCapture();
if (count <= 0) return;
final CharSequence source;
if (count == 1) {
source = decodeShaderSourceString(strings, lengths, 0);
} else {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) sb.append(decodeShaderSourceString(strings, lengths, i));
source = sb.toString();
}
glShaderSource(shader, source);
}
private static String decodeShaderSourceString(long strings, long lengths, int i) {
final long strAddr = MemoryUtilities.memGetAddress(strings + (long) i * Pointer.POINTER_SIZE);
final int len = lengths == MemoryUtilities.NULL ? -1 : MemoryUtilities.memGetInt(lengths + (long) i * 4);
return len < 0 ? MemoryUtilities.memUTF8(strAddr) : MemoryUtilities.memUTF8(strAddr, len);
}
public static void glShaderSource(int shader, ByteBuffer source) {
final byte[] bytes = new byte[source.remaining()];
final int pos = source.position();
source.get(bytes);
source.position(pos);
glShaderSource(shader, new String(bytes, StandardCharsets.UTF_8));
}
public static void glShaderSource(int shader, CharSequence[] sources) {
int totalLen = 0;
for (CharSequence s : sources) totalLen += s.length();
final StringBuilder sb = new StringBuilder(totalLen);
for (CharSequence s : sources) sb.append(s);
glShaderSource(shader, sb.toString());
}
public static void glSpecializeShader(int shader, CharSequence entryPoint, IntBuffer constantIndex, IntBuffer constantValue) {
rejectExitCapture();
RENDER_BACKEND.specializeShader(shader, entryPoint, constantIndex, constantValue);
}
public static int glGetUniformBlockIndex(int program, CharSequence name) { rejectExitCapture(); return RENDER_BACKEND.getUniformBlockIndex(program, name); }
public static void glUniformBlockBinding(int program, int blockIndex, int binding) { rejectExitCapture(); RENDER_BACKEND.uniformBlockBinding(program, blockIndex, binding); }
public static void glBindFragDataLocation(int program, int colorNumber, CharSequence name) { rejectExitCapture(); RENDER_BACKEND.bindFragDataLocation(program, colorNumber, name); }
public static void glUniform3(int location, float[] values) { rejectExitCapture(); RENDER_BACKEND.uniform3fv(location, values); }
public static void glUniform4(int location, float[] values) { rejectExitCapture(); RENDER_BACKEND.uniform4fv(location, values); }
public static void glLinkProgram(int program) {
rejectExitCapture();
if (ShaderManager.isEnabled()) {
generateVertexShaderIfNeeded(program);
}
if (ProgramBinaryCache.isEnabled()) {
ProgramBinaryCache.markRetrievable(program);
}
RENDER_BACKEND.linkProgram(program);
if (ShaderManager.isEnabled() && RENDER_BACKEND.getProgrami(program, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
LOGGER.warn("Program {} failed to link: {}", program, RENDER_BACKEND.getProgramInfoLog(program));
}
CompatUniformManager.onLinkProgram(program);
}
public static void glProgramParameteri(int program, int pname, int value) {
rejectExitCapture();
RENDER_BACKEND.programParameteri(program, pname, value);
}
public static void glGetProgramBinary(int program, IntBuffer length, IntBuffer binaryFormat, ByteBuffer binary) {
rejectExitCapture();
RENDER_BACKEND.getProgramBinary(program, length, binaryFormat, binary);
}
public static void glProgramBinary(int program, int binaryFormat, ByteBuffer binary) {
rejectExitCapture();
RENDER_BACKEND.programBinary(program, binaryFormat, binary);
if (RENDER_BACKEND.getProgrami(program, GL20.GL_LINK_STATUS) == GL11.GL_TRUE) {
CompatUniformManager.onLinkProgram(program);
}
}
/**
* If a program has a fragment shader but no vertex shader, generate a passthrough vertex shader from the fragment's in declarations and attach it.
*/
private static void generateVertexShaderIfNeeded(int program) {
final GLContextState glCtx = ctx();
final int shaderCount = RENDER_BACKEND.getProgrami(program, GL20.GL_ATTACHED_SHADERS);
if (shaderCount == 0 || shaderCount > glCtx.shaderBuf.capacity()) return;
glCtx.shaderBuf.clear().limit(shaderCount);
RENDER_BACKEND.getAttachedShaders(program, null, glCtx.shaderBuf);
int fragmentShader = 0;
boolean hasVertex = false;
for (int i = 0; i < shaderCount; i++) {
final int shader = glCtx.shaderBuf.get(i);
final int type = RENDER_BACKEND.getShaderi(shader, GL20.GL_SHADER_TYPE);
if (type == GL20.GL_VERTEX_SHADER) {
hasVertex = true;
break;
} else if (type == GL20.GL_FRAGMENT_SHADER) {
fragmentShader = shader;
}
}
if (hasVertex || fragmentShader == 0) return;
// Fragment-only program - generate a passthrough vertex shader
final String fragSource = RENDER_BACKEND.getShaderSource(fragmentShader, 65536);
String vertSource = CompatShaderTransformer.generatePassthroughVertexShader(fragSource);
if (RenderSystem.isGLES()) {
vertSource = CompatShaderTransformer.toGLES(vertSource, GL20.GL_VERTEX_SHADER, false);
}
final int vertShader = RENDER_BACKEND.createShader(GL20.GL_VERTEX_SHADER);
RENDER_BACKEND.shaderSource(vertShader, vertSource);
RENDER_BACKEND.compileShader(vertShader);
if (RENDER_BACKEND.getShaderi(vertShader, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
final String log = RENDER_BACKEND.getShaderInfoLog(vertShader, 8192);
LOGGER.warn("CompatShaderTransformer: Generated passthrough vertex shader failed to compile:\n{}\nSource:\n{}", log, vertSource);
RENDER_BACKEND.deleteShader(vertShader);
return;
}
LOGGER.debug("CompatShaderTransformer: Generated passthrough vertex shader for fragment-only program {}", program);
RENDER_BACKEND.attachShader(program, vertShader);
RENDER_BACKEND.deleteShader(vertShader);
}
@Getter
static long programLifetimeGeneration;
private static final IntOpenHashSet programsPendingDeletion = new IntOpenHashSet();
public static boolean isProgramPendingDeletion(int program) {
return programsPendingDeletion.contains(program);
}
public static void glDeleteProgram(int program) {
rejectExitCapture();
if (program == 0) return;
CompatUniformManager.onDeleteProgram(program);
// GL defers deletion of a bound program until unbind; activeProgram stays set so the
// cache matches GL_CURRENT_PROGRAM and the next glUseProgram is not skipped as redundant.
if (GLSMHooks.PROGRAM_DELETE.hasListeners()) {
GLSMHooks.programDeleteEvent.program = program;
GLSMHooks.PROGRAM_DELETE.post(GLSMHooks.programDeleteEvent);
}
RENDER_BACKEND.deleteProgram(program);
programsPendingDeletion.add(program);
programsPendingDeletion.removeIf((int id) -> !RENDER_BACKEND.isProgram(id));
programLifetimeGeneration++;
}
public static int glCreateShader(int type) {
requireContext("glCreateShader");
return RENDER_BACKEND.createShader(type);
}
public static void glCompileShader(int shader) {
rejectExitCapture();
RENDER_BACKEND.compileShader(shader);
}
public static int glCreateProgram() {
requireContext("glCreateProgram");
final int program = RENDER_BACKEND.createProgram();
programsPendingDeletion.remove(program);
programLifetimeGeneration++;
return program;
}
public static void glAttachShader(int program, int shader) {
rejectExitCapture();
RENDER_BACKEND.attachShader(program, shader);
}
public static void glDetachShader(int program, int shader) {
rejectExitCapture();
RENDER_BACKEND.detachShader(program, shader);
}
public static void glDeleteShader(int shader) {
rejectExitCapture();
RENDER_BACKEND.deleteShader(shader);
}
public static void glBindAttribLocation(int program, int index, CharSequence name) {
rejectExitCapture();
RENDER_BACKEND.bindAttribLocation(program, index, name);
}
public static void glValidateProgram(int program) {
rejectExitCapture();
RENDER_BACKEND.validateProgram(program);
}
public static int glGetShaderi(int shader, int pname) {
rejectExitCapture();
return RENDER_BACKEND.getShaderi(shader, pname);
}
public static String glGetShaderInfoLog(int shader, int maxLength) {
rejectExitCapture();
return RENDER_BACKEND.getShaderInfoLog(shader, maxLength);
}
public static String glGetShaderInfoLog(int shader) {
rejectExitCapture();
return RENDER_BACKEND.getShaderInfoLog(shader);
}
public static int glGetProgrami(int program, int pname) {
rejectExitCapture();
return RENDER_BACKEND.getProgrami(program, pname);
}
public static String glGetProgramInfoLog(int program, int maxLength) {
rejectExitCapture();
return RENDER_BACKEND.getProgramInfoLog(program, maxLength);
}
public static String glGetProgramInfoLog(int program) {
rejectExitCapture();
return RENDER_BACKEND.getProgramInfoLog(program);
}
public static boolean glIsProgram(int obj) {
rejectExitCapture();
final boolean valid = RENDER_BACKEND.isProgram(obj);
if (!valid) programsPendingDeletion.remove(obj);
return valid;
}
public static boolean glIsShader(int obj) {
rejectExitCapture();
return RENDER_BACKEND.isShader(obj);
}
public static void glDispatchCompute(int x, int y, int z) { rejectExitCapture(); RENDER_BACKEND.dispatchCompute(x, y, z); }
public static int glGetUniformLocation(int program, CharSequence name) {
rejectExitCapture();
int loc = RENDER_BACKEND.getUniformLocation(program, name);
if (loc == -1 && TEXTURE.contentEquals(name)) {
loc = RENDER_BACKEND.getUniformLocation(program, TEXTURE_RENAMED);
}
return loc;
}
public static int glGetUniformLocation(int program, ByteBuffer name) {
rejectExitCapture();
int loc = RENDER_BACKEND.getUniformLocation(program, name);
if (loc == -1 && isTextureBuffer(name)) {
loc = RENDER_BACKEND.getUniformLocation(program, TEXTURE_RENAMED);
}
return loc;
}
public static int glGetAttribLocation(int program, CharSequence name) {
rejectExitCapture();
int loc = RENDER_BACKEND.getAttribLocation(program, name);
if (loc == -1 && TEXTURE.contentEquals(name)) {
loc = RENDER_BACKEND.getAttribLocation(program, TEXTURE_RENAMED);
}
return loc;
}
public static int glGetAttribLocation(int program, ByteBuffer name) {
rejectExitCapture();
int loc = RENDER_BACKEND.getAttribLocation(program, name);
if (loc == -1 && isTextureBuffer(name)) {
loc = RENDER_BACKEND.getAttribLocation(program, TEXTURE_RENAMED);
}
return loc;
}
private static final ByteBuffer TEXTURE_BYTES = ByteBuffer.wrap(TEXTURE.getBytes(StandardCharsets.US_ASCII));
private static boolean isTextureBuffer(ByteBuffer buf) {
final int len = buf.remaining();
if (len != 7 && len != 8) return false;
// I believe the driver accepts null terminated or not
if (len == 8 && buf.get(buf.position() + 7) != 0) return false;
return buf.slice(buf.position(), 7).equals(TEXTURE_BYTES);
}
public static void glDeleteObjectARB(int obj) {
rejectExitCapture();
if (RENDER_BACKEND.isShader(obj)) {
RENDER_BACKEND.deleteShader(obj);
} else {
glDeleteProgram(obj);
}
}
public static int glGetHandleARB(int pname) {
rejectExitCapture();
return pname == ARBShaderObjects.GL_PROGRAM_OBJECT_ARB ? GLSMQueries.glGetInteger(GL20.GL_CURRENT_PROGRAM) : RENDER_BACKEND.getInteger(pname);
}
public static void glGetObjectParameterARB(int obj, int pname, IntBuffer params) {
rejectExitCapture();
final var backend = RENDER_BACKEND;
if (backend.isShader(obj)) {
params.put(params.position(), backend.getShaderi(obj, pname));
} else {
backend.getProgramiv(obj, pname, params);
}
}
public static void glGetObjectParameterARB(int obj, int pname, FloatBuffer params) {
rejectExitCapture();
final var backend = RENDER_BACKEND;
params.put(params.position(), (float) (backend.isShader(obj) ? backend.getShaderi(obj, pname) : backend.getProgrami(obj, pname)));
}
public static int glGetObjectParameteriARB(int obj, int pname) {
rejectExitCapture();
final var backend = RENDER_BACKEND;
return backend.isShader(obj) ? backend.getShaderi(obj, pname) : backend.getProgrami(obj, pname);
}
public static String glGetInfoLogARB(int obj, int maxLength) {
rejectExitCapture();
final var backend = RENDER_BACKEND;
return backend.isShader(obj) ? backend.getShaderInfoLog(obj, maxLength) : backend.getProgramInfoLog(obj, maxLength);
}
public static void glGetInfoLogARB(int obj, IntBuffer length, ByteBuffer infoLog) {
rejectExitCapture();
final var backend = RENDER_BACKEND;
if (backend.isShader(obj)) {
backend.getShaderInfoLog(obj, length, infoLog);
} else {
backend.getProgramInfoLog(obj, length, infoLog);
}
}
public static void glUniform1f(int location, float v0) {
rejectExitCapture();
RENDER_BACKEND.uniform1f(location, v0);
}
public static void glUniform2f(int location, float v0, float v1) {
rejectExitCapture();
RENDER_BACKEND.uniform2f(location, v0, v1);
}
public static void glUniform3f(int location, float v0, float v1, float v2) {
rejectExitCapture();
RENDER_BACKEND.uniform3f(location, v0, v1, v2);
}
public static void glUniform4f(int location, float v0, float v1, float v2, float v3) {
rejectExitCapture();
RENDER_BACKEND.uniform4f(location, v0, v1, v2, v3);
}
public static void glUniform1i(int location, int v0) {
rejectExitCapture();
RENDER_BACKEND.uniform1i(location, v0);
}
public static void glUniform2i(int location, int v0, int v1) {
rejectExitCapture();
RENDER_BACKEND.uniform2i(location, v0, v1);
}
public static void glUniform3i(int location, int v0, int v1, int v2) {
rejectExitCapture();
RENDER_BACKEND.uniform3i(location, v0, v1, v2);
}
public static void glUniform4i(int location, int v0, int v1, int v2, int v3) {
rejectExitCapture();
RENDER_BACKEND.uniform4i(location, v0, v1, v2, v3);
}
public static void glUniform1(int location, FloatBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform1fv(location, values);
}
public static void glUniform1(int location, IntBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform1iv(location, values);
}
public static void glUniform2(int location, FloatBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform2(location, values);
}
public static void glUniform2(int location, IntBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform2iv(location, values);
}
public static void glUniform3(int location, FloatBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform3(location, values);
}
public static void glUniform3(int location, IntBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform3iv(location, values);
}
public static void glUniform4(int location, FloatBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform4(location, values);
}
public static void glUniform4(int location, IntBuffer values) {
rejectExitCapture();
RENDER_BACKEND.uniform4iv(location, values);
}
public static void glUniformMatrix2(int location, boolean transpose, FloatBuffer matrices) {
rejectExitCapture();
RENDER_BACKEND.uniformMatrix2(location, transpose, matrices);
}
public static void glUniformMatrix3(int location, boolean transpose, FloatBuffer matrices) {
rejectExitCapture();
RENDER_BACKEND.uniformMatrix3(location, transpose, matrices);
}
public static void glUniformMatrix4(int location, boolean transpose, FloatBuffer matrices) {
rejectExitCapture();
RENDER_BACKEND.uniformMatrix4(location, transpose, matrices);
}
public static void glGetActiveUniform(int program, int index, IntBuffer length, IntBuffer size, IntBuffer type, ByteBuffer name) {
rejectExitCapture();
RENDER_BACKEND.getActiveUniform(program, index, length, size, type, name);
}
public static void glGetActiveAttrib(int program, int index, IntBuffer length, IntBuffer size, IntBuffer type, ByteBuffer name) {
rejectExitCapture();
RENDER_BACKEND.getActiveAttrib(program, index, length, size, type, name);
}
public static String glGetActiveAttrib(int program, int index, int maxLength, IntBuffer sizeType) {
rejectExitCapture();
return RENDER_BACKEND.getActiveAttrib(program, index, maxLength, sizeType);
}
public static void glGetAttachedShaders(int program, IntBuffer count, IntBuffer shaders) {
rejectExitCapture();
RENDER_BACKEND.getAttachedShaders(program, count, shaders);
}
public static String glGetShaderSource(int shader, int maxLength) {
rejectExitCapture();
return RENDER_BACKEND.getShaderSource(shader, maxLength);
}
public static void glGetShaderSource(int shader, IntBuffer length, ByteBuffer source) {
rejectExitCapture();
RENDER_BACKEND.getShaderSource(shader, length, source);
}
public static void glGetUniform(int program, int location, FloatBuffer params) {
rejectExitCapture();
RENDER_BACKEND.getUniformfv(program, location, params);
}
public static void glGetUniform(int program, int location, IntBuffer params) {
rejectExitCapture();
RENDER_BACKEND.getUniformiv(program, location, params);
}
public static int getProgramGeneration() {
return ctx().programGeneration;
}
public static IntegerStateStack getProgramStack() {
return ctx().programStack;
}
public static BooleanStateStack getVertexProgramTwoSideState() {
return ctx().vertexProgramTwoSideState;
}
public static int getActiveProgram() {
return ctx().activeProgram;
}
}
@@ -0,0 +1,594 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.states.PolygonState;
import com.gtnewhorizons.angelica.glsm.states.ImageUnitBinding;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL21;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL33;
import org.lwjgl.opengl.GL42;
import org.lwjgl.opengl.GL43;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.HAS_MULTIPLE_SET;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_ATTRIB_STACK_DEPTH;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_CLIP_PLANES;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_LEGACY_TEXTURE_UNITS;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_MODELVIEW_STACK_DEPTH;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_PROJECTION_STACK_DEPTH;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_TEXTURE_COORDS;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_TEXTURE_STACK_DEPTH;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.initConfig;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.requireContext;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMQueries {
private GLSMQueries() {}
public static boolean glGetBoolean(int pname) {
rejectExitCapture();
return glGetBoolean(ctx(), pname);
}
static boolean glGetBoolean(GLContextState glCtx, int pname) {
if (!isCachingEnabled()) {
return RENDER_BACKEND.getBoolean(pname);
}
// Handle clip planes dynamically (supports up to MAX_CLIP_PLANES)
if (pname >= GL11.GL_CLIP_PLANE0 && pname < GL11.GL_CLIP_PLANE0 + MAX_CLIP_PLANES) {
return glCtx.clipPlaneStates[pname - GL11.GL_CLIP_PLANE0].isEnabled();
}
return switch (pname) {
case GL11.GL_ALPHA_TEST -> glCtx.alphaTest.isEnabled();
case GL11.GL_AUTO_NORMAL -> glCtx.autoNormalState.isEnabled();
case GL11.GL_BLEND -> glCtx.blendMode.isEnabled();
case GL11.GL_COLOR_MATERIAL -> glCtx.colorMaterial.isEnabled();
case GL11.GL_COLOR_LOGIC_OP -> glCtx.colorLogicOpState.isEnabled();
case GL14.GL_COLOR_SUM -> glCtx.colorSumState.isEnabled();
case GL11.GL_CULL_FACE -> glCtx.cullState.isEnabled();
case GL11.GL_DEPTH_TEST -> glCtx.depthTest.isEnabled();
case GL11.GL_DEPTH_WRITEMASK -> glCtx.depthState.isEnabled();
case GL11.GL_DITHER -> glCtx.ditherState.isEnabled();
case GL11.GL_FOG -> glCtx.fogMode.isEnabled();
case GL11.GL_INDEX_LOGIC_OP -> glCtx.indexLogicOpState.isEnabled();
case GL11.GL_LIGHTING -> glCtx.lightingState.isEnabled();
case GL11.GL_LIGHT0 -> glCtx.lightStates[0].isEnabled();
case GL11.GL_LIGHT1 -> glCtx.lightStates[1].isEnabled();
case GL11.GL_LIGHT2 -> glCtx.lightStates[2].isEnabled();
case GL11.GL_LIGHT3 -> glCtx.lightStates[3].isEnabled();
case GL11.GL_LIGHT4 -> glCtx.lightStates[4].isEnabled();
case GL11.GL_LIGHT5 -> glCtx.lightStates[5].isEnabled();
case GL11.GL_LIGHT6 -> glCtx.lightStates[6].isEnabled();
case GL11.GL_LIGHT7 -> glCtx.lightStates[7].isEnabled();
case GL11.GL_LINE_SMOOTH -> glCtx.lineSmoothState.isEnabled();
case GL11.GL_LINE_STIPPLE -> glCtx.lineStippleState.isEnabled();
case GL11.GL_MAP1_COLOR_4 -> glCtx.map1Color4State.isEnabled();
case GL11.GL_MAP1_INDEX -> glCtx.map1IndexState.isEnabled();
case GL11.GL_MAP1_NORMAL -> glCtx.map1NormalState.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_1 -> glCtx.map1TextureCoord1State.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_2 -> glCtx.map1TextureCoord2State.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_3 -> glCtx.map1TextureCoord3State.isEnabled();
case GL11.GL_MAP1_TEXTURE_COORD_4 -> glCtx.map1TextureCoord4State.isEnabled();
case GL11.GL_MAP1_VERTEX_3 -> glCtx.map1Vertex3State.isEnabled();
case GL11.GL_MAP1_VERTEX_4 -> glCtx.map1Vertex4State.isEnabled();
case GL11.GL_MAP2_COLOR_4 -> glCtx.map2Color4State.isEnabled();
case GL11.GL_MAP2_INDEX -> glCtx.map2IndexState.isEnabled();
case GL11.GL_MAP2_NORMAL -> glCtx.map2NormalState.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_1 -> glCtx.map2TextureCoord1State.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_2 -> glCtx.map2TextureCoord2State.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_3 -> glCtx.map2TextureCoord3State.isEnabled();
case GL11.GL_MAP2_TEXTURE_COORD_4 -> glCtx.map2TextureCoord4State.isEnabled();
case GL11.GL_MAP2_VERTEX_3 -> glCtx.map2Vertex3State.isEnabled();
case GL11.GL_MAP2_VERTEX_4 -> glCtx.map2Vertex4State.isEnabled();
case GL13.GL_MULTISAMPLE -> glCtx.multisampleState.isEnabled();
case GL11.GL_NORMALIZE -> glCtx.normalizeState.isEnabled();
case GL11.GL_POINT_SMOOTH -> glCtx.pointSmoothState.isEnabled();
case GL20.GL_POINT_SPRITE -> glCtx.pointSpriteState.isEnabled();
case GL20.GL_VERTEX_PROGRAM_TWO_SIDE -> glCtx.vertexProgramTwoSideState.isEnabled();
case GL11.GL_POLYGON_OFFSET_POINT -> glCtx.polygonOffsetPointState.isEnabled();
case GL11.GL_POLYGON_OFFSET_LINE -> glCtx.polygonOffsetLineState.isEnabled();
case GL11.GL_POLYGON_OFFSET_FILL -> glCtx.polygonOffsetFillState.isEnabled();
case GL11.GL_POLYGON_SMOOTH -> glCtx.polygonSmoothState.isEnabled();
case GL11.GL_POLYGON_STIPPLE -> glCtx.polygonStippleState.isEnabled();
case GL12.GL_RESCALE_NORMAL -> glCtx.rescaleNormalState.isEnabled();
case GL13.GL_SAMPLE_ALPHA_TO_COVERAGE -> glCtx.sampleAlphaToCoverageState.isEnabled();
case GL13.GL_SAMPLE_ALPHA_TO_ONE -> glCtx.sampleAlphaToOneState.isEnabled();
case GL13.GL_SAMPLE_COVERAGE -> glCtx.sampleCoverageState.isEnabled();
case GL30.GL_RASTERIZER_DISCARD -> glCtx.rasterizerDiscard.isEnabled();
case GL11.GL_SCISSOR_TEST -> glCtx.scissorTest.isEnabled();
case GL11.GL_STENCIL_TEST -> glCtx.stencilTest.isEnabled();
case GL11.GL_TEXTURE_1D -> glCtx.textures.getTexture1DStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_2D -> glCtx.textures.getTextureUnitStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL12.GL_TEXTURE_3D -> glCtx.textures.getTexture3DStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL13.GL_TEXTURE_CUBE_MAP -> glCtx.textures.getTextureCubeMapStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_S -> glCtx.textures.getTexGenSStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_T -> glCtx.textures.getTexGenTStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_R -> glCtx.textures.getTexGenRStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_TEXTURE_GEN_Q -> glCtx.textures.getTexGenQStates(glCtx.activeTextureUnit.getValue()).isEnabled();
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> glCtx.lightModel.localViewer != 0.0f;
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> glCtx.lightModel.twoSide != 0.0f;
case GL11.GL_EDGE_FLAG -> glCtx.edgeFlagState.isEnabled();
default -> {
final int conv = GLSMVertexInput.clientStateToConventional(glCtx, pname);
if (conv >= 0) yield glCtx.vaos.isConventionalEnabled(conv);
final int desc = LegacyQueries.desc(pname);
yield desc != 0 ? LegacyQueries.getBoolean(glCtx, pname, desc) : RENDER_BACKEND.getBoolean(pname);
}
};
}
public static void glGetBoolean(int pname, ByteBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) {
RENDER_BACKEND.getBoolean(pname, params);
return;
}
switch (pname) {
case GL11.GL_COLOR_WRITEMASK -> {
final int pos = params.position();
params.put(pos, (byte) (glCtx.colorMask.red ? GL11.GL_TRUE : GL11.GL_FALSE));
params.put(pos + 1, (byte) (glCtx.colorMask.green ? GL11.GL_TRUE : GL11.GL_FALSE));
params.put(pos + 2, (byte) (glCtx.colorMask.blue ? GL11.GL_TRUE : GL11.GL_FALSE));
params.put(pos + 3, (byte) (glCtx.colorMask.alpha ? GL11.GL_TRUE : GL11.GL_FALSE));
}
default -> {
if (!HAS_MULTIPLE_SET.contains(pname)) {
params.put(params.position(), (byte) (glGetBoolean(glCtx, pname) ? GL11.GL_TRUE : GL11.GL_FALSE));
} else if (!LegacyQueries.getBooleanv(glCtx, pname, params)) {
RENDER_BACKEND.getBoolean(pname, params);
}
}
}
}
public static int glGetInteger(int pname) {
rejectExitCapture();
return glGetInteger(ctx(), pname);
}
static int glGetInteger(GLContextState glCtx, int pname) {
if (!isCachingEnabled()) {
return RENDER_BACKEND.getInteger(pname);
}
return switch (pname) {
case GL11.GL_ALPHA_TEST_FUNC -> glCtx.alphaState.getFunction();
case GL11.GL_DEPTH_FUNC -> glCtx.depthState.getFunc();
case GL11.GL_LIST_BASE -> glCtx.listBase;
case GL11.GL_LIST_MODE -> DisplayListManager.getListMode();
case GL11.GL_MATRIX_MODE -> glCtx.matrixMode.getMode();
case GL11.GL_SHADE_MODEL -> glCtx.shadeModelState.getValue();
// GL_TEXTURE_2D makes no sense here, but some mod still queries it...
case GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_BINDING_2D -> GLSMTextures.getBoundTextureForServerState();
case GL13.GL_ACTIVE_TEXTURE -> GL13.GL_TEXTURE0 + GLSMTextures.getActiveTextureUnitForServerState();
case GL13.GL_CLIENT_ACTIVE_TEXTURE -> GL13.GL_TEXTURE0 + glCtx.clientActiveTextureUnit;
case GL11.GL_COLOR_MATERIAL_FACE -> glCtx.colorMaterialFace.getValue();
case GL11.GL_COLOR_MATERIAL_PARAMETER -> glCtx.colorMaterialParameter.getValue();
case GL11.GL_MODELVIEW_STACK_DEPTH -> GLSMMatrices.getMatrixStackDepth(glCtx.modelViewMatrix);
case GL11.GL_PROJECTION_STACK_DEPTH -> GLSMMatrices.getMatrixStackDepth(glCtx.projectionMatrix);
case GL11.GL_DEPTH_WRITEMASK -> glCtx.depthState.isEnabled() ? GL11.GL_TRUE : GL11.GL_FALSE;
case GL11.GL_CULL_FACE_MODE -> glCtx.polygonState.getCullFaceMode();
case GL11.GL_FRONT_FACE -> glCtx.polygonState.getFrontFace();
case GL11.GL_POLYGON_MODE -> glCtx.polygonState.getFrontMode();
case GL11.GL_UNPACK_ALIGNMENT -> glCtx.pixelUnpackState.alignment();
case GL11.GL_UNPACK_ROW_LENGTH -> glCtx.pixelUnpackState.rowLength();
case GL11.GL_UNPACK_SKIP_ROWS -> glCtx.pixelUnpackState.skipRows();
case GL11.GL_UNPACK_SKIP_PIXELS -> glCtx.pixelUnpackState.skipPixels();
case GL12.GL_LIGHT_MODEL_COLOR_CONTROL -> glCtx.lightModel.colorControl;
case GL14.GL_BLEND_DST_ALPHA -> glCtx.blendState.getDstAlpha();
case GL11.GL_BLEND_DST, GL14.GL_BLEND_DST_RGB -> glCtx.blendState.getDstRgb();
case GL14.GL_BLEND_SRC_ALPHA -> glCtx.blendState.getSrcAlpha();
case GL11.GL_BLEND_SRC, GL14.GL_BLEND_SRC_RGB -> glCtx.blendState.getSrcRgb();
case GL14.GL_BLEND_EQUATION -> glCtx.blendState.getEquationRgb();
case GL20.GL_BLEND_EQUATION_ALPHA -> glCtx.blendState.getEquationAlpha();
case GL11.GL_LOGIC_OP_MODE -> glCtx.logicOpMode.getValue();
case GL11.GL_DRAW_BUFFER -> glCtx.drawBuffer.getValue();
case GL11.GL_STENCIL_FUNC -> glCtx.stencilState.getFuncFront();
case GL11.GL_STENCIL_REF -> glCtx.stencilState.getRefFront();
case GL11.GL_STENCIL_VALUE_MASK -> glCtx.stencilState.getValueMaskFront();
case GL11.GL_STENCIL_FAIL -> glCtx.stencilState.getFailOpFront();
case GL11.GL_STENCIL_PASS_DEPTH_FAIL -> glCtx.stencilState.getZFailOpFront();
case GL11.GL_STENCIL_PASS_DEPTH_PASS -> glCtx.stencilState.getZPassOpFront();
case GL11.GL_STENCIL_WRITEMASK -> glCtx.stencilState.getWriteMaskFront();
case GL11.GL_STENCIL_CLEAR_VALUE -> glCtx.stencilState.getClearValue();
case GL15.GL_ARRAY_BUFFER_BINDING -> glCtx.boundVBO;
case GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING -> glCtx.vaos.boundEBO;
case GL21.GL_PIXEL_UNPACK_BUFFER_BINDING -> glCtx.boundPixelUnpackBuffer;
case GL21.GL_PIXEL_PACK_BUFFER_BINDING -> glCtx.boundPixelPackBuffer;
case GL20.GL_CURRENT_PROGRAM -> glCtx.activeProgram;
case GL30.GL_VERTEX_ARRAY_BINDING -> glCtx.boundVAO;
case GL30.GL_DRAW_FRAMEBUFFER_BINDING -> glCtx.drawFramebuffer;
case GL30.GL_READ_FRAMEBUFFER_BINDING -> glCtx.readFramebuffer;
case GL33.GL_SAMPLER_BINDING -> glCtx.samplerUnits.get(glCtx.activeTextureUnit.getValue());
default -> switch (pname) {
case GL11.GL_FOG_MODE -> glCtx.fogState.getFogMode();
case GL11.GL_LINE_STIPPLE_PATTERN -> glCtx.lineState.getStipplePattern() & 0xFFFF;
case GL11.GL_LINE_STIPPLE_REPEAT -> glCtx.lineState.getStippleFactor();
case GL11.GL_LIST_INDEX -> DisplayListManager.isRecording() ? Math.max(DisplayListManager.getRecordingListId(), 0) : 0;
case GL11.GL_ATTRIB_STACK_DEPTH -> glCtx.attribDepth;
case GL11.GL_CLIENT_ATTRIB_STACK_DEPTH -> glCtx.clientAttribStackPointer;
case GL11.GL_TEXTURE_STACK_DEPTH -> GLSMMatrices.getMatrixStackDepth(glCtx.textures.getTextureUnitMatrix(glCtx.activeTextureUnit.getValue()));
case GL11.GL_MAX_ATTRIB_STACK_DEPTH -> MAX_ATTRIB_STACK_DEPTH;
case GL11.GL_MAX_CLIENT_ATTRIB_STACK_DEPTH -> GLSMAttribStack.CLIENT_ATTRIB_STACK_DEPTH;
case GL11.GL_MAX_MODELVIEW_STACK_DEPTH -> MAX_MODELVIEW_STACK_DEPTH;
case GL11.GL_MAX_PROJECTION_STACK_DEPTH -> MAX_PROJECTION_STACK_DEPTH;
case GL11.GL_MAX_TEXTURE_STACK_DEPTH -> MAX_TEXTURE_STACK_DEPTH;
case GL13.GL_MAX_TEXTURE_UNITS -> MAX_LEGACY_TEXTURE_UNITS;
case GL11.GL_MAX_LIGHTS -> glCtx.lightStates.length;
case GL11.GL_STENCIL_BITS -> GLSMFramebuffer.drawFramebufferBits(glCtx, true);
case GL11.GL_DEPTH_BITS -> GLSMFramebuffer.drawFramebufferBits(glCtx, false);
case GL20.GL_MAX_TEXTURE_COORDS -> MAX_TEXTURE_COORDS;
case GL20.GL_POINT_SPRITE_COORD_ORIGIN -> glCtx.pointState.getSpriteCoordOrigin();
case GL11.GL_RENDER_MODE -> FeedbackManager.getRenderMode();
default -> {
final int shift = GLSMRasterizer.hintShift(pname);
if (shift >= 0) yield GLSMRasterizer.hintMode(glCtx.hintState.getValue(), shift);
final int key = GLSMVertexInput.clientArrayField(glCtx, pname);
if (key >= 0 && (key & ~0xFF) != GLSMVertexInput.FIELD_POINTER) yield GLSMVertexInput.clientArrayParam(glCtx, key);
final int desc = LegacyQueries.desc(pname);
yield desc != 0 ? LegacyQueries.getInteger(glCtx, pname, desc) : RENDER_BACKEND.getInteger(pname);
}
};
};
}
public static void glGetInteger(int pname, IntBuffer params) {
rejectExitCapture();
if (!isCachingEnabled()) {
RENDER_BACKEND.getInteger(pname, params);
return;
}
switch (pname) {
case GL11.GL_VIEWPORT -> ctx().viewportState.get(params);
case GL11.GL_SCISSOR_BOX -> ctx().scissorState.get(params);
case GL11.GL_POLYGON_MODE -> {
final PolygonState polygon = ctx().polygonState;
final int pos = params.position();
params.put(pos, polygon.getFrontMode());
params.put(pos + 1, polygon.getBackMode());
}
default -> {
final GLContextState glCtx = ctx();
if (!HAS_MULTIPLE_SET.contains(pname)) {
params.put(params.position(), glGetInteger(glCtx, pname));
} else if (!LegacyQueries.getIntegerv(glCtx, pname, params)) {
RENDER_BACKEND.getInteger(pname, params);
}
}
}
}
public static void glGetFloat(int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) {
RENDER_BACKEND.getFloat(pname, params);
return;
}
switch (pname) {
case GL11.GL_MODELVIEW_MATRIX -> glCtx.modelViewMatrix.get(params.position(), params);
case GL11.GL_PROJECTION_MATRIX -> glCtx.projectionMatrix.get(params.position(), params);
case GL11.GL_TEXTURE_MATRIX -> glCtx.textures.getTextureUnitMatrix(GLSMTextures.getActiveTextureUnit()).get(params.position(), params);
case GL11.GL_COLOR_CLEAR_VALUE -> glCtx.clearColor.get(params);
case GL11.GL_CURRENT_COLOR -> glCtx.color.get(params);
case GL14.GL_CURRENT_SECONDARY_COLOR -> glCtx.secondaryColor.get(params);
case GL11.GL_DEPTH_RANGE -> {
final int pos = params.position();
params.put(pos, (float) glCtx.viewportState.depthRangeNear);
params.put(pos + 1, (float) glCtx.viewportState.depthRangeFar);
}
case GL14.GL_BLEND_COLOR -> {
final int pos = params.position();
params.put(pos, glCtx.blendState.getBlendColorR());
params.put(pos + 1, glCtx.blendState.getBlendColorG());
params.put(pos + 2, glCtx.blendState.getBlendColorB());
params.put(pos + 3, glCtx.blendState.getBlendColorA());
}
case GL11.GL_CURRENT_NORMAL -> {
final Vector3f normal = glCtx.ffp.currentNormal;
final int pos = params.position();
params.put(pos, normal.x);
params.put(pos + 1, normal.y);
params.put(pos + 2, normal.z);
}
case GL11.GL_CURRENT_TEXTURE_COORDS -> {
final int unit = glCtx.activeTextureUnit.getValue();
final int pos = params.position();
if (unit == 1) {
params.put(pos, glCtx.lastBrightnessX);
params.put(pos + 1, glCtx.lastBrightnessY);
params.put(pos + 2, 0.0f);
params.put(pos + 3, 1.0f);
} else if (unit >= 0 && unit < glCtx.ffp.currentTexCoords.length) {
final Vector4f tc = glCtx.ffp.currentTexCoords[unit];
params.put(pos, tc.x);
params.put(pos + 1, tc.y);
params.put(pos + 2, tc.z);
params.put(pos + 3, tc.w);
} else {
params.put(pos, 0.0f);
params.put(pos + 1, 0.0f);
params.put(pos + 2, 0.0f);
params.put(pos + 3, 1.0f);
}
}
case GL11.GL_FOG_COLOR -> {
final FloatBuffer fogBuf = glCtx.fogState.getFogColorBuffer();
final int pos = params.position();
params.put(pos, fogBuf.get(0));
params.put(pos + 1, fogBuf.get(1));
params.put(pos + 2, fogBuf.get(2));
params.put(pos + 3, fogBuf.get(3));
}
case GL11.GL_LIGHT_MODEL_AMBIENT -> glCtx.lightModel.ambient.get(params.position(), params);
case GL14.GL_POINT_DISTANCE_ATTENUATION -> {
final int pos = params.position();
params.put(pos, glCtx.pointState.getAttenuationConstant());
params.put(pos + 1, glCtx.pointState.getAttenuationLinear());
params.put(pos + 2, glCtx.pointState.getAttenuationQuadratic());
}
default -> {
if (!HAS_MULTIPLE_SET.contains(pname)) {
params.put(params.position(), glGetFloat(glCtx, pname));
} else {
RENDER_BACKEND.getFloat(pname, params);
}
}
}
}
public static float glGetFloat(int pname) {
rejectExitCapture();
return glGetFloat(ctx(), pname);
}
static float glGetFloat(GLContextState glCtx, int pname) {
return switch (pname) {
case GL11.GL_ALPHA_TEST_REF -> glCtx.alphaState.getReference();
case GL11.GL_FOG_DENSITY -> glCtx.fogState.getDensity();
case GL11.GL_FOG_START -> glCtx.fogState.getStart();
case GL11.GL_FOG_END -> glCtx.fogState.getEnd();
case GL11.GL_DEPTH_CLEAR_VALUE -> (float) glCtx.depthState.getClearValue();
case GL11.GL_LINE_WIDTH -> glCtx.lineState.getWidth();
case GL11.GL_POINT_SIZE -> glCtx.pointState.getSize();
case GL14.GL_POINT_SIZE_MIN -> glCtx.pointState.getMinSize();
case GL14.GL_POINT_SIZE_MAX -> Float.isNaN(glCtx.pointState.getMaxSize()) ? GLSMRasterizer.maxPointSize : glCtx.pointState.getMaxSize();
case GL14.GL_POINT_FADE_THRESHOLD_SIZE -> glCtx.pointState.getFadeThreshold();
default -> {
final int desc = isCachingEnabled() ? LegacyQueries.desc(pname) : 0;
yield desc != 0 ? LegacyQueries.getFloat(glCtx, pname, desc) : RENDER_BACKEND.getFloat(pname);
}
};
}
public static void glGetFloat(int pname, float[] params) {
final FloatBuffer scratch = ctx().queryScratch;
final FloatBuffer buf;
if (params.length <= scratch.capacity()) {
buf = scratch;
buf.clear();
buf.limit(params.length);
} else {
buf = BufferUtils.createFloatBuffer(params.length);
}
glGetFloat(pname, buf);
buf.position(0);
buf.get(params);
}
public static double glGetDouble(int pname) {
rejectExitCapture();
return switch (pname) {
case GL11.GL_DEPTH_CLEAR_VALUE -> ctx().depthState.getClearValue();
default -> glGetFloat(pname);
};
}
public static void glGetDouble(int pname, DoubleBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) {
RENDER_BACKEND.getDouble(pname, params);
return;
}
final int pos = params.position();
switch (pname) {
case GL11.GL_DEPTH_CLEAR_VALUE -> params.put(pos, glCtx.depthState.getClearValue());
case GL11.GL_DEPTH_RANGE -> {
params.put(pos, glCtx.viewportState.depthRangeNear);
params.put(pos + 1, glCtx.viewportState.depthRangeFar);
}
case GL11.GL_MODELVIEW_MATRIX, GL11.GL_PROJECTION_MATRIX, GL11.GL_TEXTURE_MATRIX -> widenFromFloat(pname, params, 16);
case GL11.GL_COLOR_CLEAR_VALUE, GL11.GL_CURRENT_COLOR, GL11.GL_CURRENT_TEXTURE_COORDS, GL11.GL_FOG_COLOR,
GL11.GL_LIGHT_MODEL_AMBIENT, GL14.GL_BLEND_COLOR, GL14.GL_CURRENT_SECONDARY_COLOR -> widenFromFloat(pname, params, 4);
case GL11.GL_CURRENT_NORMAL, GL14.GL_POINT_DISTANCE_ATTENUATION -> widenFromFloat(pname, params, 3);
default -> {
if (!HAS_MULTIPLE_SET.contains(pname)) {
params.put(pos, glGetDouble(pname));
} else {
RENDER_BACKEND.getDouble(pname, params);
}
}
}
}
public static void glGetDouble(int pname, double[] params) {
final DoubleBuffer scratch = ctx().queryScratchDouble;
final DoubleBuffer buf;
if (params.length <= scratch.capacity()) {
buf = scratch;
buf.clear();
buf.limit(params.length);
} else {
buf = BufferUtils.createDoubleBuffer(params.length);
}
glGetDouble(pname, buf);
buf.position(0);
buf.get(params);
}
private static void widenFromFloat(int pname, DoubleBuffer params, int count) {
final FloatBuffer scratch = ctx().queryScratch;
scratch.clear();
glGetFloat(pname, scratch);
final int pos = params.position();
for (int i = 0; i < count; i++) {
params.put(pos + i, scratch.get(i));
}
}
public static int glGetError() {
rejectExitCapture();
if (!RENDER_BACKEND.hasContext()) return 0;
if (initConfig.isNoErrorChecks()) return 0;
return RENDER_BACKEND.getError();
}
public static void checkGLError() {
final int error = glGetError();
if (error != GL11.GL_NO_ERROR) GLErrorReporter.reportError(error);
}
public static String glGetString(int pname) {
rejectExitCapture();
if (!RENDER_BACKEND.hasContext()) return "no valid GL/render context";
return RENDER_BACKEND.getString(pname);
}
public static String glGetStringi(int name, int index) {
rejectExitCapture();
if (!RENDER_BACKEND.hasContext()) return "no valid GL/render context";
return RENDER_BACKEND.getStringi(name, index);
}
public static boolean glIsQuery(int query) { rejectExitCapture(); return RENDER_BACKEND.isQuery(query); }
public static void glGenQueries(IntBuffer ids) {
requireContext("glGenQueries");
RENDER_BACKEND.genQueries(ids);
}
public static int glGenQueries() {
requireContext("glGenQueries");
return RENDER_BACKEND.genQueries();
}
public static void glDeleteQueries(int id) { rejectExitCapture(); RENDER_BACKEND.deleteQueries(id); }
public static void glBeginQuery(int target, int id) { rejectExitCapture(); RENDER_BACKEND.beginQuery(target, id); }
public static void glEndQuery(int target) { rejectExitCapture(); RENDER_BACKEND.endQuery(target); }
public static void glGetQueryObjectui(int id, int pname, IntBuffer params) { rejectExitCapture(); RENDER_BACKEND.getQueryObjectui(id, pname, params); }
public static int glGetQueryObjecti(int id, int pname) { rejectExitCapture(); return RENDER_BACKEND.getQueryObjecti(id, pname); }
public static void glQueryCounter(int id, int target) { rejectExitCapture(); RENDER_BACKEND.queryCounter(id, target); }
public static long glGetQueryObjectui64(int id, int pname) { rejectExitCapture(); return RENDER_BACKEND.getQueryObjectui64(id, pname); }
public static void glGetInteger(int pname, int[] params) {
rejectExitCapture();
if (!isCachingEnabled() || params.length == 0) {
RENDER_BACKEND.getInteger(pname, params);
return;
}
switch (pname) {
case GL11.GL_VIEWPORT -> {
if (params.length < 4) {
RENDER_BACKEND.getInteger(pname, params);
} else {
ctx().viewportState.get(params);
}
}
case GL11.GL_SCISSOR_BOX -> {
if (params.length < 4) {
RENDER_BACKEND.getInteger(pname, params);
} else {
ctx().scissorState.get(params);
}
}
case GL11.GL_POLYGON_MODE -> {
final PolygonState polygon = ctx().polygonState;
params[0] = polygon.getFrontMode();
if (params.length > 1) params[1] = polygon.getBackMode();
}
default -> {
final GLContextState glCtx = ctx();
if (!HAS_MULTIPLE_SET.contains(pname)) {
params[0] = glGetInteger(glCtx, pname);
} else if (!LegacyQueries.getIntegerv(glCtx, pname, params)) {
RENDER_BACKEND.getInteger(pname, params);
}
}
}
}
private static int indexedIntegerOrBackend(int pname, int index) {
if (pname == GL31.GL_UNIFORM_BUFFER_BINDING) return GLSMBuffers.getIndexedBufferBinding(GL31.GL_UNIFORM_BUFFER, index);
if (pname == GL43.GL_SHADER_STORAGE_BUFFER_BINDING) return GLSMBuffers.getIndexedBufferBinding(GL43.GL_SHADER_STORAGE_BUFFER, index);
final ImageUnitBinding binding = !isCachingEnabled() ? null : ctx().imageUnits.get(index);
if (binding == null) return RENDER_BACKEND.getIntegerIndexed(pname, index);
return switch (pname) {
case GL42.GL_IMAGE_BINDING_NAME -> binding.getTexture();
case GL42.GL_IMAGE_BINDING_LEVEL -> binding.getLevel();
case GL42.GL_IMAGE_BINDING_LAYERED -> binding.isLayered() ? GL11.GL_TRUE : GL11.GL_FALSE;
case GL42.GL_IMAGE_BINDING_LAYER -> binding.getLayer();
case GL42.GL_IMAGE_BINDING_ACCESS -> binding.getAccess();
case GL42.GL_IMAGE_BINDING_FORMAT -> binding.getFormat();
default -> RENDER_BACKEND.getIntegerIndexed(pname, index);
};
}
public static int glGetInteger(int pname, int index) {
rejectExitCapture();
return indexedIntegerOrBackend(pname, index);
}
public static int glGetIntegeri(int pname, int index) {
rejectExitCapture();
return indexedIntegerOrBackend(pname, index);
}
public static void glGetIntegeri(int pname, int index, IntBuffer params) {
glGetIntegeri_v(pname, index, params);
}
public static void glGetIntegeri_v(int pname, int index, IntBuffer params) {
rejectExitCapture();
params.put(params.position(), indexedIntegerOrBackend(pname, index));
}
public static void glGetBooleani_v(int pname, int index, ByteBuffer params) {
rejectExitCapture();
params.put(params.position(), (byte) (indexedIntegerOrBackend(pname, index) != 0 ? GL11.GL_TRUE : GL11.GL_FALSE));
}
public static void glGetBooleani(int pname, int index, ByteBuffer params) {
glGetBooleani_v(pname, index, params);
}
}
@@ -0,0 +1,700 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.DisplayListManager.RecordMode;
import com.gtnewhorizons.angelica.glsm.stacks.BooleanStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.IntegerStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.LineStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.PointStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.PolygonStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.ScissorStateStack;
import com.gtnewhorizons.angelica.glsm.stacks.ViewPortStateStack;
import com.gtnewhorizons.angelica.glsm.states.ClipPlaneState;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL20;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.LOGGER;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.MAX_CLIP_PLANES;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.guardUnsupportedFFP;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.mod;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMRasterizer {
private GLSMRasterizer() {}
static float maxPointSize;
// Line width range queried at init from GL_ALIASED_LINE_WIDTH_RANGE
static float lineWidthMin = 1.0f;
static float lineWidthMax = 1.0f;
// The driver cannot draw wide lines (Mesa forward-compat, SDL_GPU), so FFP widens them from LineQuads in the vertex shader
public static boolean wideLineEmulationEnabled = false;
public static void glGetClipPlane(int plane, DoubleBuffer equation) {
rejectExitCapture();
final int index = plane - GL11.GL_CLIP_PLANE0;
if (index < 0 || index >= MAX_CLIP_PLANES) return;
ctx().clipPlaneState.getEyePlane(index, equation);
}
static void probeLineWidthRange() {
final FloatBuffer lwRange = BufferUtils.createFloatBuffer(16);
RENDER_BACKEND.getFloat(GL12.GL_ALIASED_LINE_WIDTH_RANGE, lwRange);
lineWidthMin = lwRange.get(0);
lineWidthMax = lwRange.get(1);
final float queriedMax = lineWidthMax;
// Probe whether the driver actually accepts the queried max (Mesa forward-compat rejects > 1.0)
if (lineWidthMax > 1.0f) {
while (RENDER_BACKEND.getError() != GL11.GL_NO_ERROR) {}
RENDER_BACKEND.lineWidth(lineWidthMax);
if (RENDER_BACKEND.getError() != GL11.GL_NO_ERROR) {
// Binary search for the actual accepted max between 1.0 and queriedMax
float lo = 1.0f, hi = queriedMax;
while (hi - lo > 0.01f) {
final float mid = (lo + hi) * 0.5f;
while (RENDER_BACKEND.getError() != GL11.GL_NO_ERROR) {}
RENDER_BACKEND.lineWidth(mid);
if (RENDER_BACKEND.getError() == GL11.GL_NO_ERROR) {
lo = mid;
} else {
hi = mid;
}
}
lineWidthMax = lo;
}
RENDER_BACKEND.lineWidth(1.0f);
while (RENDER_BACKEND.getError() != GL11.GL_NO_ERROR) {}
}
wideLineEmulationEnabled = lineWidthMax <= 1.0f;
if (wideLineEmulationEnabled) {
LOGGER.info("GL line width: aliased range [{}, {}], probe at {} rejected, native [{}, {}], line quads widen ({}, {}]", lineWidthMin, queriedMax, queriedMax, lineWidthMin, lineWidthMax, lineWidthMax, queriedMax);
} else {
LOGGER.info("GL line width: aliased range [{}, {}], probe at {} accepted, native [{}, {}]", lineWidthMin, queriedMax, queriedMax, lineWidthMin, lineWidthMax);
}
}
static void probePointSizeRange(GLContextState glCtx) {
final FloatBuffer range = glCtx.queryScratch;
range.clear();
RENDER_BACKEND.getFloat(GL11.GL_POINT_SIZE_RANGE, range);
final float smooth = range.get(1);
RENDER_BACKEND.getFloat(GL12.GL_ALIASED_POINT_SIZE_RANGE, range);
maxPointSize = Math.max(smooth, range.get(1));
}
public static void enableScissorTest() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_SCISSOR_TEST);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableScissorTest(ctx());
}
static void enableScissorTest(GLContextState glCtx) {
glCtx.scissorTest.enable();
}
public static void disableScissorTest() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_SCISSOR_TEST);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableScissorTest(ctx());
}
static void disableScissorTest(GLContextState glCtx) {
glCtx.scissorTest.disable();
}
public static void glPointParameterf(int pname, float param) {
pointParameter(pname, param, 0.0f, 0.0f);
}
public static void glPointParameteri(int pname, int param) {
pointParameter(pname, param, 0.0f, 0.0f);
}
public static void glPointParameter(int pname, FloatBuffer params) {
final int pos = params.position();
final boolean attenuation = pname == GL14.GL_POINT_DISTANCE_ATTENUATION;
pointParameter(pname, params.get(pos), attenuation ? params.get(pos + 1) : 0.0f, attenuation ? params.get(pos + 2) : 0.0f);
}
public static void glPointParameter(int pname, IntBuffer params) {
final int pos = params.position();
final boolean attenuation = pname == GL14.GL_POINT_DISTANCE_ATTENUATION;
pointParameter(pname, params.get(pos), attenuation ? params.get(pos + 1) : 0.0f, attenuation ? params.get(pos + 2) : 0.0f);
}
private static void pointParameter(int pname, float v0, float v1, float v2) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final PointStateStack point = glCtx.pointState;
switch (pname) {
case GL14.GL_POINT_SIZE_MIN -> {
if (!(v0 < 0.0f) && point.getMinSize() != v0) mod(point).setMinSize(v0);
}
case GL14.GL_POINT_SIZE_MAX -> {
if (!(v0 < 0.0f) && point.getMaxSize() != v0) mod(point).setMaxSize(v0);
}
case GL14.GL_POINT_FADE_THRESHOLD_SIZE -> {
if (!(v0 < 0.0f) && point.getFadeThreshold() != v0) {
mod(point).setFadeThreshold(v0);
RENDER_BACKEND.pointParameterf(pname, v0);
}
}
case GL14.GL_POINT_DISTANCE_ATTENUATION -> {
if (point.getAttenuationConstant() == v0 && point.getAttenuationLinear() == v1 && point.getAttenuationQuadratic() == v2) return;
mod(point);
point.setAttenuationConstant(v0);
point.setAttenuationLinear(v1);
point.setAttenuationQuadratic(v2);
}
case GL20.GL_POINT_SPRITE_COORD_ORIGIN -> {
final int origin = (int) v0;
if ((origin == GL20.GL_LOWER_LEFT || origin == GL20.GL_UPPER_LEFT) && point.getSpriteCoordOrigin() != origin) {
mod(point).setSpriteCoordOrigin(origin);
RENDER_BACKEND.pointParameteri(pname, origin);
}
}
default -> RENDER_BACKEND.pointParameterf(pname, v0);
}
}
static void applyPointState(GLContextState glCtx) {
final PointStateStack point = glCtx.pointState;
RENDER_BACKEND.pointSize(point.getSize());
RENDER_BACKEND.pointParameterf(GL14.GL_POINT_FADE_THRESHOLD_SIZE, point.getFadeThreshold());
RENDER_BACKEND.pointParameteri(GL20.GL_POINT_SPRITE_COORD_ORIGIN, point.getSpriteCoordOrigin());
}
private static boolean isLegacyHint(int target) {
return switch (target) {
case GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_POINT_SMOOTH_HINT, GL11.GL_FOG_HINT, GL14.GL_GENERATE_MIPMAP_HINT -> true;
default -> false;
};
}
static int hintShift(int target) {
return switch (target) {
case GL11.GL_PERSPECTIVE_CORRECTION_HINT -> 0;
case GL11.GL_POINT_SMOOTH_HINT -> 2;
case GL11.GL_LINE_SMOOTH_HINT -> 4;
case GL11.GL_POLYGON_SMOOTH_HINT -> 6;
case GL11.GL_FOG_HINT -> 8;
case GL13.GL_TEXTURE_COMPRESSION_HINT -> 10;
case GL14.GL_GENERATE_MIPMAP_HINT -> 12;
case GL20.GL_FRAGMENT_SHADER_DERIVATIVE_HINT -> 14;
default -> -1;
};
}
static int hintMode(int packed, int shift) {
return switch (packed >>> shift & 3) {
case 1 -> GL11.GL_FASTEST;
case 2 -> GL11.GL_NICEST;
default -> GL11.GL_DONT_CARE;
};
}
private static final int[] DRIVER_HINTS = {
GL11.GL_LINE_SMOOTH_HINT, GL11.GL_POLYGON_SMOOTH_HINT, GL13.GL_TEXTURE_COMPRESSION_HINT, GL20.GL_FRAGMENT_SHADER_DERIVATIVE_HINT
};
static void applyHintState(GLContextState glCtx) {
final int packed = glCtx.hintState.getValue();
for (final int target : DRIVER_HINTS) {
RENDER_BACKEND.hint(target, hintMode(packed, hintShift(target)));
}
}
public static void enableCull() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordEnable(GL11.GL_CULL_FACE);
if (mode == RecordMode.COMPILE) {
return;
}
}
enableCull(ctx());
}
static void enableCull(GLContextState glCtx) {
glCtx.cullState.enable();
}
public static void disableCull() {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordDisable(GL11.GL_CULL_FACE);
if (mode == RecordMode.COMPILE) {
return;
}
}
disableCull(ctx());
}
static void disableCull(GLContextState glCtx) {
glCtx.cullState.disable();
}
public static void glShadeModel(int mode) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.SHADE_MODEL);
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
DisplayListManager.recordShadeModel(mode);
if (recordMode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
final int oldValue = glCtx.shadeModelState.getValue();
final boolean needsUpdate = !caching || oldValue != mode;
if (needsUpdate) {
mod(glCtx.shadeModelState).setValue(mode);
}
}
public static void glViewport(int x, int y, int width, int height) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordViewport(x, y, width, height);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
RENDER_BACKEND.viewport(x, y, width, height);
// Only update cached state when caching is enabled
if (isCachingEnabled()) {
mod(ctx().viewportState).setViewPort(x, y, width, height);
}
}
public static void glLineWidth(float width) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLineWidth(width);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.lineState.getWidth() != width) {
mod(glCtx.lineState).setWidth(width);
RENDER_BACKEND.lineWidth(Math.clamp(width, lineWidthMin, lineWidthMax));
}
}
public static void glCullFace(int mode) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.CULL_FACE);
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
DisplayListManager.recordCullFace(mode);
if (recordMode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.polygonState.getCullFaceMode() != mode) {
mod(glCtx.polygonState).setCullFaceMode(mode);
RENDER_BACKEND.cullFace(mode);
}
}
public static void glFrontFace(int mode) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.FRONT_FACE);
final RecordMode recordMode = DisplayListManager.getRecordMode();
if (recordMode != RecordMode.NONE) {
DisplayListManager.recordFrontFace(mode);
if (recordMode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.polygonState.getFrontFace() != mode) {
mod(glCtx.polygonState).setFrontFace(mode);
RENDER_BACKEND.frontFace(mode);
}
}
public static void glHint(int target, int hint) {
rejectExitCapture();
if (hint != GL11.GL_NICEST && hint != GL11.GL_FASTEST && hint != GL11.GL_DONT_CARE) {
return;
}
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordHint(target, hint);
if (mode == RecordMode.COMPILE) {
return;
}
}
final int shift = hintShift(target);
if (shift >= 0) {
final IntegerStateStack hints = ctx().hintState;
final int code = hint == GL11.GL_FASTEST ? 1 : hint == GL11.GL_NICEST ? 2 : 0;
final int packed = hints.getValue() & ~(3 << shift) | code << shift;
if (packed != hints.getValue()) mod(hints).setValue(packed);
}
if (!isLegacyHint(target)) {
RENDER_BACKEND.hint(target, hint);
}
}
public static void glLineStipple(int factor, short pattern) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordLineStipple(factor, pattern);
if (mode == RecordMode.COMPILE) {
return;
}
}
mod(glCtx.lineState);
glCtx.lineState.setStippleFactor(factor);
glCtx.lineState.setStipplePattern(pattern);
}
public static void glPointSize(float size) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPointSize(size);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.pointState.getSize() != size) {
mod(glCtx.pointState).setSize(size);
RENDER_BACKEND.pointSize(size);
}
}
public static void glPolygonMode(int face, int polygonMode) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPolygonMode(face, polygonMode);
if (mode == RecordMode.COMPILE) {
return;
}
}
// Track front/back separately in cache (Mesa compat semantics), but always issue GL_FRONT_AND_BACK to the driver (core profile constraint).
final boolean caching = isCachingEnabled();
final boolean front = face != GL11.GL_BACK;
final boolean back = face != GL11.GL_FRONT;
final boolean needsUpdate = !caching
|| (front && glCtx.polygonState.getFrontMode() != polygonMode)
|| (back && glCtx.polygonState.getBackMode() != polygonMode);
if (!needsUpdate) return;
beforeUncapturedStateChange();
if (caching) {
mod(glCtx.polygonState);
if (front) glCtx.polygonState.setFrontMode(polygonMode);
if (back) glCtx.polygonState.setBackMode(polygonMode);
}
RENDER_BACKEND.polygonMode(GL11.GL_FRONT_AND_BACK, polygonMode);
}
public static void glPolygonOffset(float factor, float units) {
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.OFFSET_VALUES);
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordPolygonOffset(factor, units);
if (mode == RecordMode.COMPILE) {
return;
}
}
final boolean caching = isCachingEnabled();
if (!caching || glCtx.polygonState.getOffsetFactor() != factor || glCtx.polygonState.getOffsetUnits() != units || glCtx.polygonState.getOffsetClamp() != 0.0f) {
mod(glCtx.polygonState);
glCtx.polygonState.setOffsetFactor(factor);
glCtx.polygonState.setOffsetUnits(units);
glCtx.polygonState.setOffsetClamp(0.0f);
RENDER_BACKEND.polygonOffset(factor, units);
}
}
public static void glPolygonOffsetClamp(float factor, float units, float clamp) {
if (clamp == 0.0f) {
glPolygonOffset(factor, units);
return;
}
if (DisplayListManager.isRecording()) {
throw DisplayListManager.unsupportedInList("glPolygonOffsetClamp");
}
final GLContextState glCtx = ctx();
glCtx.exitCapture.write(ExitStateCapture.OFFSET_VALUES);
final boolean caching = isCachingEnabled();
if (!caching || glCtx.polygonState.getOffsetFactor() != factor || glCtx.polygonState.getOffsetUnits() != units || glCtx.polygonState.getOffsetClamp() != clamp) {
mod(glCtx.polygonState);
glCtx.polygonState.setOffsetFactor(factor);
glCtx.polygonState.setOffsetUnits(units);
glCtx.polygonState.setOffsetClamp(clamp);
RENDER_BACKEND.polygonOffsetClamp(factor, units, clamp);
}
}
public static void glScissor(int x, int y, int width, int height) {
final RecordMode mode = DisplayListManager.getRecordMode();
if (mode != RecordMode.NONE) {
DisplayListManager.recordScissor(x, y, width, height);
if (mode == RecordMode.COMPILE) {
return;
}
}
beforeUncapturedStateChange();
RENDER_BACKEND.scissor(x, y, width, height);
if (isCachingEnabled()) {
mod(ctx().scissorState).setScissor(x, y, width, height);
}
}
public static void glClipPlane(int plane, DoubleBuffer equation) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (DisplayListManager.isRecording()) {
final int pos = equation.position();
DisplayListManager.recordClipPlane(plane, equation.get(pos), equation.get(pos + 1), equation.get(pos + 2), equation.get(pos + 3));
return;
}
final int index = plane - GL11.GL_CLIP_PLANE0;
if (index < 0 || index >= MAX_CLIP_PLANES) return;
final int pos = equation.position();
beforeUncapturedStateChange();
glCtx.clipPlaneState.setPlane(index, equation.get(pos), equation.get(pos + 1), equation.get(pos + 2), equation.get(pos + 3), glCtx.modelViewMatrix);
glCtx.clipPlaneGeneration++;
}
/** Returns true if any GL_CLIP_PLANE0..7 is currently enabled. */
public static boolean anyClipPlaneEnabled() {
return anyClipPlaneEnabled(ctx());
}
public static boolean anyClipPlaneEnabled(GLContextState glCtx) {
return glCtx.clipPlaneEnabledMask != 0;
}
public static void glSampleCoverage(float value, boolean invert) {
if (DisplayListManager.isRecording()) {
throw DisplayListManager.unsupportedInList("glSampleCoverage");
}
beforeUncapturedStateChange();
RENDER_BACKEND.sampleCoverage(value, invert);
}
public static void glPolygonStipple(ByteBuffer pattern) {
guardUnsupportedFFP("glPolygonStipple", "glPolygonStipple is not available in GL 3.3 core profile.");
}
public static IntegerStateStack getShadeModelState() {
return ctx().shadeModelState;
}
public static BooleanStateStack getScissorTest() {
return ctx().scissorTest;
}
public static BooleanStateStack getCullState() {
return ctx().cullState;
}
public static BooleanStateStack getDitherState() {
return ctx().ditherState;
}
public static BooleanStateStack getLineSmoothState() {
return ctx().lineSmoothState;
}
public static BooleanStateStack getLineStippleState() {
return ctx().lineStippleState;
}
public static BooleanStateStack getPointSmoothState() {
return ctx().pointSmoothState;
}
public static BooleanStateStack getPolygonSmoothState() {
return ctx().polygonSmoothState;
}
public static BooleanStateStack getPolygonStippleState() {
return ctx().polygonStippleState;
}
public static BooleanStateStack getMultisampleState() {
return ctx().multisampleState;
}
public static BooleanStateStack getSampleAlphaToCoverageState() {
return ctx().sampleAlphaToCoverageState;
}
public static BooleanStateStack getSampleAlphaToOneState() {
return ctx().sampleAlphaToOneState;
}
public static BooleanStateStack getSampleCoverageState() {
return ctx().sampleCoverageState;
}
public static BooleanStateStack getPolygonOffsetPointState() {
return ctx().polygonOffsetPointState;
}
public static BooleanStateStack getPolygonOffsetLineState() {
return ctx().polygonOffsetLineState;
}
public static BooleanStateStack getPolygonOffsetFillState() {
return ctx().polygonOffsetFillState;
}
public static LineStateStack getLineState() {
return ctx().lineState;
}
public static PointStateStack getPointState() {
return ctx().pointState;
}
public static IntegerStateStack getHintState() {
return ctx().hintState;
}
public static BooleanStateStack getPointSpriteState() {
return ctx().pointSpriteState;
}
public static BooleanStateStack getEdgeFlagState() {
return ctx().edgeFlagState;
}
public static PolygonStateStack getPolygonState() {
return ctx().polygonState;
}
public static BooleanStateStack getAutoNormalState() {
return ctx().autoNormalState;
}
public static BooleanStateStack getMap1Color4State() {
return ctx().map1Color4State;
}
public static BooleanStateStack getMap1IndexState() {
return ctx().map1IndexState;
}
public static BooleanStateStack getMap1NormalState() {
return ctx().map1NormalState;
}
public static BooleanStateStack getMap1TextureCoord1State() {
return ctx().map1TextureCoord1State;
}
public static BooleanStateStack getMap1TextureCoord2State() {
return ctx().map1TextureCoord2State;
}
public static BooleanStateStack getMap1TextureCoord3State() {
return ctx().map1TextureCoord3State;
}
public static BooleanStateStack getMap1TextureCoord4State() {
return ctx().map1TextureCoord4State;
}
public static BooleanStateStack getMap1Vertex3State() {
return ctx().map1Vertex3State;
}
public static BooleanStateStack getMap1Vertex4State() {
return ctx().map1Vertex4State;
}
public static BooleanStateStack getMap2Color4State() {
return ctx().map2Color4State;
}
public static BooleanStateStack getMap2IndexState() {
return ctx().map2IndexState;
}
public static BooleanStateStack getMap2NormalState() {
return ctx().map2NormalState;
}
public static BooleanStateStack getMap2TextureCoord1State() {
return ctx().map2TextureCoord1State;
}
public static BooleanStateStack getMap2TextureCoord2State() {
return ctx().map2TextureCoord2State;
}
public static BooleanStateStack getMap2TextureCoord3State() {
return ctx().map2TextureCoord3State;
}
public static BooleanStateStack getMap2TextureCoord4State() {
return ctx().map2TextureCoord4State;
}
public static BooleanStateStack getMap2Vertex3State() {
return ctx().map2Vertex3State;
}
public static BooleanStateStack getMap2Vertex4State() {
return ctx().map2Vertex4State;
}
public static BooleanStateStack[] getClipPlaneStates() {
return ctx().clipPlaneStates;
}
public static ClipPlaneState getClipPlaneState() {
return ctx().clipPlaneState;
}
public static ViewPortStateStack getViewportState() {
return ctx().viewportState;
}
public static ScissorStateStack getScissorState() {
return ctx().scissorState;
}
}
@@ -0,0 +1,366 @@
package com.gtnewhorizons.angelica.glsm;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL14;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.beforeUncapturedStateChange;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.guardUnsupportedFFP;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.isCachingEnabled;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
public final class GLSMTexEnvGen {
private GLSMTexEnvGen() {}
public static void glTexEnvi(int target, int pname, int param) {
handleTexEnvScalar(target, pname, param);
}
public static void glTexEnvf(int target, int pname, float param) {
handleTexEnvScalar(target, pname, param);
}
public static void glTexEnv(int target, int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (target == GL11.GL_TEXTURE_ENV && pname == GL11.GL_TEXTURE_ENV_COLOR && params.remaining() >= 4) {
beforeUncapturedStateChange();
final int pos = params.position();
final var envState = glCtx.textures.getTexEnvState(glCtx.activeTextureUnit.getValue());
envState.beforeModify();
envState.envColorR = params.get(pos);
envState.envColorG = params.get(pos + 1);
envState.envColorB = params.get(pos + 2);
envState.envColorA = params.get(pos + 3);
glCtx.fragmentGeneration++;
return;
}
if (target == GL14.GL_TEXTURE_FILTER_CONTROL) {
guardUnsupportedFFP(
"glTexEnv",
"LOD bias via buffer glTexEnv is not supported; use glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, value) instead.");
return;
}
// Silently ignore other buffer glTexEnv calls (some mods pass combine params via buffers)
}
public static void glTexEnv(int target, int pname, IntBuffer params) {
rejectExitCapture();
if (target == GL11.GL_TEXTURE_ENV) {
handleTexEnvScalar(target, pname, (float) params.get(params.position()));
}
}
/**
* Scalar glTexEnvi/glTexEnvf dispatch. glTexEnv is removed in core profile. GL_TEXTURE_FILTER_CONTROL (LOD bias) is remapped to glTexParameterf. All
* GL_TEXTURE_ENV parameters including GL_COMBINE sub-params are tracked in per-unit TexEnvState.
*/
private static void handleTexEnvScalar(int target, int pname, float param) {
beforeUncapturedStateChange();
final GLContextState glCtx = ctx();
if (target == GL14.GL_TEXTURE_FILTER_CONTROL) {
// LOD bias via legacy glTexEnv path - remap to core-profile glTexParameterf
GLSMTextures.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, param);
return;
}
if (target != GL11.GL_TEXTURE_ENV) return;
final var envState = glCtx.textures.getTexEnvState(glCtx.activeTextureUnit.getValue());
envState.beforeModify();
final int iparam = (int) param;
switch (pname) {
case GL11.GL_TEXTURE_ENV_MODE -> {
envState.mode = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_COMBINE_RGB -> {
envState.combineRgb = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_COMBINE_ALPHA -> {
envState.combineAlpha = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_SOURCE0_RGB -> {
envState.sourceRgb[0] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_SOURCE1_RGB -> {
envState.sourceRgb[1] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_SOURCE2_RGB -> {
envState.sourceRgb[2] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_SOURCE0_ALPHA -> {
envState.sourceAlpha[0] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_SOURCE1_ALPHA -> {
envState.sourceAlpha[1] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_SOURCE2_ALPHA -> {
envState.sourceAlpha[2] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_OPERAND0_RGB -> {
envState.operandRgb[0] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_OPERAND1_RGB -> {
envState.operandRgb[1] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_OPERAND2_RGB -> {
envState.operandRgb[2] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_OPERAND0_ALPHA -> {
envState.operandAlpha[0] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_OPERAND1_ALPHA -> {
envState.operandAlpha[1] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_OPERAND2_ALPHA -> {
envState.operandAlpha[2] = iparam;
glCtx.fragmentGeneration++;
}
case GL13.GL_RGB_SCALE -> {
envState.scaleRgb = param;
glCtx.fragmentGeneration++;
}
case GL11.GL_ALPHA_SCALE -> {
envState.scaleAlpha = param;
glCtx.fragmentGeneration++;
}
// Silently ignore unknown pname - other mods may pass unrecognized params
}
}
public static float glGetTexEnvf(int target, int pname) {
return (float) glGetTexEnvi(target, pname);
}
public static int glGetTexEnvi(int target, int pname) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (target != GL11.GL_TEXTURE_ENV) return 0;
final var envState = glCtx.textures.getTexEnvState(glCtx.activeTextureUnit.getValue());
return switch (pname) {
case GL11.GL_TEXTURE_ENV_MODE -> envState.mode;
case GL13.GL_COMBINE_RGB -> envState.combineRgb;
case GL13.GL_COMBINE_ALPHA -> envState.combineAlpha;
case GL13.GL_SOURCE0_RGB -> envState.sourceRgb[0];
case GL13.GL_SOURCE1_RGB -> envState.sourceRgb[1];
case GL13.GL_SOURCE2_RGB -> envState.sourceRgb[2];
case GL13.GL_SOURCE0_ALPHA -> envState.sourceAlpha[0];
case GL13.GL_SOURCE1_ALPHA -> envState.sourceAlpha[1];
case GL13.GL_SOURCE2_ALPHA -> envState.sourceAlpha[2];
case GL13.GL_OPERAND0_RGB -> envState.operandRgb[0];
case GL13.GL_OPERAND1_RGB -> envState.operandRgb[1];
case GL13.GL_OPERAND2_RGB -> envState.operandRgb[2];
case GL13.GL_OPERAND0_ALPHA -> envState.operandAlpha[0];
case GL13.GL_OPERAND1_ALPHA -> envState.operandAlpha[1];
case GL13.GL_OPERAND2_ALPHA -> envState.operandAlpha[2];
case GL13.GL_RGB_SCALE -> (int) envState.scaleRgb;
case GL11.GL_ALPHA_SCALE -> (int) envState.scaleAlpha;
default -> 0;
};
}
public static void glGetTexEnv(int target, int pname, IntBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (target != GL11.GL_TEXTURE_ENV) return;
if (pname == GL11.GL_TEXTURE_ENV_COLOR) {
final var envState = glCtx.textures.getTexEnvState(glCtx.activeTextureUnit.getValue());
params.put(params.position(), (int) (envState.envColorR * 2147483647.0f));
params.put(params.position() + 1, (int) (envState.envColorG * 2147483647.0f));
params.put(params.position() + 2, (int) (envState.envColorB * 2147483647.0f));
params.put(params.position() + 3, (int) (envState.envColorA * 2147483647.0f));
} else {
params.put(params.position(), glGetTexEnvi(target, pname));
}
}
public static void glGetTexEnv(int target, int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (target != GL11.GL_TEXTURE_ENV) return;
if (pname == GL11.GL_TEXTURE_ENV_COLOR) {
final var envState = glCtx.textures.getTexEnvState(glCtx.activeTextureUnit.getValue());
params.put(params.position(), envState.envColorR);
params.put(params.position() + 1, envState.envColorG);
params.put(params.position() + 2, envState.envColorB);
params.put(params.position() + 3, envState.envColorA);
} else {
params.put(params.position(), (float) glGetTexEnvi(target, pname));
}
}
public static void glTexGeni(int coord, int pname, int param) {
beforeUncapturedStateChange();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) return;
if (pname == GL11.GL_TEXTURE_GEN_MODE) {
final int unit = glCtx.activeTextureUnit.getValue();
glCtx.textures.getTexGenState(unit).setMode(coord, param);
glCtx.texGenGeneration++;
}
}
public static void glTexGenf(int coord, int pname, float param) {
// Single-float form only valid for GL_TEXTURE_GEN_MODE
glTexGeni(coord, pname, (int) param);
}
public static void glTexGend(int coord, int pname, double param) {
glTexGeni(coord, pname, (int) param);
}
public static void glTexGen(int coord, int pname, FloatBuffer params) {
beforeUncapturedStateChange();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) return;
final int unit = glCtx.activeTextureUnit.getValue();
final var texGenState = glCtx.textures.getTexGenState(unit);
final int pos = params.position();
switch (pname) {
case GL11.GL_TEXTURE_GEN_MODE -> {
texGenState.setMode(coord, (int) params.get(pos));
glCtx.texGenGeneration++;
}
case GL11.GL_OBJECT_PLANE -> {
glCtx.texGenTempPlane[0] = params.get(pos);
glCtx.texGenTempPlane[1] = params.get(pos + 1);
glCtx.texGenTempPlane[2] = params.get(pos + 2);
glCtx.texGenTempPlane[3] = params.get(pos + 3);
texGenState.setObjectPlane(coord, glCtx.texGenTempPlane);
glCtx.texGenGeneration++;
}
case GL11.GL_EYE_PLANE -> {
glCtx.texGenTempPlane[0] = params.get(pos);
glCtx.texGenTempPlane[1] = params.get(pos + 1);
glCtx.texGenTempPlane[2] = params.get(pos + 2);
glCtx.texGenTempPlane[3] = params.get(pos + 3);
texGenState.setEyePlane(coord, glCtx.texGenTempPlane, glCtx.modelViewMatrix);
glCtx.texGenGeneration++;
}
}
}
public static void glTexGen(int coord, int pname, DoubleBuffer params) {
beforeUncapturedStateChange();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) return;
final int pos = params.position();
glCtx.texGenTempPlane[0] = (float) params.get(pos);
glCtx.texGenTempPlane[1] = (float) params.get(pos + 1);
glCtx.texGenTempPlane[2] = (float) params.get(pos + 2);
glCtx.texGenTempPlane[3] = (float) params.get(pos + 3);
final int unit = glCtx.activeTextureUnit.getValue();
final var texGenState = glCtx.textures.getTexGenState(unit);
switch (pname) {
case GL11.GL_TEXTURE_GEN_MODE -> {
texGenState.setMode(coord, (int) params.get(pos));
glCtx.texGenGeneration++;
}
case GL11.GL_OBJECT_PLANE -> {
texGenState.setObjectPlane(coord, glCtx.texGenTempPlane);
glCtx.texGenGeneration++;
}
case GL11.GL_EYE_PLANE -> {
texGenState.setEyePlane(coord, glCtx.texGenTempPlane, glCtx.modelViewMatrix);
glCtx.texGenGeneration++;
}
}
}
public static void glTexGen(int coord, int pname, IntBuffer params) {
beforeUncapturedStateChange();
final GLContextState glCtx = ctx();
if (!isCachingEnabled()) return;
if (pname == GL11.GL_TEXTURE_GEN_MODE) {
final int unit = glCtx.activeTextureUnit.getValue();
glCtx.textures.getTexGenState(unit).setMode(coord, params.get(params.position()));
glCtx.texGenGeneration++;
}
}
public static int glGetTexGeni(int coord, int pname) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (pname == GL11.GL_TEXTURE_GEN_MODE) {
return glCtx.textures.getTexGenState(glCtx.activeTextureUnit.getValue()).getMode(coord);
}
return 0;
}
public static float glGetTexGenf(int coord, int pname) {
return (float) glGetTexGeni(coord, pname);
}
public static double glGetTexGend(int coord, int pname) {
return glGetTexGeni(coord, pname);
}
public static void glGetTexGen(int coord, int pname, IntBuffer params) {
if (pname == GL11.GL_TEXTURE_GEN_MODE) {
params.put(params.position(), glGetTexGeni(coord, pname));
}
}
public static void glGetTexGen(int coord, int pname, FloatBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final var state = glCtx.textures.getTexGenState(glCtx.activeTextureUnit.getValue());
if (pname == GL11.GL_TEXTURE_GEN_MODE) {
params.put(params.position(), (float) state.getMode(coord));
} else if (pname == GL11.GL_OBJECT_PLANE) {
final float[] plane = state.getObjectPlane(coord);
params.put(params.position(), plane[0]);
params.put(params.position() + 1, plane[1]);
params.put(params.position() + 2, plane[2]);
params.put(params.position() + 3, plane[3]);
} else if (pname == GL11.GL_EYE_PLANE) {
final float[] plane = state.getEyePlane(coord);
params.put(params.position(), plane[0]);
params.put(params.position() + 1, plane[1]);
params.put(params.position() + 2, plane[2]);
params.put(params.position() + 3, plane[3]);
}
}
public static void glGetTexGen(int coord, int pname, DoubleBuffer params) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final var state = glCtx.textures.getTexGenState(glCtx.activeTextureUnit.getValue());
if (pname == GL11.GL_TEXTURE_GEN_MODE) {
params.put(params.position(), state.getMode(coord));
} else if (pname == GL11.GL_OBJECT_PLANE) {
final float[] plane = state.getObjectPlane(coord);
params.put(params.position(), plane[0]);
params.put(params.position() + 1, plane[1]);
params.put(params.position() + 2, plane[2]);
params.put(params.position() + 3, plane[3]);
} else if (pname == GL11.GL_EYE_PLANE) {
final float[] plane = state.getEyePlane(coord);
params.put(params.position(), plane[0]);
params.put(params.position() + 1, plane[1]);
params.put(params.position() + 2, plane[2]);
params.put(params.position() + 3, plane[3]);
}
}
}
@@ -0,0 +1,360 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
import com.gtnewhorizons.angelica.glsm.stacks.TextureBindingStack;
import com.gtnewhorizons.angelica.glsm.states.ImageUnitBinding;
import com.gtnewhorizons.angelica.glsm.texture.TextureInfoCache;
import com.gtnewhorizons.angelica.glsm.texture.TextureTargets;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2LongMap;
import it.unimi.dsi.fastutil.ints.Int2LongMaps;
import it.unimi.dsi.fastutil.ints.Int2LongOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongIterator;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.EXTTextureFilterAnisotropic;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GL33;
import org.lwjgl.opengl.GL42;
import org.lwjgl.opengl.GL43;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.acquireDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.drawableContextStates;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.primaryContext;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.releaseDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.splashComplete;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMTextureLifetime {
private GLSMTextureLifetime() {}
// Deferred texture deletion: names kept valid until glGenTextures recycles them.
// Emulates Mesa/compat-profile behavior where delete-then-bind doesn't error.
private static final Int2LongOpenHashMap deferredDeleteTextures = new Int2LongOpenHashMap();
private static final long DEFERRED_ABSENT = Long.MIN_VALUE;
private static final long DEFERRED_ATTACHED = -1;
private static final long DEFERRED_RELEASED = -2;
private static final int RELEASE_DELAY_FRAMES = 3;
private static long frameIndex;
private static long nextReleaseFrame = Long.MAX_VALUE;
private static final Int2IntOpenHashMap non2DTextureTargets = new Int2IntOpenHashMap();
private static final Int2IntOpenHashMap textureFramebufferRefs = new Int2IntOpenHashMap();
private static final FloatBuffer TRANSPARENT_BLACK = BufferUtils.createFloatBuffer(4);
private static final Tracy.ZoneId Z_TEX_RELEASE_STORAGE = Tracy.zoneId("texReleaseStorage", Tracy.COLOR_FFP);
private static final Tracy.ZoneId Z_TEX_RESCUE_RESET = Tracy.zoneId("texRescueReset", Tracy.COLOR_FFP);
private static final Tracy.ZoneId Z_TEX_FLUSH_DELETES = Tracy.zoneId("texFlushDeletes", Tracy.COLOR_FFP);
static {
deferredDeleteTextures.defaultReturnValue(DEFERRED_ABSENT);
non2DTextureTargets.defaultReturnValue(GL11.GL_TEXTURE_2D);
}
/**
* Defer deleting textures until it has been reclaimed.
* Why you might ask? In compat profile if you bind a texture that doesn't exist, ie a deleted texture,
* mesa will silently create it for you, in core this is an error. Why would you be binding a deleted texture?
* Damned if I know, but vanilla and mods do it... they create one, delete it, and then bind it....
* */
static void deferDeleteTexture(int id) {
final GLContextState glCtx = ctx();
if (id == 0) return;
final int savedUnit = glCtx.activeTextureUnit.getValue();
int activeUnit = savedUnit;
// Unbind from all units that have this texture
for (int i = 0; i <= glCtx.maxBoundTextureUnit; i++) {
final TextureBindingStack unitBindings = glCtx.textures.getTextureUnitBindings(i);
if (unitBindings.getBinding() == id) {
if (i != activeUnit) {
RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + i);
activeUnit = i;
}
final int unitTarget = unitBindings.getTarget();
RENDER_BACKEND.bindTexture(unitTarget == 0 ? GL11.GL_TEXTURE_2D : unitTarget, 0);
}
}
for (int i = 0; i <= glCtx.maxBoundImageUnit; i++) {
final ImageUnitBinding image = glCtx.imageUnits.get(i);
if (image != null && image.getTexture() == id) {
RENDER_BACKEND.bindImageTexture(i, 0, 0, false, 0, GL15.GL_READ_ONLY, GL30.GL_R8);
}
}
if (activeUnit != savedUnit) {
RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + savedUnit);
}
final TextureBindingStack savedBindings = glCtx.textures.getTextureUnitBindings(savedUnit);
if (!is2D(savedBindings.getTarget()) && previous2D(savedBindings) == id) restoreUnitAfter2DBind(savedBindings, id, id);
final boolean locked = acquireDrawLock();
try {
detachFromFramebuffer(glCtx, GL30.GL_DRAW_FRAMEBUFFER, glCtx.drawFramebuffer, id);
if (glCtx.readFramebuffer != glCtx.drawFramebuffer) detachFromFramebuffer(glCtx, GL30.GL_READ_FRAMEBUFFER, glCtx.readFramebuffer, id);
if (textureFramebufferRefs.get(id) > 0) deferredDeleteTextures.put(id, DEFERRED_ATTACHED);
else scheduleRelease(id);
} finally {
if (locked) releaseDrawLock();
}
}
private static void scheduleRelease(int id) {
deferredDeleteTextures.put(id, frameIndex);
nextReleaseFrame = Math.min(nextReleaseFrame, frameIndex + RELEASE_DELAY_FRAMES);
}
static final long BIND_REJECTED = Long.MIN_VALUE + 1;
// Rebinding a deferred-delete texture rescues it (Mesa/compat-profile behavior)
static long claimForBind(int texture, int target) {
if (texture == 0) return DEFERRED_ABSENT;
final boolean locked = acquireDrawLock();
try {
final long state = deferredDeleteTextures.isEmpty() ? DEFERRED_ABSENT : deferredDeleteTextures.get(texture);
if (state == DEFERRED_ABSENT) {
recordTarget(texture, target);
return DEFERRED_ABSENT;
}
return non2DTextureTargets.get(texture) == target ? deferredDeleteTextures.remove(texture) : BIND_REJECTED;
} finally {
if (locked) releaseDrawLock();
}
}
static void finishRescue(int target, int texture, long claim) {
if (claim != DEFERRED_ABSENT) resetRescuedTexture(target, texture, claim);
}
static int targetOf(int texture) {
return non2DTextureTargets.get(texture);
}
static boolean isDeferredDelete(int texture) {
if (texture == 0 || deferredDeleteTextures.isEmpty()) return false;
final boolean locked = acquireDrawLock();
try {
return deferredDeleteTextures.containsKey(texture);
} finally {
if (locked) releaseDrawLock();
}
}
public static void onFrameEnd() {
frameIndex++;
if (!splashComplete || frameIndex < nextReleaseFrame) return;
nextReleaseFrame = Long.MAX_VALUE;
for (Int2LongMap.Entry entry : Int2LongMaps.fastIterable(deferredDeleteTextures)) {
final long since = entry.getLongValue();
if (since < 0) continue;
if (frameIndex - since < RELEASE_DELAY_FRAMES) {
nextReleaseFrame = Math.min(nextReleaseFrame, since + RELEASE_DELAY_FRAMES);
continue;
}
final int id = entry.getIntKey();
if (non2DTextureTargets.get(id) == GL11.GL_TEXTURE_2D) releaseStorage2D(id);
entry.setValue(DEFERRED_RELEASED);
}
}
public static int deferredTexturesAwaitingRelease() {
int count = 0;
final LongIterator it = deferredDeleteTextures.values().iterator();
while (it.hasNext()) {
if (it.nextLong() != DEFERRED_RELEASED) count++;
}
return count;
}
private static void releaseStorage2D(int id) {
if (Tracy.ENABLED) Tracy.beginZone(Z_TEX_RELEASE_STORAGE);
try {
final TextureBindingStack unit = ctx().textures.getTextureUnitBindings(GLSMTextures.getActiveTextureUnit());
final int previous2D = previous2D(unit);
RENDER_BACKEND.bindTexture(GL11.GL_TEXTURE_2D, id);
if (bindTook(GL11.GL_TEXTURE_2D, id)) releaseBoundStorage2D();
restoreUnitAfter2DBind(unit, id, previous2D);
} finally {
if (Tracy.ENABLED) Tracy.endZone();
}
}
private static void restoreUnitAfter2DBind(TextureBindingStack unit, int deleted, int previous2D) {
RENDER_BACKEND.bindTexture(GL11.GL_TEXTURE_2D, previous2D == deleted ? 0 : previous2D);
final int target = unit.getTarget();
if (is2D(target)) return;
RENDER_BACKEND.bindTexture(target, unit.getBinding() == deleted ? 0 : unit.getBinding());
}
static boolean is2D(int target) {
return target == 0 || target == GL11.GL_TEXTURE_2D;
}
private static int previous2D(TextureBindingStack unit) {
return is2D(unit.getTarget()) ? unit.getBinding() : RENDER_BACKEND.getInteger(GL11.GL_TEXTURE_BINDING_2D);
}
static void recordTarget(int texture, int target) {
if (target != GL11.GL_TEXTURE_2D) non2DTextureTargets.put(texture, target);
}
private static void releaseBoundStorage2D() {
if (RenderSystem.supportsTextureStorage() && RENDER_BACKEND.getTexParameteri(GL11.GL_TEXTURE_2D, GL42.GL_TEXTURE_IMMUTABLE_FORMAT) != 0) return;
final int size = Math.max(RENDER_BACKEND.getTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_WIDTH), RENDER_BACKEND.getTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_HEIGHT));
final int levels = Math.max(1, 32 - Integer.numberOfLeadingZeros(size));
GLSMBuffers.suspendPixelUnpackBuffer();
for (int level = 0; level < levels; level++) {
RENDER_BACKEND.texImage2D(GL11.GL_TEXTURE_2D, level, GL11.GL_RGBA8, 0, 0, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
}
GLSMBuffers.restorePixelUnpackBuffer();
}
private static boolean bindTook(int target, int texture) {
return RENDER_BACKEND.getInteger(TextureTargets.bindingQuery(target)) == texture;
}
private static void resetRescuedTexture(int target, int texture, long state) {
if (Tracy.ENABLED) Tracy.beginZone(Z_TEX_RESCUE_RESET);
try {
if (!bindTook(target, texture)) return;
if (target == GL11.GL_TEXTURE_2D && state >= 0) releaseBoundStorage2D();
if (target == GL31.GL_TEXTURE_BUFFER || target == GL32.GL_TEXTURE_2D_MULTISAMPLE || target == GL32.GL_TEXTURE_2D_MULTISAMPLE_ARRAY) return;
final boolean rectangle = target == GL31.GL_TEXTURE_RECTANGLE;
final int wrap = rectangle ? GL12.GL_CLAMP_TO_EDGE : GL11.GL_REPEAT;
RENDER_BACKEND.texParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, rectangle ? GL11.GL_LINEAR : GL11.GL_NEAREST_MIPMAP_LINEAR);
RENDER_BACKEND.texParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
RENDER_BACKEND.texParameteri(target, GL11.GL_TEXTURE_WRAP_S, wrap);
RENDER_BACKEND.texParameteri(target, GL11.GL_TEXTURE_WRAP_T, wrap);
RENDER_BACKEND.texParameteri(target, GL12.GL_TEXTURE_WRAP_R, wrap);
RENDER_BACKEND.texParameteri(target, GL12.GL_TEXTURE_BASE_LEVEL, 0);
if (!rectangle) RENDER_BACKEND.texParameteri(target, GL12.GL_TEXTURE_MAX_LEVEL, 1000);
RENDER_BACKEND.texParameterf(target, GL12.GL_TEXTURE_MIN_LOD, -1000.0f);
RENDER_BACKEND.texParameterf(target, GL12.GL_TEXTURE_MAX_LOD, 1000.0f);
RENDER_BACKEND.texParameteri(target, GL14.GL_TEXTURE_COMPARE_MODE, GL11.GL_NONE);
RENDER_BACKEND.texParameteri(target, GL14.GL_TEXTURE_COMPARE_FUNC, GL11.GL_LEQUAL);
RENDER_BACKEND.texParameteri(target, GL33.GL_TEXTURE_SWIZZLE_R, GL11.GL_RED);
RENDER_BACKEND.texParameteri(target, GL33.GL_TEXTURE_SWIZZLE_G, GL11.GL_GREEN);
RENDER_BACKEND.texParameteri(target, GL33.GL_TEXTURE_SWIZZLE_B, GL11.GL_BLUE);
RENDER_BACKEND.texParameteri(target, GL33.GL_TEXTURE_SWIZZLE_A, GL11.GL_ALPHA);
if (!RenderSystem.isGLES()) {
RENDER_BACKEND.texParameterf(target, GL14.GL_TEXTURE_LOD_BIAS, 0.0f);
RENDER_BACKEND.texParameterfv(target, GL11.GL_TEXTURE_BORDER_COLOR, TRANSPARENT_BLACK);
}
if (RenderSystem.supportsStencilTexturing()) RENDER_BACKEND.texParameteri(target, GL43.GL_DEPTH_STENCIL_TEXTURE_MODE, GL11.GL_DEPTH_COMPONENT);
if (RENDER_BACKEND.isAnisotropicSupported()) RENDER_BACKEND.texParameterf(target, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
} finally {
if (Tracy.ENABLED) Tracy.endZone();
}
}
/** Flush deferred deletes so the driver can recycle names. */
static void flushDeferredTextureDeletes() {
if (!splashComplete || deferredDeleteTextures.isEmpty()) return;
if (Tracy.ENABLED) Tracy.beginZone(Z_TEX_FLUSH_DELETES);
try {
final GLContextState primary = primaryContext();
final GLContextState[] drawables = drawableContextStates;
final var it = Int2LongMaps.fastIterator(deferredDeleteTextures);
while (it.hasNext()) {
final Int2LongMap.Entry entry = it.next();
if (entry.getLongValue() == DEFERRED_ATTACHED) continue;
final int id = entry.getIntKey();
it.remove();
RENDER_BACKEND.deleteTextures(id);
non2DTextureTargets.remove(id);
GLSMTextures.clearTextureBindings(primary, id);
for (int i = 0; i < drawables.length; i++) {
GLSMTextures.clearTextureBindings(drawables[i], id);
}
}
} finally {
if (Tracy.ENABLED) Tracy.endZone();
}
}
private static final int DEPTH_SLOT = 16;
private static final int STENCIL_SLOT = 17;
private static final int FRAMEBUFFER_SLOTS = 18;
private static int attachmentSlot(int attachment) {
return switch (attachment) {
case GL30.GL_DEPTH_ATTACHMENT -> DEPTH_SLOT;
case GL30.GL_STENCIL_ATTACHMENT -> STENCIL_SLOT;
default -> attachment >= GL30.GL_COLOR_ATTACHMENT0 && attachment <= GL30.GL_COLOR_ATTACHMENT15 ? attachment - GL30.GL_COLOR_ATTACHMENT0 : -1;
};
}
private static int slotAttachment(int slot) {
return switch (slot) {
case DEPTH_SLOT -> GL30.GL_DEPTH_ATTACHMENT;
case STENCIL_SLOT -> GL30.GL_STENCIL_ATTACHMENT;
default -> GL30.GL_COLOR_ATTACHMENT0 + slot;
};
}
static boolean beginAttach(int target, int attachment, int texture) {
final GLContextState glCtx = ctx();
return beginAttach(glCtx, target == GL30.GL_READ_FRAMEBUFFER ? glCtx.readFramebuffer : glCtx.drawFramebuffer, attachment, texture);
}
static boolean beginAttach(GLContextState glCtx, int framebuffer, int attachment, int texture) {
if (isDeferredDelete(texture)) return false;
TextureInfoCache.INSTANCE.onWrittenOutsideUploads(texture);
trackFramebufferAttachment(glCtx, framebuffer, attachment, texture);
return true;
}
static void trackFramebufferAttachment(GLContextState glCtx, int framebuffer, int attachment, int texture) {
if (framebuffer == 0) return;
if (attachment == GL30.GL_DEPTH_STENCIL_ATTACHMENT) {
trackFramebufferAttachment(glCtx, framebuffer, GL30.GL_DEPTH_ATTACHMENT, texture);
trackFramebufferAttachment(glCtx, framebuffer, GL30.GL_STENCIL_ATTACHMENT, texture);
return;
}
final int slot = attachmentSlot(attachment);
if (slot < 0) return;
int[] slots = glCtx.framebufferTextures.get(framebuffer);
if (slots == null) {
if (texture == 0) return;
slots = new int[FRAMEBUFFER_SLOTS];
glCtx.framebufferTextures.put(framebuffer, slots);
}
setFramebufferSlot(slots, slot, texture);
}
static void setFramebufferSlot(int[] slots, int slot, int texture) {
final int previous = slots[slot];
if (previous == texture) return;
slots[slot] = texture;
final boolean locked = acquireDrawLock();
try {
if (texture != 0) textureFramebufferRefs.addTo(texture, 1);
if (previous != 0 && textureFramebufferRefs.addTo(previous, -1) == 1) {
textureFramebufferRefs.remove(previous);
if (deferredDeleteTextures.get(previous) == DEFERRED_ATTACHED) scheduleRelease(previous);
}
} finally {
if (locked) releaseDrawLock();
}
}
private static void detachFromFramebuffer(GLContextState glCtx, int target, int framebuffer, int texture) {
final int[] slots = glCtx.framebufferTextures.get(framebuffer);
if (slots == null) return;
for (int slot = 0; slot < slots.length; slot++) {
if (slots[slot] != texture) continue;
RENDER_BACKEND.framebufferTexture2D(target, slotAttachment(slot), GL11.GL_TEXTURE_2D, 0, 0);
setFramebufferSlot(slots, slot, 0);
}
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,654 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.glsm.ffp.VAOManager;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL15;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.acquireDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.ctx;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.rejectExitCapture;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.releaseDrawLock;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.requireContext;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.warnOnceTrace;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
public final class GLSMVertexInput {
private GLSMVertexInput() {}
public static int getBoundEBO() {
return ctx().vaos.boundEBO;
}
private static int texCoordConventional(GLContextState glCtx) {
return VAOManager.CONV_TEX0 + glCtx.clientActiveTextureUnit;
}
static void prepareClientArrays(GLContextState glCtx) {
final VAOManager vaos = glCtx.vaos;
if (vaos.hasAnyClientSideEnabledAttrib()) {
vaos.uploadClientArraysToVBO();
}
}
private static boolean isLegalClientArray(int conv, int size, int type, int stride) {
return isLegalPointer(VAOManager.isLegalConventional(conv, size, type), "client-array", "client array", conv, size, type, stride);
}
private static boolean isLegalVertexAttrib(int index, int size, int type, int stride, boolean integer) {
return isLegalPointer(VAOManager.isLegalGeneric(index, size, type, integer), "vertex-attrib", "vertex attribute", index, size, type, stride);
}
private static boolean isLegalPointer(boolean legal, String key, String what, int slot, int size, int type, int stride) {
if (stride < 0) warnOnceTrace(key + "-stride", "Negative {} stride {}", what, stride);
if (legal) return true;
warnOnceTrace(key + "-" + slot, "Ignoring {} {} with illegal size {} / type 0x{}", what, slot, size, Integer.toHexString(type));
return false;
}
private static boolean isValidVertexAttribIndex(int index, String function) {
if (index >= 0 && index < VAOManager.MAX_ATTRIBS) return true;
warnOnceTrace(function, "{}({}) is outside the {} supported vertex attributes; ignoring", function, index, VAOManager.MAX_ATTRIBS);
return false;
}
private static void ffpClientArrayPointer(int conv, int size, int type, boolean normalized, int stride, long offset) {
rejectExitCapture();
if (!isLegalClientArray(conv, size, type, stride)) return;
final GLContextState glCtx = ctx();
if (glCtx.vaos.setConventional(conv, size, type, normalized, stride, offset, glCtx.boundVBO)) {
RENDER_BACKEND.vertexAttribPointer(VAOManager.conventionalLocation(conv), size, type, normalized, stride, offset);
}
}
private static void ffpClientArrayPointer(int conv, int size, int type, boolean normalized, int stride, ByteBuffer pointer) {
rejectExitCapture();
if (!isLegalClientArray(conv, size, type, stride)) return;
ctx().vaos.setConventional(conv, size, type, normalized, stride, pointer);
}
static final int FIELD_SIZE = 0, FIELD_TYPE = 1 << 8, FIELD_STRIDE = 2 << 8, FIELD_BINDING = 3 << 8, FIELD_POINTER = 4 << 8;
static int clientArrayField(GLContextState glCtx, int pname) {
return switch (pname) {
case GL11.GL_VERTEX_ARRAY_SIZE -> VAOManager.CONV_POSITION | FIELD_SIZE;
case GL11.GL_VERTEX_ARRAY_TYPE -> VAOManager.CONV_POSITION | FIELD_TYPE;
case GL11.GL_VERTEX_ARRAY_STRIDE -> VAOManager.CONV_POSITION | FIELD_STRIDE;
case GL15.GL_VERTEX_ARRAY_BUFFER_BINDING -> VAOManager.CONV_POSITION | FIELD_BINDING;
case GL11.GL_VERTEX_ARRAY_POINTER -> VAOManager.CONV_POSITION | FIELD_POINTER;
case GL11.GL_NORMAL_ARRAY_TYPE -> VAOManager.CONV_NORMAL | FIELD_TYPE;
case GL11.GL_NORMAL_ARRAY_STRIDE -> VAOManager.CONV_NORMAL | FIELD_STRIDE;
case GL15.GL_NORMAL_ARRAY_BUFFER_BINDING -> VAOManager.CONV_NORMAL | FIELD_BINDING;
case GL11.GL_NORMAL_ARRAY_POINTER -> VAOManager.CONV_NORMAL | FIELD_POINTER;
case GL11.GL_COLOR_ARRAY_SIZE -> VAOManager.CONV_COLOR | FIELD_SIZE;
case GL11.GL_COLOR_ARRAY_TYPE -> VAOManager.CONV_COLOR | FIELD_TYPE;
case GL11.GL_COLOR_ARRAY_STRIDE -> VAOManager.CONV_COLOR | FIELD_STRIDE;
case GL15.GL_COLOR_ARRAY_BUFFER_BINDING -> VAOManager.CONV_COLOR | FIELD_BINDING;
case GL11.GL_COLOR_ARRAY_POINTER -> VAOManager.CONV_COLOR | FIELD_POINTER;
case GL11.GL_INDEX_ARRAY_TYPE -> VAOManager.CONV_INDEX | FIELD_TYPE;
case GL11.GL_INDEX_ARRAY_STRIDE -> VAOManager.CONV_INDEX | FIELD_STRIDE;
case GL15.GL_INDEX_ARRAY_BUFFER_BINDING -> VAOManager.CONV_INDEX | FIELD_BINDING;
case GL11.GL_INDEX_ARRAY_POINTER -> VAOManager.CONV_INDEX | FIELD_POINTER;
case GL11.GL_EDGE_FLAG_ARRAY_STRIDE -> VAOManager.CONV_EDGE_FLAG | FIELD_STRIDE;
case GL15.GL_EDGE_FLAG_ARRAY_BUFFER_BINDING -> VAOManager.CONV_EDGE_FLAG | FIELD_BINDING;
case GL11.GL_EDGE_FLAG_ARRAY_POINTER -> VAOManager.CONV_EDGE_FLAG | FIELD_POINTER;
case GL14.GL_SECONDARY_COLOR_ARRAY_SIZE -> VAOManager.CONV_SECONDARY_COLOR | FIELD_SIZE;
case GL14.GL_SECONDARY_COLOR_ARRAY_TYPE -> VAOManager.CONV_SECONDARY_COLOR | FIELD_TYPE;
case GL14.GL_SECONDARY_COLOR_ARRAY_STRIDE -> VAOManager.CONV_SECONDARY_COLOR | FIELD_STRIDE;
case GL15.GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING -> VAOManager.CONV_SECONDARY_COLOR | FIELD_BINDING;
case GL14.GL_SECONDARY_COLOR_ARRAY_POINTER -> VAOManager.CONV_SECONDARY_COLOR | FIELD_POINTER;
case GL14.GL_FOG_COORDINATE_ARRAY_TYPE -> VAOManager.CONV_FOG_COORD | FIELD_TYPE;
case GL14.GL_FOG_COORDINATE_ARRAY_STRIDE -> VAOManager.CONV_FOG_COORD | FIELD_STRIDE;
case GL15.GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -> VAOManager.CONV_FOG_COORD | FIELD_BINDING;
case GL14.GL_FOG_COORDINATE_ARRAY_POINTER -> VAOManager.CONV_FOG_COORD | FIELD_POINTER;
case GL11.GL_TEXTURE_COORD_ARRAY_SIZE -> texCoordConventional(glCtx) | FIELD_SIZE;
case GL11.GL_TEXTURE_COORD_ARRAY_TYPE -> texCoordConventional(glCtx) | FIELD_TYPE;
case GL11.GL_TEXTURE_COORD_ARRAY_STRIDE -> texCoordConventional(glCtx) | FIELD_STRIDE;
case GL15.GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING -> texCoordConventional(glCtx) | FIELD_BINDING;
case GL11.GL_TEXTURE_COORD_ARRAY_POINTER -> texCoordConventional(glCtx) | FIELD_POINTER;
default -> -1;
};
}
static int clientArrayParam(GLContextState glCtx, int key) {
final int conv = key & 0xFF;
final VAOManager.Attrib a = glCtx.vaos.conventional(conv);
final boolean specified = a != null && a.size != 0;
return switch (key & ~0xFF) {
case FIELD_SIZE -> specified ? a.size : conv == VAOManager.CONV_SECONDARY_COLOR ? 3 : 4;
case FIELD_TYPE -> specified ? a.type : GL11.GL_FLOAT;
case FIELD_STRIDE -> specified ? a.stride : 0;
default -> specified ? a.vboId : 0;
};
}
public static ByteBuffer glGetPointer(int pname, long result_size) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final int key = clientArrayField(glCtx, pname);
if ((key & ~0xFF) != FIELD_POINTER) return null;
final VAOManager.Attrib a = glCtx.vaos.conventional(key & 0xFF);
if (a == null) return null;
final long address = a.clientPointer != null ? MemoryUtilities.memAddress(a.clientPointer) : a.offset;
return address == 0 ? null : MemoryUtilities.memByteBuffer(address, (int) result_size);
}
public static void glEdgeFlagPointer(int stride, ByteBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_EDGE_FLAG, 1, GL11.GL_UNSIGNED_BYTE, false, stride, pointer);
}
public static void glEdgeFlagPointer(int stride, long pointer_buffer_offset) {
ffpClientArrayPointer(VAOManager.CONV_EDGE_FLAG, 1, GL11.GL_UNSIGNED_BYTE, false, stride, pointer_buffer_offset);
}
public static void glFogCoordPointer(int stride, FloatBuffer data) {
ffpClientArrayPointer(VAOManager.CONV_FOG_COORD, 1, GL11.GL_FLOAT, false, stride, MemoryUtilities.memByteBuffer(data));
}
public static void glFogCoordPointer(int stride, DoubleBuffer data) {
ffpClientArrayPointer(VAOManager.CONV_FOG_COORD, 1, GL11.GL_DOUBLE, false, stride, MemoryUtilities.memByteBuffer(data));
}
public static void glFogCoordPointer(int type, int stride, long data_buffer_offset) {
ffpClientArrayPointer(VAOManager.CONV_FOG_COORD, 1, type, false, stride, data_buffer_offset);
}
public static void glSecondaryColorPointer(int size, int stride, FloatBuffer data) {
ffpClientArrayPointer(VAOManager.CONV_SECONDARY_COLOR, size, GL11.GL_FLOAT, true, stride, MemoryUtilities.memByteBuffer(data));
}
public static void glSecondaryColorPointer(int size, int stride, DoubleBuffer data) {
ffpClientArrayPointer(VAOManager.CONV_SECONDARY_COLOR, size, GL11.GL_DOUBLE, true, stride, MemoryUtilities.memByteBuffer(data));
}
public static void glSecondaryColorPointer(int size, boolean unsigned, int stride, ByteBuffer data) {
final int type = unsigned ? GL11.GL_UNSIGNED_BYTE : GL11.GL_BYTE;
ffpClientArrayPointer(VAOManager.CONV_SECONDARY_COLOR, size, type, true, stride, data);
}
public static void glSecondaryColorPointer(int size, int type, int stride, long data_buffer_offset) {
ffpClientArrayPointer(VAOManager.CONV_SECONDARY_COLOR, size, type, true, stride, data_buffer_offset);
}
static void pointAttrib(GLContextState glCtx, int index) {
final VAOManager vaos = glCtx.vaos;
final VAOManager.Attrib a = vaos.attrib(index);
if (a == null) return;
RENDER_BACKEND.vertexAttribDivisor(index, a.divisor);
if (a.size == 0 || a.vboId == 0 || !vaos.isBufferLive(a)) return;
if (glCtx.boundVBO != a.vboId) GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, a.vboId);
if (a.integer) {
RENDER_BACKEND.vertexAttribIPointer(index, a.size, a.type, a.stride, a.offset);
} else {
RENDER_BACKEND.vertexAttribPointer(index, a.size, a.type, a.normalized, a.stride, a.offset);
}
}
private static void repointAttrib(GLContextState glCtx, int index) {
final int savedVBO = glCtx.boundVBO;
pointAttrib(glCtx, index);
if (glCtx.boundVBO != savedVBO) GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
}
public static void glVertexPointer(int size, int stride, IntBuffer pointer) {
glVertexPointer(size, GL11.GL_INT, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexPointer(int size, int stride, ShortBuffer pointer) {
glVertexPointer(size, GL11.GL_SHORT, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexPointer(int size, int stride, FloatBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_POSITION, size, GL11.GL_FLOAT, false, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexPointer(int size, int stride, DoubleBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_POSITION, size, GL11.GL_DOUBLE, false, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexPointer(int size, int type, int stride, ByteBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_POSITION, size, type, false, stride, pointer);
}
public static void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset) {
ffpClientArrayPointer(VAOManager.CONV_POSITION, size, type, false, stride, pointer_buffer_offset);
}
public static void glColorPointer(int size, int stride, FloatBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_COLOR, size, GL11.GL_FLOAT, Usage.COLOR.isNormalized(), stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glColorPointer(int size, int stride, DoubleBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_COLOR, size, GL11.GL_DOUBLE, Usage.COLOR.isNormalized(), stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glColorPointer(int size, int type, int stride, ByteBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_COLOR, size, type, Usage.COLOR.isNormalized(), stride, pointer);
}
public static void glColorPointer(int size, boolean unsigned, int stride, ByteBuffer pointer) {
final int type = unsigned ? GL11.GL_UNSIGNED_BYTE : GL11.GL_BYTE;
ffpClientArrayPointer(VAOManager.CONV_COLOR, size, type, Usage.COLOR.isNormalized(), stride, pointer);
}
public static void glColorPointer(int size, int type, int stride, long pointer_buffer_offset) {
ffpClientArrayPointer(VAOManager.CONV_COLOR, size, type, Usage.COLOR.isNormalized(), stride, pointer_buffer_offset);
}
public static void glNormalPointer(int stride, FloatBuffer pointer) {
glNormalPointer(GL11.GL_FLOAT, stride, pointer);
}
public static void glNormalPointer(int stride, ByteBuffer pointer) {
glNormalPointer(GL11.GL_BYTE, stride, pointer);
}
public static void glNormalPointer(int stride, IntBuffer pointer) {
glNormalPointer(GL11.GL_INT, stride, pointer);
}
public static void glNormalPointer(int stride, DoubleBuffer pointer) {
glNormalPointer(GL11.GL_DOUBLE, stride, pointer);
}
public static void glNormalPointer(int type, int stride, ByteBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_NORMAL, 3, type, Usage.NORMAL.isNormalized(), stride, pointer);
}
public static void glNormalPointer(int type, int stride, FloatBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_NORMAL, 3, GL11.GL_FLOAT, Usage.NORMAL.isNormalized(), stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glNormalPointer(int type, int stride, ShortBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_NORMAL, 3, GL11.GL_SHORT, Usage.NORMAL.isNormalized(), stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glNormalPointer(int type, int stride, IntBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_NORMAL, 3, GL11.GL_INT, Usage.NORMAL.isNormalized(), stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glNormalPointer(int type, int stride, DoubleBuffer pointer) {
ffpClientArrayPointer(VAOManager.CONV_NORMAL, 3, GL11.GL_DOUBLE, Usage.NORMAL.isNormalized(), stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glNormalPointer(int type, int stride, long pointer_buffer_offset) {
ffpClientArrayPointer(VAOManager.CONV_NORMAL, 3, type, Usage.NORMAL.isNormalized(), stride, pointer_buffer_offset);
}
public static void glTexCoordPointer(int size, int type, int stride, ByteBuffer pointer) {
ffpClientArrayPointer(texCoordConventional(ctx()), size, type, false, stride, pointer);
}
public static void glTexCoordPointer(int size, int stride, FloatBuffer pointer) {
glTexCoordPointer(size, GL11.GL_FLOAT, stride, pointer);
}
public static void glTexCoordPointer(int size, int stride, IntBuffer pointer) {
glTexCoordPointer(size, GL11.GL_INT, stride, pointer);
}
public static void glTexCoordPointer(int size, int stride, ShortBuffer pointer) {
glTexCoordPointer(size, GL11.GL_SHORT, stride, pointer);
}
public static void glTexCoordPointer(int size, int stride, DoubleBuffer pointer) {
glTexCoordPointer(size, GL11.GL_DOUBLE, stride, pointer);
}
public static void glTexCoordPointer(int size, int type, int stride, FloatBuffer pointer) {
ffpClientArrayPointer(texCoordConventional(ctx()), size, GL11.GL_FLOAT, false, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glTexCoordPointer(int size, int type, int stride, ShortBuffer pointer) {
ffpClientArrayPointer(texCoordConventional(ctx()), size, GL11.GL_SHORT, false, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glTexCoordPointer(int size, int type, int stride, IntBuffer pointer) {
ffpClientArrayPointer(texCoordConventional(ctx()), size, GL11.GL_INT, false, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glTexCoordPointer(int size, int type, int stride, DoubleBuffer pointer) {
ffpClientArrayPointer(texCoordConventional(ctx()), size, GL11.GL_DOUBLE, false, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset) {
ffpClientArrayPointer(texCoordConventional(ctx()), size, type, false, stride, pointer_buffer_offset);
}
public static void glEnableClientState(int cap) {
rejectExitCapture();
setClientArrayCap(ctx(), cap, true);
}
public static void glDisableClientState(int cap) {
rejectExitCapture();
setClientArrayCap(ctx(), cap, false);
}
static boolean setClientArrayCap(GLContextState glCtx, int cap, boolean enabled) {
final int conv = clientStateToConventional(glCtx, cap);
if (conv < 0) return false;
setClientArrayEnabled(glCtx, conv, enabled);
return true;
}
private static void setClientArrayEnabled(GLContextState glCtx, int conv, boolean enabled) {
final VAOManager vaos = glCtx.vaos;
final boolean repoint = vaos.setConventionalEnabled(conv, enabled);
final int index = VAOManager.conventionalLocation(conv);
if (index >= 0) {
if (repoint) repointAttrib(glCtx, index);
syncAttribEnable(glCtx, index);
}
final int flag = conventionalVertexFlag(conv);
if (flag == 0) return;
if (enabled) {
vaos.enableClientVertexFlag(flag);
} else {
vaos.disableClientVertexFlag(flag);
}
}
static void syncAttribEnable(GLContextState glCtx, int index) {
if (glCtx.vaos.isAttribEnabled(index)) {
RENDER_BACKEND.enableVertexAttribArray(index);
} else {
RENDER_BACKEND.disableVertexAttribArray(index);
}
}
public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long offset) {
rejectExitCapture();
if (!isLegalVertexAttrib(index, size, type, stride, false)) return;
final GLContextState glCtx = ctx();
if (glCtx.vaos.setAttribute(index, size, type, normalized, stride, offset, glCtx.boundVBO)) {
RENDER_BACKEND.vertexAttribPointer(index, size, type, normalized, stride, offset);
}
}
public static void glVertexAttribPointer(int index, int size, boolean normalized, int stride, FloatBuffer pointer) {
glVertexAttribPointer(index, size, GL11.GL_FLOAT, normalized, stride, pointer);
}
public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, FloatBuffer pointer) {
glVertexAttribPointer(index, size, type, normalized, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, DoubleBuffer pointer) {
glVertexAttribPointer(index, size, type, normalized, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, IntBuffer pointer) {
glVertexAttribPointer(index, size, type, normalized, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, ShortBuffer pointer) {
glVertexAttribPointer(index, size, type, normalized, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, ByteBuffer pointer) {
rejectExitCapture();
if (!isLegalVertexAttrib(index, size, type, stride, false)) return;
ctx().vaos.setAttribute(index, size, type, normalized, stride, pointer);
}
public static void glVertexAttribIPointer(int index, int size, int type, int stride, long offset) {
rejectExitCapture();
if (!isLegalVertexAttrib(index, size, type, stride, true)) return;
final GLContextState glCtx = ctx();
if (glCtx.vaos.setIntegerAttribute(index, size, type, stride, offset, glCtx.boundVBO)) {
RENDER_BACKEND.vertexAttribIPointer(index, size, type, stride, offset);
}
}
public static void glVertexAttribIPointer(int index, int size, int type, int stride, ByteBuffer pointer) {
rejectExitCapture();
if (!isLegalVertexAttrib(index, size, type, stride, true)) return;
ctx().vaos.setIntegerAttribute(index, size, type, stride, pointer);
}
public static void glVertexAttribIPointer(int index, int size, int type, int stride, IntBuffer pointer) {
glVertexAttribIPointer(index, size, type, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexAttribIPointer(int index, int size, int type, int stride, ShortBuffer pointer) {
glVertexAttribIPointer(index, size, type, stride, MemoryUtilities.memByteBuffer(pointer));
}
public static void glVertexAttribDivisor(int index, int divisor) {
rejectExitCapture();
if (ctx().vaos.setDivisor(index, divisor)) RENDER_BACKEND.vertexAttribDivisor(index, divisor);
}
public static void glVertexAttribDivisorARB(int index, int divisor) { glVertexAttribDivisor(index, divisor); }
public static void glBindVertexBuffer(int bindingindex, int buffer, long offset, int stride) { rejectExitCapture(); RENDER_BACKEND.bindVertexBuffer(bindingindex, buffer, offset, stride); }
public static void glVertexAttribFormat(int attribindex, int size, int type, boolean normalized, int relativeoffset) { rejectExitCapture(); RENDER_BACKEND.vertexAttribFormat(attribindex, size, type, normalized, relativeoffset); }
public static void glVertexAttribIFormat(int attribindex, int size, int type, int relativeoffset) { rejectExitCapture(); RENDER_BACKEND.vertexAttribIFormat(attribindex, size, type, relativeoffset); }
public static void glVertexAttribBinding(int attribindex, int bindingindex) { rejectExitCapture(); RENDER_BACKEND.vertexAttribBinding(attribindex, bindingindex); }
public static void glEnableVertexAttribArray(int index) {
rejectExitCapture();
if (!isValidVertexAttribIndex(index, "glEnableVertexAttribArray")) return;
final GLContextState glCtx = ctx();
if (glCtx.vaos.enableAttribute(index)) repointAttrib(glCtx, index);
RENDER_BACKEND.enableVertexAttribArray(index);
}
public static void glDisableVertexAttribArray(int index) {
rejectExitCapture();
if (!isValidVertexAttribIndex(index, "glDisableVertexAttribArray")) return;
final GLContextState glCtx = ctx();
if (glCtx.vaos.disableAttribute(index)) repointAttrib(glCtx, index);
if (!glCtx.vaos.isAttribEnabled(index)) RENDER_BACKEND.disableVertexAttribArray(index);
}
static int clientStateToConventional(GLContextState glCtx, int cap) {
return switch (cap) {
case GL11.GL_VERTEX_ARRAY -> VAOManager.CONV_POSITION;
case GL11.GL_NORMAL_ARRAY -> VAOManager.CONV_NORMAL;
case GL11.GL_COLOR_ARRAY -> VAOManager.CONV_COLOR;
case GL11.GL_INDEX_ARRAY -> VAOManager.CONV_INDEX;
case GL11.GL_EDGE_FLAG_ARRAY -> VAOManager.CONV_EDGE_FLAG;
case GL14.GL_SECONDARY_COLOR_ARRAY -> VAOManager.CONV_SECONDARY_COLOR;
case GL14.GL_FOG_COORDINATE_ARRAY -> VAOManager.CONV_FOG_COORD;
case GL11.GL_TEXTURE_COORD_ARRAY -> texCoordConventional(glCtx);
default -> -1;
};
}
private static int conventionalVertexFlag(int conv) {
return switch (conv) {
case VAOManager.CONV_COLOR -> VertexFlags.COLOR_BIT;
case VAOManager.CONV_NORMAL -> VertexFlags.NORMAL_BIT;
case VAOManager.CONV_TEX0 -> VertexFlags.TEXTURE_BIT;
case VAOManager.CONV_TEX0 + 1 -> VertexFlags.BRIGHTNESS_BIT;
default -> 0;
};
}
public static void glInterleavedArrays(int format, int stride, long pointer) {
interleavedArrays(format, stride, pointer, null);
}
private static void interleavedPointer(int conv, int size, int type, boolean normalized, int stride, long pointer, ByteBuffer base, int offset) {
if (base == null) {
ffpClientArrayPointer(conv, size, type, normalized, stride, pointer + offset);
} else {
ffpClientArrayPointer(conv, size, type, normalized, stride, MemoryUtilities.memSlice(base, offset, base.remaining() - offset));
}
}
private static void interleavedArrays(int format, int stride, long pointer, ByteBuffer base) {
rejectExitCapture();
// Mesa _mesa_get_interleaved_layout decomposition
final int f = 4; // sizeof(float)
final int c = f * ((4 + (f - 1)) / f); // 4 ubytes padded to float alignment = 4
boolean tflag = false, cflag = false, nflag = false;
int tcomps = 0, ccomps = 0, vcomps = 0;
int ctype = 0;
final int toffset = 0;
int coffset = 0;
int noffset = 0;
int voffset = 0;
final int defstride;
switch (format) {
case GL11.GL_V2F:
vcomps = 2; defstride = 2 * f; break;
case GL11.GL_V3F:
vcomps = 3; defstride = 3 * f; break;
case GL11.GL_C4UB_V2F:
cflag = true; ccomps = 4; vcomps = 2;
ctype = GL11.GL_UNSIGNED_BYTE; voffset = c; defstride = c + 2 * f; break;
case GL11.GL_C4UB_V3F:
cflag = true; ccomps = 4; vcomps = 3;
ctype = GL11.GL_UNSIGNED_BYTE; voffset = c; defstride = c + 3 * f; break;
case GL11.GL_C3F_V3F:
cflag = true; ccomps = 3; vcomps = 3;
ctype = GL11.GL_FLOAT; voffset = 3 * f; defstride = 6 * f; break;
case GL11.GL_N3F_V3F:
nflag = true; vcomps = 3;
voffset = 3 * f; defstride = 6 * f; break;
case GL11.GL_C4F_N3F_V3F:
cflag = true; nflag = true; ccomps = 4; vcomps = 3;
ctype = GL11.GL_FLOAT; noffset = 4 * f; voffset = 7 * f; defstride = 10 * f; break;
case GL11.GL_T2F_V3F:
tflag = true; tcomps = 2; vcomps = 3;
voffset = 2 * f; defstride = 5 * f; break;
case GL11.GL_T4F_V4F:
tflag = true; tcomps = 4; vcomps = 4;
voffset = 4 * f; defstride = 8 * f; break;
case GL11.GL_T2F_C4UB_V3F:
tflag = true; cflag = true; tcomps = 2; ccomps = 4; vcomps = 3;
ctype = GL11.GL_UNSIGNED_BYTE; coffset = 2 * f; voffset = c + 2 * f; defstride = c + 5 * f; break;
case GL11.GL_T2F_C3F_V3F:
tflag = true; cflag = true; tcomps = 2; ccomps = 3; vcomps = 3;
ctype = GL11.GL_FLOAT; coffset = 2 * f; voffset = 5 * f; defstride = 8 * f; break;
case GL11.GL_T2F_N3F_V3F:
tflag = true; nflag = true; tcomps = 2; vcomps = 3;
noffset = 2 * f; voffset = 5 * f; defstride = 8 * f; break;
case GL11.GL_T2F_C4F_N3F_V3F:
tflag = true; cflag = true; nflag = true; tcomps = 2; ccomps = 4; vcomps = 3;
ctype = GL11.GL_FLOAT; coffset = 2 * f; noffset = 6 * f; voffset = 9 * f; defstride = 12 * f; break;
case GL11.GL_T4F_C4F_N3F_V4F:
tflag = true; cflag = true; nflag = true; tcomps = 4; ccomps = 4; vcomps = 4;
ctype = GL11.GL_FLOAT; coffset = 4 * f; noffset = 8 * f; voffset = 11 * f; defstride = 15 * f; break;
default:
return; // Invalid format
}
if (stride == 0) stride = defstride;
if (tflag) {
glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
interleavedPointer(texCoordConventional(ctx()), tcomps, GL11.GL_FLOAT, false, stride, pointer, base, toffset);
} else {
glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if (cflag) {
glEnableClientState(GL11.GL_COLOR_ARRAY);
interleavedPointer(VAOManager.CONV_COLOR, ccomps, ctype, Usage.COLOR.isNormalized(), stride, pointer, base, coffset);
} else {
glDisableClientState(GL11.GL_COLOR_ARRAY);
}
if (nflag) {
glEnableClientState(GL11.GL_NORMAL_ARRAY);
interleavedPointer(VAOManager.CONV_NORMAL, 3, GL11.GL_FLOAT, Usage.NORMAL.isNormalized(), stride, pointer, base, noffset);
} else {
glDisableClientState(GL11.GL_NORMAL_ARRAY);
}
glEnableClientState(GL11.GL_VERTEX_ARRAY);
interleavedPointer(VAOManager.CONV_POSITION, vcomps, GL11.GL_FLOAT, false, stride, pointer, base, voffset);
}
public static void glInterleavedArrays(int format, int stride, ByteBuffer pointer) {
interleavedArrays(format, stride, 0L, pointer);
}
public static void glInterleavedArrays(int format, int stride, FloatBuffer pointer) {
interleavedArrays(format, stride, 0L, MemoryUtilities.memByteBuffer(pointer));
}
public static void glInterleavedArrays(int format, int stride, DoubleBuffer pointer) {
interleavedArrays(format, stride, 0L, MemoryUtilities.memByteBuffer(pointer));
}
public static void glInterleavedArrays(int format, int stride, IntBuffer pointer) {
interleavedArrays(format, stride, 0L, MemoryUtilities.memByteBuffer(pointer));
}
public static void glInterleavedArrays(int format, int stride, ShortBuffer pointer) {
interleavedArrays(format, stride, 0L, MemoryUtilities.memByteBuffer(pointer));
}
public static void glBindVertexArray(int array) {
rejectExitCapture();
final GLContextState glCtx = ctx();
if (DisplayListManager.isRecording()) {
DisplayListManager.recordBindVAO(array);
// Since the vao needs to be bound to do stuff like state setup & data upload, it'll still execute the bind call.
// This is technically wrong, but I'm not sure if there's a better solution here.
}
bindVertexArrayInternal(glCtx, array == 0 ? glCtx.defaultVAO : array);
}
static void bindVertexArrayInternal(GLContextState glCtx, int array) {
final boolean locked = acquireDrawLock();
try {
if (glCtx.boundVAO != array) {
glCtx.boundVAO = array;
glCtx.vaos.onBindVertexArrayPre(array);
RENDER_BACKEND.bindVertexArray(array);
}
} finally {
if (locked) releaseDrawLock();
}
}
public static void glDeleteVertexArrays(int array) {
rejectExitCapture();
final GLContextState glCtx = ctx();
final boolean locked = acquireDrawLock();
try {
glCtx.vaos.onDeleteVertexArray(array);
if (array == glCtx.boundVAO) {
// Deleting the bound VAO implicitly unbinds it. Rebind the default VAO.
bindVertexArrayInternal(glCtx, glCtx.defaultVAO);
}
RENDER_BACKEND.deleteVertexArrays(array);
} finally {
if (locked) releaseDrawLock();
}
}
public static int glGenVertexArrays() {
requireContext("glGenVertexArrays");
return RENDER_BACKEND.genVertexArrays();
}
public static boolean glIsVertexArray(int array) {
rejectExitCapture();
return RENDER_BACKEND.isVertexArray(array);
}
public static void glBindVertexArrayAPPLE(int array) {
glBindVertexArray(array);
}
public static int getBoundVAO() {
return ctx().boundVAO;
}
}
File diff suppressed because it is too large. Load diff
@@ -25,10 +25,10 @@ public final class LTWWorkaround {
oneTexel = BufferUtils.createByteBuffer(4);
}
oneTexel.clear();
GLStateManager.forcePixelUnpackState(PixelStoreState.DEFAULT);
GLStateManager.suspendPixelUnpackBuffer();
GLSMTextures.forcePixelUnpackState(PixelStoreState.DEFAULT);
GLSMBuffers.suspendPixelUnpackBuffer();
RENDER_BACKEND.texSubImage2D(target, level, 0, 0, 1, 1, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, oneTexel);
GLStateManager.restorePixelUnpackBuffer();
GLStateManager.restorePixelUnpackState(PixelStoreState.DEFAULT);
GLSMBuffers.restorePixelUnpackBuffer();
GLSMTextures.restorePixelUnpackState(PixelStoreState.DEFAULT);
}
}
@@ -88,7 +88,7 @@ final class LegacyQueries {
private static FloatBuffer fillScratch(GLContextState glCtx, int pname) {
final FloatBuffer scratch = glCtx.queryScratch;
scratch.clear();
GLStateManager.glGetFloat(pname, scratch);
GLSMQueries.glGetFloat(pname, scratch);
return scratch;
}
@@ -102,9 +102,9 @@ final class LegacyQueries {
return toInt(type, fillScratch(glCtx, pname).get(0));
}
return switch (type) {
case BOOL -> GLStateManager.glGetBoolean(glCtx, pname) ? GL11.GL_TRUE : GL11.GL_FALSE;
case FLOAT -> lround(GLStateManager.glGetFloat(glCtx, pname));
case FLOATN -> floatToInt(GLStateManager.glGetFloat(glCtx, pname));
case BOOL -> GLSMQueries.glGetBoolean(glCtx, pname) ? GL11.GL_TRUE : GL11.GL_FALSE;
case FLOAT -> lround(GLSMQueries.glGetFloat(glCtx, pname));
case FLOATN -> floatToInt(GLSMQueries.glGetFloat(glCtx, pname));
default -> throw uncached(pname);
};
}
@@ -114,8 +114,8 @@ final class LegacyQueries {
return fillScratch(glCtx, pname).get(0);
}
return switch (type(desc)) {
case BOOL -> GLStateManager.glGetBoolean(glCtx, pname) ? 1.0f : 0.0f;
case INT -> (float) GLStateManager.glGetInteger(glCtx, pname);
case BOOL -> GLSMQueries.glGetBoolean(glCtx, pname) ? 1.0f : 0.0f;
case INT -> (float) GLSMQueries.glGetInteger(glCtx, pname);
default -> throw uncached(pname);
};
}
@@ -125,8 +125,8 @@ final class LegacyQueries {
return fillScratch(glCtx, pname).get(0) != 0.0f;
}
return switch (type(desc)) {
case INT -> GLStateManager.glGetInteger(glCtx, pname) != 0;
case FLOAT, FLOATN -> GLStateManager.glGetFloat(glCtx, pname) != 0.0f;
case INT -> GLSMQueries.glGetInteger(glCtx, pname) != 0;
case FLOAT, FLOATN -> GLSMQueries.glGetFloat(glCtx, pname) != 0.0f;
default -> throw uncached(pname);
};
}
@@ -114,7 +114,7 @@ public final class QuadConverter {
uploadAndDraw(glCtx, dst, quadCount * 6, GL11.GL_UNSIGNED_INT, 4, primcount, instanced);
return;
}
GLStateManager.preDraw(glCtx, GL11.GL_TRIANGLES);
GLSMDraws.preDraw(glCtx, GL11.GL_TRIANGLES);
final int prevEbo = glCtx.vaos.boundEBO;
ensureCapacity(first / 4 + quadCount);
RENDER_BACKEND.bindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, eboId);
@@ -143,7 +143,7 @@ public final class QuadConverter {
}
private static void uploadAndDraw(GLContextState glCtx, ByteBuffer dst, int triIndexCount, int indexType, int bytesPerIndex, int primcount, boolean instanced) {
GLStateManager.preDraw(glCtx, GL11.GL_TRIANGLES);
GLSMDraws.preDraw(glCtx, GL11.GL_TRIANGLES);
final int needed = triIndexCount * bytesPerIndex;
final int prevEbo = glCtx.vaos.boundEBO;
@@ -209,14 +209,14 @@ public class RenderSystem {
public static void texImage2D(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, @Nullable ByteBuffer pixels) {
GLStateManager.rejectExitCapture();
final GLStateManager.GLESTexImageRemap remap = GLStateManager.remapTexImageForGLES(internalformat, format, type);
final GLSMTextures.GLESTexImageRemap remap = GLSMTextures.remapTexImageForGLES(internalformat, format, type);
internalformat = remap.internalFormat();
format = remap.format();
type = remap.type();
GLStateManager.glBindTexture(target, texture);
GLStateManager.suspendPixelUnpackBuffer();
GLSMTextures.glBindTexture(target, texture);
GLSMBuffers.suspendPixelUnpackBuffer();
RENDER_BACKEND.texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
if (target == GL11.GL_TEXTURE_2D && level == 0) {
TextureInfoCache.INSTANCE.onTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
@@ -228,7 +228,7 @@ public class RenderSystem {
}
public static void copyTexImage2D(int target, int level, int internalFormat, int x, int y, int width, int height, int border) {
GLStateManager.glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
GLSMTextures.glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
}
public static void uniform1f(int location, float v0) {
@@ -304,50 +304,50 @@ public class RenderSystem {
public static void textureImage2D(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, ByteBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.suspendPixelUnpackBuffer();
GLSMBuffers.suspendPixelUnpackBuffer();
dsaState.textureImage2D(texture, target, level, internalformat, width, height, border, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
TextureInfoCache.INSTANCE.onTextureImage2D(texture, target, level, internalformat, width, height);
}
public static void textureImage2D(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, IntBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.suspendPixelUnpackBuffer();
GLSMBuffers.suspendPixelUnpackBuffer();
dsaState.textureImage2D(texture, target, level, internalformat, width, height, border, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
TextureInfoCache.INSTANCE.onTextureImage2D(texture, target, level, internalformat, width, height);
}
public static void textureSubImage2D(int texture, int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, ByteBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.suspendPixelUnpackBuffer();
GLSMBuffers.suspendPixelUnpackBuffer();
dsaState.textureSubImage2D(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
if (level == 0) TextureInfoCache.INSTANCE.onContentsChanged(texture);
}
public static void textureSubImage2D(int texture, int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, IntBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.suspendPixelUnpackBuffer();
GLSMBuffers.suspendPixelUnpackBuffer();
dsaState.textureSubImage2D(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
if (level == 0) TextureInfoCache.INSTANCE.onContentsChanged(texture);
}
public static void texImage1D(int texture, int target, int level, int internalformat, int width, int border, int format, int type, ByteBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.glBindTexture(target, texture);
GLStateManager.suspendPixelUnpackBuffer();
GLSMTextures.glBindTexture(target, texture);
GLSMBuffers.suspendPixelUnpackBuffer();
RENDER_BACKEND.texImage1D(target, level, internalformat, width, border, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
}
public static void texImage3D(int texture, int target, int level, int internalformat, int width, int height, int depth, int border, int format, int type, ByteBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.glBindTexture(target, texture);
GLStateManager.suspendPixelUnpackBuffer();
GLSMTextures.glBindTexture(target, texture);
GLSMBuffers.suspendPixelUnpackBuffer();
RENDER_BACKEND.texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
GLStateManager.restorePixelUnpackBuffer();
GLSMBuffers.restorePixelUnpackBuffer();
}
public static String getProgramInfoLog(int program) {
@@ -377,13 +377,13 @@ public class RenderSystem {
public static void readPixels(int x, int y, int width, int height, int format, int type, FloatBuffer pixels) {
GLStateManager.rejectExitCapture();
GLStateManager.suspendPixelPackBuffer();
GLSMBuffers.suspendPixelPackBuffer();
RENDER_BACKEND.readPixels(x, y, width, height, format, type, pixels);
GLStateManager.restorePixelPackBuffer();
GLSMBuffers.restorePixelPackBuffer();
}
public static void bufferData(int target, FloatBuffer data, int usage) {
GLStateManager.glBufferData(target, data, usage);
GLSMBuffers.glBufferData(target, data, usage);
}
public static int bufferStorage(int target, FloatBuffer data, int usage) {
@@ -422,7 +422,7 @@ public class RenderSystem {
}
public static void bindImageTexture(int unit, int texture, int level, boolean layered, int layer, int access, int format) {
GLStateManager.glBindImageTexture(unit, texture, level, layered, layer, access, format);
GLSMTextures.glBindImageTexture(unit, texture, level, layered, layer, access, format);
}
public static int getMaxImageUnits() {
@@ -439,9 +439,9 @@ public class RenderSystem {
}
private static boolean hasExtension(String name) {
final int count = GLStateManager.glGetInteger(GL30.GL_NUM_EXTENSIONS);
final int count = GLSMQueries.glGetInteger(GL30.GL_NUM_EXTENSIONS);
for (int i = 0; i < count; i++) {
if (name.equals(GLStateManager.glGetStringi(GL11.GL_EXTENSIONS, i))) return true;
if (name.equals(GLSMQueries.glGetStringi(GL11.GL_EXTENSIONS, i))) return true;
}
return false;
}
@@ -533,7 +533,7 @@ public class RenderSystem {
}
public static void bindBuffer(int target, int buffer) {
GLStateManager.glBindBuffer(target, buffer);
GLSMBuffers.glBindBuffer(target, buffer);
}
public static void memoryBarrier(int barriers) {
@@ -548,52 +548,52 @@ public class RenderSystem {
}
public static void disableBufferBlend(int buffer) {
GLStateManager.glDisablei(GL11.GL_BLEND, buffer);
GLSMEnable.glDisablei(GL11.GL_BLEND, buffer);
}
public static void enableBufferBlend(int buffer) {
GLStateManager.glEnablei(GL11.GL_BLEND, buffer);
GLSMEnable.glEnablei(GL11.GL_BLEND, buffer);
}
public static void blendFuncSeparatei(int buffer, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) {
GLStateManager.glBlendFuncSeparatei(buffer, srcRGB, dstRGB, srcAlpha, dstAlpha);
GLSMBlend.glBlendFuncSeparatei(buffer, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
public static void bindTextureToUnit(int unit, int texture) {
if (unit == 0) GLStateManager.recordExitTextureBind(GL11.GL_TEXTURE_2D, 0);
else if (GLStateManager.getBoundTextureForServerState(unit) != texture) GLStateManager.beforeUncapturedStateChange();
else if (GLSMTextures.getBoundTextureForServerState(unit) != texture) GLStateManager.beforeUncapturedStateChange();
dsaState.bindTextureToUnit(unit, texture);
}
public static void bindTextureToUnit(int target, int unit, int texture) {
if (unit == 0) GLStateManager.recordExitTextureBind(target, 0);
else if (GLStateManager.getBoundTextureForServerState(unit) != texture) GLStateManager.beforeUncapturedStateChange();
else if (GLSMTextures.getBoundTextureForServerState(unit) != texture) GLStateManager.beforeUncapturedStateChange();
dsaState.bindTextureToUnit(target, unit, texture);
}
public static void setupProjectionMatrix(Matrix4f matrix) {
final FloatBuffer projectionMatrixBuffer = GLStateManager.ctx().projectionMatrixBuffer;
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glPushMatrix();
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glPushMatrix();
matrix.get(0, projectionMatrixBuffer);
GLStateManager.glLoadMatrix(projectionMatrixBuffer);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadMatrix(projectionMatrixBuffer);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
}
public static void restoreProjectionMatrix() {
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glPopMatrix();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glPopMatrix();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
}
public static void blitFramebuffer(int source, int dest, int offsetX, int offsetY, int width, int height, int offsetX2, int offsetY2, int width2, int height2, int bufferChoice, int filter) {
GLStateManager.rejectExitCapture();
final boolean scissor = GLStateManager.glIsEnabled(GL11.GL_SCISSOR_TEST);
if (scissor) GLStateManager.glDisable(GL11.GL_SCISSOR_TEST);
final boolean scissor = GLSMEnable.glIsEnabled(GL11.GL_SCISSOR_TEST);
if (scissor) GLSMEnable.glDisable(GL11.GL_SCISSOR_TEST);
try {
dsaState.blitFramebuffer(source, dest, offsetX, offsetY, width, height, offsetX2, offsetY2, width2, height2, bufferChoice, filter);
} finally {
if (scissor) GLStateManager.glEnable(GL11.GL_SCISSOR_TEST);
if (scissor) GLSMEnable.glEnable(GL11.GL_SCISSOR_TEST);
}
}
@@ -617,30 +617,30 @@ public class RenderSystem {
}
public static int createBuffers() {
return GLStateManager.glGenBuffers();
return GLSMBuffers.glGenBuffers();
}
public static int getIndexedBufferBinding(int target, int index) {
GLStateManager.rejectExitCapture();
return GLStateManager.getIndexedBufferBinding(target, index);
return GLSMBuffers.getIndexedBufferBinding(target, index);
}
public static void bindBufferBase(int target, int index, int buffer) {
GLStateManager.glBindBufferBase(target, index, buffer);
GLSMBuffers.glBindBufferBase(target, index, buffer);
}
public static void bufferStorage(int target, long size, int flags) {
GLStateManager.glBufferStorage(target, size, flags);
GLSMBuffers.glBufferStorage(target, size, flags);
}
public static void clearBufferSubData(int target, int internalFormat, long offset, long size, int format, int type, int[] data) {
final ByteBuffer buf = BufferUtils.createByteBuffer(data.length * 4);
buf.asIntBuffer().put(data);
GLStateManager.glClearBufferSubData(target, internalFormat, offset, size, format, type, buf);
GLSMBuffers.glClearBufferSubData(target, internalFormat, offset, size, format, type, buf);
}
public static void deleteBuffers(int buffer) {
GLStateManager.glDeleteBuffers(buffer);
GLSMBuffers.glDeleteBuffers(buffer);
}
public static long getVRAM() {
@@ -688,32 +688,32 @@ public class RenderSystem {
public static int genSampler() {
if (!supportsSamplerObjects) return 0;
return GLStateManager.glGenSamplers();
return GLSMTextures.glGenSamplers();
}
public static void destroySampler(int sampler) {
if (!supportsSamplerObjects || sampler == 0) return;
GLStateManager.glDeleteSamplers(sampler);
GLSMTextures.glDeleteSamplers(sampler);
}
public static void samplerParameteri(int sampler, int pname, int param) {
if (!supportsSamplerObjects || sampler == 0) return;
GLStateManager.glSamplerParameteri(sampler, pname, param);
GLSMTextures.glSamplerParameteri(sampler, pname, param);
}
public static void samplerParameterf(int sampler, int pname, float param) {
if (!supportsSamplerObjects || sampler == 0) return;
GLStateManager.glSamplerParameterf(sampler, pname, param);
GLSMTextures.glSamplerParameterf(sampler, pname, param);
}
public static void bindSamplerToUnit(int unit, int sampler) {
if (!supportsSamplerObjects) return;
GLStateManager.glBindSampler(unit, sampler);
GLSMTextures.glBindSampler(unit, sampler);
}
public static void unbindAllSamplers() {
if (!supportsSamplerObjects) return;
GLStateManager.unbindAllSamplers();
GLSMTextures.unbindAllSamplers();
}
/** Parse a GL version string (e.g. "4.6.0 NVIDIA ...") into concatenated digits "460". Strips
@@ -49,7 +49,7 @@ public final class StateSet {
this.restore = restore;
this.bump = bump;
this.blendSnapshot = blendSnapshot;
this.pushCommand = () -> GLStateManager.pushStateLive(this);
this.pushCommand = () -> GLSMAttribStack.pushStateLive(this);
}
public boolean contains(int id) {
@@ -83,18 +83,18 @@ public final class StateSet {
private static StateSet buildBatch() {
return new StateSet(0,
ids(
GLStateManager.getBlendState(), GLStateManager.getAlphaState(), GLStateManager.getDepthState(),
GLStateManager.getColorMask(), GLStateManager.getPolygonState(),
GLStateManager.getTextures().getTextureUnitBindings(0), GLStateManager.getTextures().getTextureUnitBindings(1),
GLStateManager.getActiveTextureUnitStack(),
GLStateManager.getBlendMode(), GLStateManager.getAlphaTest(), GLStateManager.getDepthTest(),
GLStateManager.getLightingState(), GLStateManager.getCullState(), GLStateManager.getPolygonOffsetFillState(),
GLStateManager.getTextures().getTextureUnitStates(0), GLStateManager.getTextures().getTextureUnitStates(1),
GLStateManager.getLightStates()[0], GLStateManager.getLightStates()[1],
GLStateManager.getLightDataStates()[0], GLStateManager.getLightDataStates()[1],
GLStateManager.getColorMaterial(), GLStateManager.getColorMaterialFace(), GLStateManager.getColorMaterialParameter(),
GLStateManager.getLightModel(), GLStateManager.getFrontMaterial(), GLStateManager.getBackMaterial(),
GLStateManager.getNormalizeState(), GLStateManager.getRescaleNormalState()
GLSMBlend.getBlendState(), GLSMDepthStencilAlpha.getAlphaState(), GLSMDepthStencilAlpha.getDepthState(),
GLSMBlend.getColorMask(), GLSMRasterizer.getPolygonState(),
GLSMTextures.getTextures().getTextureUnitBindings(0), GLSMTextures.getTextures().getTextureUnitBindings(1),
GLSMTextures.getActiveTextureUnitStack(),
GLSMBlend.getBlendMode(), GLSMDepthStencilAlpha.getAlphaTest(), GLSMDepthStencilAlpha.getDepthTest(),
GLSMLighting.getLightingState(), GLSMRasterizer.getCullState(), GLSMRasterizer.getPolygonOffsetFillState(),
GLSMTextures.getTextures().getTextureUnitStates(0), GLSMTextures.getTextures().getTextureUnitStates(1),
GLSMLighting.getLightStates()[0], GLSMLighting.getLightStates()[1],
GLSMLighting.getLightDataStates()[0], GLSMLighting.getLightDataStates()[1],
GLSMLighting.getColorMaterial(), GLSMLighting.getColorMaterialFace(), GLSMLighting.getColorMaterialParameter(),
GLSMLighting.getLightModel(), GLSMLighting.getFrontMaterial(), GLSMLighting.getBackMaterial(),
GLSMLighting.getNormalizeState(), GLSMLighting.getRescaleNormalState()
),
R_BLEND | R_DEPTH | R_COLOR_MASK | R_POLYGON | R_TEXTURE | R_ACTIVE_UNIT,
B_FRAG_COLORBUF | B_LIGHTING,
@@ -104,13 +104,13 @@ public final class StateSet {
private static StateSet buildFont() {
return new StateSet(0,
ids(
GLStateManager.getBlendState(), GLStateManager.getDepthState(), GLStateManager.getShadeModelState(),
GLStateManager.getTextures().getTextureUnitBindings(0), GLStateManager.getTextures().getTextureUnitBindings(1),
GLStateManager.getActiveTextureUnitStack(), GLStateManager.getProgramStack(),
GLStateManager.getBlendMode(), GLStateManager.getAlphaTest(), GLStateManager.getDepthTest(),
GLStateManager.getTextures().getTextureUnitStates(0),
GLStateManager.getColorMask(), GLStateManager.getCullState(),
GLStateManager.getPolygonState(), GLStateManager.getPolygonOffsetFillState()
GLSMBlend.getBlendState(), GLSMDepthStencilAlpha.getDepthState(), GLSMRasterizer.getShadeModelState(),
GLSMTextures.getTextures().getTextureUnitBindings(0), GLSMTextures.getTextures().getTextureUnitBindings(1),
GLSMTextures.getActiveTextureUnitStack(), GLSMPrograms.getProgramStack(),
GLSMBlend.getBlendMode(), GLSMDepthStencilAlpha.getAlphaTest(), GLSMDepthStencilAlpha.getDepthTest(),
GLSMTextures.getTextures().getTextureUnitStates(0),
GLSMBlend.getColorMask(), GLSMRasterizer.getCullState(),
GLSMRasterizer.getPolygonState(), GLSMRasterizer.getPolygonOffsetFillState()
),
R_BLEND | R_DEPTH | R_COLOR_MASK | R_TEXTURE | R_ACTIVE_UNIT | R_PROGRAM | R_POLYGON,
0,
@@ -120,13 +120,13 @@ public final class StateSet {
private static StateSet buildFontPipeline() {
return new StateSet(0,
ids(
GLStateManager.getBlendState(), GLStateManager.getDepthState(),
GLStateManager.getTextures().getTextureUnitBindings(0), GLStateManager.getTextures().getTextureUnitBindings(1),
GLStateManager.getActiveTextureUnitStack(),
GLStateManager.getBlendMode(), GLStateManager.getAlphaTest(), GLStateManager.getDepthTest(),
GLStateManager.getTextures().getTextureUnitStates(0),
GLStateManager.getColorMask(), GLStateManager.getCullState(),
GLStateManager.getPolygonState(), GLStateManager.getPolygonOffsetFillState()
GLSMBlend.getBlendState(), GLSMDepthStencilAlpha.getDepthState(),
GLSMTextures.getTextures().getTextureUnitBindings(0), GLSMTextures.getTextures().getTextureUnitBindings(1),
GLSMTextures.getActiveTextureUnitStack(),
GLSMBlend.getBlendMode(), GLSMDepthStencilAlpha.getAlphaTest(), GLSMDepthStencilAlpha.getDepthTest(),
GLSMTextures.getTextures().getTextureUnitStates(0),
GLSMBlend.getColorMask(), GLSMRasterizer.getCullState(),
GLSMRasterizer.getPolygonState(), GLSMRasterizer.getPolygonOffsetFillState()
),
R_BLEND | R_DEPTH | R_COLOR_MASK | R_TEXTURE | R_ACTIVE_UNIT | R_POLYGON,
0,
@@ -136,8 +136,8 @@ public final class StateSet {
private static StateSet buildHand() {
return new StateSet(0,
ids(
GLStateManager.getBlendState(), GLStateManager.getAlphaState(), GLStateManager.getDepthState(),
GLStateManager.getBlendMode(), GLStateManager.getAlphaTest(), GLStateManager.getTextures().getTextureUnitStates(1)
GLSMBlend.getBlendState(), GLSMDepthStencilAlpha.getAlphaState(), GLSMDepthStencilAlpha.getDepthState(),
GLSMBlend.getBlendMode(), GLSMDepthStencilAlpha.getAlphaTest(), GLSMTextures.getTextures().getTextureUnitStates(1)
),
R_BLEND | R_DEPTH,
B_FRAG_COLORBUF,
@@ -146,7 +146,7 @@ public final class StateSet {
private static StateSet buildBlend() {
return new StateSet(0,
ids(GLStateManager.getBlendState(), GLStateManager.getBlendMode()),
ids(GLSMBlend.getBlendState(), GLSMBlend.getBlendMode()),
R_BLEND,
0,
true);
@@ -154,7 +154,7 @@ public final class StateSet {
private static StateSet buildAlpha() {
return new StateSet(0,
ids(GLStateManager.getAlphaState(), GLStateManager.getAlphaTest()),
ids(GLSMDepthStencilAlpha.getAlphaState(), GLSMDepthStencilAlpha.getAlphaTest()),
0,
B_FRAG_COLORBUF,
false);
@@ -162,7 +162,7 @@ public final class StateSet {
private static StateSet buildCutout() {
return new StateSet(0,
ids(GLStateManager.getAlphaState(), GLStateManager.getAlphaTest(), GLStateManager.getTextures().getTextureUnitStates(1)),
ids(GLSMDepthStencilAlpha.getAlphaState(), GLSMDepthStencilAlpha.getAlphaTest(), GLSMTextures.getTextures().getTextureUnitStates(1)),
0,
B_FRAG_COLORBUF,
false);
@@ -170,7 +170,7 @@ public final class StateSet {
private static StateSet buildMasks() {
return new StateSet(0,
ids(GLStateManager.getDepthState(), GLStateManager.getColorMask()),
ids(GLSMDepthStencilAlpha.getDepthState(), GLSMBlend.getColorMask()),
R_DEPTH | R_COLOR_MASK,
0,
false);
@@ -178,7 +178,7 @@ public final class StateSet {
private static StateSet buildCull() {
return new StateSet(0,
ids(GLStateManager.getPolygonState(), GLStateManager.getCullState()),
ids(GLSMRasterizer.getPolygonState(), GLSMRasterizer.getCullState()),
R_POLYGON,
0,
false);
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.glsm.backend;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizons.angelica.glsm.GLESFormatRemap;
import com.gtnewhorizons.angelica.glsm.GLSMAttribStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import com.gtnewhorizons.angelica.glsm.texture.TextureStaging;
@@ -249,7 +250,7 @@ public abstract class RenderBackend {
public void onFrameBegin() {
if (GLStateManager.takeStateSeedPending()) {
GLStateManager.replayStateToBackend();
GLSMAttribStack.replayStateToBackend();
}
}
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.compat.lwjgl;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
import org.lwjgl.util.glu.Cylinder;
import static org.lwjgl.opengl.GL11.GL_LINES;
@@ -28,11 +29,11 @@ public class AngelicaCylinder extends Cylinder {
y /= mag;
z /= mag;
}
GLStateManager.glNormal3f(x, y, z);
GLSMCurrentAttribs.glNormal3f(x, y, z);
}
private void emitTexCoord(float x, float y) {
if (super.textureFlag) GLStateManager.glTexCoord2f(x, y);
if (super.textureFlag) GLSMCurrentAttribs.glTexCoord2f(x, y);
}
@Override
@@ -48,7 +49,7 @@ public class AngelicaCylinder extends Cylinder {
nz = (baseRadius - topRadius) / height;
if (super.drawStyle == GLU_POINT) {
GLStateManager.glBegin(GL_POINTS);
GLSMDraws.glBegin(GL_POINTS);
for (int i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
@@ -57,60 +58,60 @@ public class AngelicaCylinder extends Cylinder {
z = 0.0f;
r = baseRadius;
for (int j = 0; j <= stacks; j++) {
GLStateManager.glVertex3f(x * r, y * r, z);
GLSMDraws.glVertex3f(x * r, y * r, z);
z += dz;
r += dr;
}
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
} else if (super.drawStyle == GLU_LINE || super.drawStyle == GLU_SILHOUETTE) {
// Draw rings
if (super.drawStyle == GLU_LINE) {
z = 0.0f;
r = baseRadius;
for (int j = 0; j <= stacks; j++) {
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glBegin(GL_LINE_LOOP);
for (int i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
emitNormal(x * nsign, y * nsign, nz * nsign);
GLStateManager.glVertex3f(x * r, y * r, z);
GLSMDraws.glVertex3f(x * r, y * r, z);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
z += dz;
r += dr;
}
} else {
// draw one ring at each end
if (baseRadius != 0.0) {
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glBegin(GL_LINE_LOOP);
for (int i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
emitNormal(x * nsign, y * nsign, nz * nsign);
GLStateManager.glVertex3f(x * baseRadius, y * baseRadius, 0.0f);
GLSMDraws.glVertex3f(x * baseRadius, y * baseRadius, 0.0f);
}
GLStateManager.glEnd();
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glEnd();
GLSMDraws.glBegin(GL_LINE_LOOP);
for (int i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
emitNormal(x * nsign, y * nsign, nz * nsign);
GLStateManager.glVertex3f(x * topRadius, y * topRadius, height);
GLSMDraws.glVertex3f(x * topRadius, y * topRadius, height);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
}
// draw length lines
GLStateManager.glBegin(GL_LINES);
GLSMDraws.glBegin(GL_LINES);
for (int i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
emitNormal(x * nsign, y * nsign, nz * nsign);
GLStateManager.glVertex3f(x * baseRadius, y * baseRadius, 0.0f);
GLStateManager.glVertex3f(x * topRadius, y * topRadius, height);
GLSMDraws.glVertex3f(x * baseRadius, y * baseRadius, 0.0f);
GLSMDraws.glVertex3f(x * topRadius, y * topRadius, height);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
} else if (super.drawStyle == GLU_FILL) {
final float ds = 1.0f / slices;
final float dt = 1.0f / stacks;
@@ -119,20 +120,20 @@ public class AngelicaCylinder extends Cylinder {
r = baseRadius;
for (int j = 0; j < stacks; j++) {
float s = 0.0f;
GLStateManager.glBegin(GL_TRIANGLE_STRIP);
GLSMDraws.glBegin(GL_TRIANGLE_STRIP);
for (int i = 0; i <= slices; i++) {
final float angle = (i == slices) ? 0.0f : i * da;
x = sin(angle);
y = cos(angle);
emitNormal(x * nsign, y * nsign, nz * nsign);
emitTexCoord(s, t);
GLStateManager.glVertex3f(x * r, y * r, z);
GLSMDraws.glVertex3f(x * r, y * r, z);
emitNormal(x * nsign, y * nsign, nz * nsign);
emitTexCoord(s, t + dt);
GLStateManager.glVertex3f(x * (r + dr), y * (r + dr), z + dz);
GLSMDraws.glVertex3f(x * (r + dr), y * (r + dr), z + dz);
s += ds;
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
r += dr;
t += dt;
z += dz;
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.compat.lwjgl;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
import org.lwjgl.util.glu.Disk;
import static org.lwjgl.opengl.GL11.GL_LINE_LOOP;
@@ -23,7 +24,7 @@ public class AngelicaDisk extends Disk {
private static final float PI = (float) Math.PI;
private void emitTexCoord(float x, float y) {
if (super.textureFlag) GLStateManager.glTexCoord2f(x, y);
if (super.textureFlag) GLSMCurrentAttribs.glTexCoord2f(x, y);
}
@Override
@@ -31,7 +32,7 @@ public class AngelicaDisk extends Disk {
final float da, dr;
if (super.normals != GLU_NONE) {
GLStateManager.glNormal3f(0.0f, 0.0f, (super.orientation == GLU_OUTSIDE) ? 1.0f : -1.0f);
GLSMCurrentAttribs.glNormal3f(0.0f, 0.0f, (super.orientation == GLU_OUTSIDE) ? 1.0f : -1.0f);
}
da = 2.0f * PI / slices;
@@ -45,29 +46,29 @@ public class AngelicaDisk extends Disk {
for (int l = 0; l < loops; l++) {
final float r2 = r1 + dr;
if (super.orientation == GLU_OUTSIDE) {
GLStateManager.glBegin(GL_TRIANGLE_STRIP);
GLSMDraws.glBegin(GL_TRIANGLE_STRIP);
for (int s = 0; s <= slices; s++) {
final float a = (s == slices) ? 0.0f : s * da;
sa = sin(a);
ca = cos(a);
emitTexCoord(0.5f + sa * r2 / dtc, 0.5f + ca * r2 / dtc);
GLStateManager.glVertex2f(r2 * sa, r2 * ca);
GLSMDraws.glVertex2f(r2 * sa, r2 * ca);
emitTexCoord(0.5f + sa * r1 / dtc, 0.5f + ca * r1 / dtc);
GLStateManager.glVertex2f(r1 * sa, r1 * ca);
GLSMDraws.glVertex2f(r1 * sa, r1 * ca);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
} else {
GLStateManager.glBegin(GL_TRIANGLE_STRIP);
GLSMDraws.glBegin(GL_TRIANGLE_STRIP);
for (int s = slices; s >= 0; s--) {
final float a = (s == slices) ? 0.0f : s * da;
sa = sin(a);
ca = cos(a);
emitTexCoord(0.5f - sa * r2 / dtc, 0.5f + ca * r2 / dtc);
GLStateManager.glVertex2f(r2 * sa, r2 * ca);
GLSMDraws.glVertex2f(r2 * sa, r2 * ca);
emitTexCoord(0.5f - sa * r1 / dtc, 0.5f + ca * r1 / dtc);
GLStateManager.glVertex2f(r1 * sa, r1 * ca);
GLSMDraws.glVertex2f(r1 * sa, r1 * ca);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
r1 = r2;
}
@@ -76,56 +77,56 @@ public class AngelicaDisk extends Disk {
/* draw loops */
for (int l = 0; l <= loops; l++) {
final float r = innerRadius + l * dr;
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glBegin(GL_LINE_LOOP);
for (int s = 0; s < slices; s++) {
final float a = s * da;
GLStateManager.glVertex2f(r * sin(a), r * cos(a));
GLSMDraws.glVertex2f(r * sin(a), r * cos(a));
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
/* draw spokes */
for (int s = 0; s < slices; s++) {
final float a = s * da;
final float x = sin(a);
final float y = cos(a);
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int l = 0; l <= loops; l++) {
final float r = innerRadius + l * dr;
GLStateManager.glVertex2f(r * x, r * y);
GLSMDraws.glVertex2f(r * x, r * y);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
}
case GLU_POINT -> {
GLStateManager.glBegin(GL_POINTS);
GLSMDraws.glBegin(GL_POINTS);
for (int s = 0; s < slices; s++) {
final float a = s * da;
final float x = sin(a);
final float y = cos(a);
for (int l = 0; l <= loops; l++) {
final float r = innerRadius * l * dr;
GLStateManager.glVertex2f(r * x, r * y);
GLSMDraws.glVertex2f(r * x, r * y);
}
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
case GLU_SILHOUETTE -> {
if (innerRadius != 0.0) {
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glBegin(GL_LINE_LOOP);
for (float a = 0.0f; a < 2.0 * PI; a += da) {
final float x = innerRadius * sin(a);
final float y = innerRadius * cos(a);
GLStateManager.glVertex2f(x, y);
GLSMDraws.glVertex2f(x, y);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glBegin(GL_LINE_LOOP);
for (float a = 0; a < 2.0f * PI; a += da) {
final float x = outerRadius * sin(a);
final float y = outerRadius * cos(a);
GLStateManager.glVertex2f(x, y);
GLSMDraws.glVertex2f(x, y);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
default -> {
}
@@ -1,5 +1,7 @@
package com.gtnewhorizons.angelica.glsm.compat.lwjgl;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.lwjgl.util.glu.PartialDisk;
@@ -63,7 +65,7 @@ public class AngelicaPartialDisk extends PartialDisk {
}
switch (super.normals) {
case GLU_FLAT, GLU_SMOOTH -> GLStateManager.glNormal3f(0.0f, 0.0f, (super.orientation == GLU_OUTSIDE) ? 1.0f : -1.0f);
case GLU_FLAT, GLU_SMOOTH -> GLSMCurrentAttribs.glNormal3f(0.0f, 0.0f, (super.orientation == GLU_OUTSIDE) ? 1.0f : -1.0f);
default -> {
}
}
@@ -73,11 +75,11 @@ public class AngelicaPartialDisk extends PartialDisk {
if (innerRadius == .0f) {
finish = loops - 1;
/* Triangle strip for inner polygons */
GLStateManager.glBegin(GL_TRIANGLE_FAN);
GLSMDraws.glBegin(GL_TRIANGLE_FAN);
if (super.textureFlag) {
GLStateManager.glTexCoord2f(0.5f, 0.5f);
GLSMCurrentAttribs.glTexCoord2f(0.5f, 0.5f);
}
GLStateManager.glVertex3f(0.0f, 0.0f, 0.0f);
GLSMDraws.glVertex3f(0.0f, 0.0f, 0.0f);
radiusLow = outerRadius - deltaRadius * ((float) (loops - 1) / loops);
if (super.textureFlag) {
texLow = radiusLow / outerRadius / 2;
@@ -86,19 +88,19 @@ public class AngelicaPartialDisk extends PartialDisk {
if (super.orientation == GLU_OUTSIDE) {
for (int i = slices; i >= 0; i--) {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
}
} else {
for (int i = 0; i <= slices; i++) {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
}
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
} else {
finish = loops;
}
@@ -110,35 +112,35 @@ public class AngelicaPartialDisk extends PartialDisk {
texHigh = radiusHigh / outerRadius / 2;
}
GLStateManager.glBegin(GL_TRIANGLE_STRIP);
GLSMDraws.glBegin(GL_TRIANGLE_STRIP);
for (int i = 0; i <= slices; i++) {
if (super.orientation == GLU_OUTSIDE) {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texHigh * sinCache[i] + 0.5f, texHigh * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texHigh * sinCache[i] + 0.5f, texHigh * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusHigh * sinCache[i], radiusHigh * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusHigh * sinCache[i], radiusHigh * cosCache[i], 0.0f);
} else {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texHigh * sinCache[i] + 0.5f, texHigh * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texHigh * sinCache[i] + 0.5f, texHigh * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusHigh * sinCache[i], radiusHigh * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusHigh * sinCache[i], radiusHigh * cosCache[i], 0.0f);
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
}
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
}
case GLU_POINT -> {
GLStateManager.glBegin(GL_POINTS);
GLSMDraws.glBegin(GL_POINTS);
for (int i = 0; i < slices2; i++) {
sintemp = sinCache[i];
costemp = cosCache[i];
@@ -148,24 +150,24 @@ public class AngelicaPartialDisk extends PartialDisk {
if (super.textureFlag) {
texLow = radiusLow / outerRadius / 2;
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f);
GLSMDraws.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f);
}
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
case GLU_LINE -> {
if (innerRadius == outerRadius) {
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int i = 0; i <= slices; i++) {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(sinCache[i] / 2 + 0.5f, cosCache[i] / 2 + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(sinCache[i] / 2 + 0.5f, cosCache[i] / 2 + 0.5f);
}
GLStateManager.glVertex3f(innerRadius * sinCache[i], innerRadius * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(innerRadius * sinCache[i], innerRadius * cosCache[i], 0.0f);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
break;
}
for (int j = 0; j <= loops; j++) {
@@ -174,19 +176,19 @@ public class AngelicaPartialDisk extends PartialDisk {
texLow = radiusLow / outerRadius / 2;
}
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int i = 0; i <= slices; i++) {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
for (int i = 0; i < slices2; i++) {
sintemp = sinCache[i];
costemp = cosCache[i];
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int j = 0; j <= loops; j++) {
radiusLow = outerRadius - deltaRadius * ((float) j / loops);
if (super.textureFlag) {
@@ -194,11 +196,11 @@ public class AngelicaPartialDisk extends PartialDisk {
}
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f);
GLSMDraws.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
}
case GLU_SILHOUETTE -> {
@@ -206,17 +208,17 @@ public class AngelicaPartialDisk extends PartialDisk {
for (int i = 0; i <= slices; i += slices) {
sintemp = sinCache[i];
costemp = cosCache[i];
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int j = 0; j <= loops; j++) {
radiusLow = outerRadius - deltaRadius * ((float) j / loops);
if (super.textureFlag) {
texLow = radiusLow / outerRadius / 2;
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f);
GLSMDraws.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
}
for (int j = 0; j <= loops; j += loops) {
@@ -225,14 +227,14 @@ public class AngelicaPartialDisk extends PartialDisk {
texLow = radiusLow / outerRadius / 2;
}
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int i = 0; i <= slices; i++) {
if (super.textureFlag) {
GLStateManager.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
GLSMCurrentAttribs.glTexCoord2f(texLow * sinCache[i] + 0.5f, texLow * cosCache[i] + 0.5f);
}
GLStateManager.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
GLSMDraws.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
if (innerRadius == outerRadius) break;
}
}
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.compat.lwjgl;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
import org.lwjgl.util.glu.Sphere;
import static org.lwjgl.opengl.GL11.GL_LINE_LOOP;
@@ -30,11 +31,11 @@ public class AngelicaSphere extends Sphere {
y /= mag;
z /= mag;
}
GLStateManager.glNormal3f(x, y, z);
GLSMCurrentAttribs.glNormal3f(x, y, z);
}
private void emitTexCoord(float x, float y) {
if (super.textureFlag) GLStateManager.glTexCoord2f(x, y);
if (super.textureFlag) GLSMCurrentAttribs.glTexCoord2f(x, y);
}
@Override
@@ -54,9 +55,9 @@ public class AngelicaSphere extends Sphere {
if (super.drawStyle == GLU_FILL) {
if (!super.textureFlag) {
// draw +Z end as a triangle fan
GLStateManager.glBegin(GL_TRIANGLE_FAN);
GLStateManager.glNormal3f(0.0f, 0.0f, 1.0f);
GLStateManager.glVertex3f(0.0f, 0.0f, nsign * radius);
GLSMDraws.glBegin(GL_TRIANGLE_FAN);
GLSMCurrentAttribs.glNormal3f(0.0f, 0.0f, 1.0f);
GLSMDraws.glVertex3f(0.0f, 0.0f, nsign * radius);
for (int j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0f : j * dtheta;
x = -sin(theta) * sin(drho);
@@ -65,9 +66,9 @@ public class AngelicaSphere extends Sphere {
if (normals) {
emitNormal(x * nsign, y * nsign, z * nsign);
}
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
ds = 1.0f / slices;
@@ -84,7 +85,7 @@ public class AngelicaSphere extends Sphere {
// draw intermediate stacks as triangle strips (GL_QUAD_STRIP removed in core profile)
for (int i = imin; i < imax; i++) {
rho = i * drho;
GLStateManager.glBegin(GL_TRIANGLE_STRIP);
GLSMDraws.glBegin(GL_TRIANGLE_STRIP);
s = 0.0f;
for (int j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0f : j * dtheta;
@@ -95,7 +96,7 @@ public class AngelicaSphere extends Sphere {
emitNormal(x * nsign, y * nsign, z * nsign);
}
emitTexCoord(s, t);
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
x = -sin(theta) * sin(rho + drho);
y = cos(theta) * sin(rho + drho);
z = nsign * cos(rho + drho);
@@ -104,17 +105,17 @@ public class AngelicaSphere extends Sphere {
}
emitTexCoord(s, t - dt);
s += ds;
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
t -= dt;
}
if (!super.textureFlag) {
// draw -Z end as a triangle fan
GLStateManager.glBegin(GL_TRIANGLE_FAN);
GLStateManager.glNormal3f(0.0f, 0.0f, -1.0f);
GLStateManager.glVertex3f(0.0f, 0.0f, -radius * nsign);
GLSMDraws.glBegin(GL_TRIANGLE_FAN);
GLSMCurrentAttribs.glNormal3f(0.0f, 0.0f, -1.0f);
GLSMDraws.glVertex3f(0.0f, 0.0f, -radius * nsign);
rho = PI - drho;
s = 1.0f;
for (int j = slices; j >= 0; j--) {
@@ -124,46 +125,46 @@ public class AngelicaSphere extends Sphere {
z = nsign * cos(rho);
if (normals) emitNormal(x * nsign, y * nsign, z * nsign);
s -= ds;
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
} else if (super.drawStyle == GLU_LINE || super.drawStyle == GLU_SILHOUETTE) {
// draw stack lines
for (int i = 1; i < stacks; i++) {
rho = i * drho;
GLStateManager.glBegin(GL_LINE_LOOP);
GLSMDraws.glBegin(GL_LINE_LOOP);
for (int j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if (normals) emitNormal(x * nsign, y * nsign, z * nsign);
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
// draw slice lines
for (int j = 0; j < slices; j++) {
theta = j * dtheta;
GLStateManager.glBegin(GL_LINE_STRIP);
GLSMDraws.glBegin(GL_LINE_STRIP);
for (int i = 0; i <= stacks; i++) {
rho = i * drho;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if (normals) emitNormal(x * nsign, y * nsign, z * nsign);
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
} else if (super.drawStyle == GLU_POINT) {
// top and bottom-most points
GLStateManager.glBegin(GL_POINTS);
if (normals) GLStateManager.glNormal3f(0.0f, 0.0f, nsign);
GLStateManager.glVertex3f(0.0f, 0.0f, radius);
if (normals) GLStateManager.glNormal3f(0.0f, 0.0f, -nsign);
GLStateManager.glVertex3f(0.0f, 0.0f, -radius);
GLSMDraws.glBegin(GL_POINTS);
if (normals) GLSMCurrentAttribs.glNormal3f(0.0f, 0.0f, nsign);
GLSMDraws.glVertex3f(0.0f, 0.0f, radius);
if (normals) GLSMCurrentAttribs.glNormal3f(0.0f, 0.0f, -nsign);
GLSMDraws.glVertex3f(0.0f, 0.0f, -radius);
// loop over stacks
for (int i = 1; i < stacks - 1; i++) {
@@ -174,10 +175,10 @@ public class AngelicaSphere extends Sphere {
y = sin(theta) * sin(rho);
z = cos(rho);
if (normals) emitNormal(x * nsign, y * nsign, z * nsign);
GLStateManager.glVertex3f(x * radius, y * radius, z * radius);
GLSMDraws.glVertex3f(x * radius, y * radius, z * radius);
}
}
GLStateManager.glEnd();
GLSMDraws.glEnd();
}
}
}
@@ -1,5 +1,8 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMFramebuffer;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.texture.TextureInfoCache;
import org.lwjgl.opengl.GL11;
@@ -42,23 +45,23 @@ public class DSAARB extends DSAUnsupported {
@Override
public void texParameteri(int texture, int target, int pname, int param) {
param = GLStateManager.remapTexClamp(pname, param);
if(!GLStateManager.updateTexParameteriCache(target, texture, pname, param)) return;
param = GLSMTextures.remapTexClamp(pname, param);
if(!GLSMTextures.updateTexParameteriCache(target, texture, pname, param)) return;
RENDER_BACKEND.textureParameteri(texture, target, pname, param);
}
@Override
public void texParameterf(int texture, int target, int pname, float param) {
param = GLStateManager.remapTexClamp(pname, param);
if(!GLStateManager.updateTexParameterfCache(target, texture, pname, param)) return;
param = GLSMTextures.remapTexClamp(pname, param);
if(!GLSMTextures.updateTexParameterfCache(target, texture, pname, param)) return;
RENDER_BACKEND.textureParameterf(texture, target, pname, param);
}
@Override
public void texParameteriv(int texture, int target, int pname, IntBuffer params) {
GLStateManager.remapTexClampBuffer(pname, params);
GLSMTextures.remapTexClampBuffer(pname, params);
RENDER_BACKEND.textureParameteriv(texture, target, pname, params);
}
@@ -74,8 +77,8 @@ public class DSAARB extends DSAUnsupported {
@Override
public int getTexParameteri(int texture, int target, int pname) {
final long v = GLStateManager.lookupTexParameteri(TextureInfoCache.INSTANCE.getInfo(texture), pname);
return v != GLStateManager.TEX_PARAM_MISS ? (int) v : RENDER_BACKEND.getTextureParameteri(texture, target, pname);
final long v = GLSMTextures.lookupTexParameteri(TextureInfoCache.INSTANCE.getInfo(texture), pname);
return v != GLSMTextures.TEX_PARAM_MISS ? (int) v : RENDER_BACKEND.getTextureParameteri(texture, target, pname);
}
@Override
@@ -100,23 +103,23 @@ public class DSAARB extends DSAUnsupported {
@Override
public void bindTextureToUnit(int target, int unit, int texture) {
if(GLStateManager.getBoundTextureForServerState(unit) == texture) return;
if(GLSMTextures.getBoundTextureForServerState(unit) == texture) return;
if (texture == 0) {
super.bindTextureToUnit(target != 0 ? target : GL11.GL_TEXTURE_2D, unit, texture);
} else {
RENDER_BACKEND.bindTextureUnit(unit, texture);
final var binding = GLStateManager.getTextures().getTextureUnitBindings(unit);
final var binding = GLSMTextures.getTextures().getTextureUnitBindings(unit);
binding.beforeModify();
binding.setBinding(texture, target);
GLStateManager.trackMaxBoundTextureUnit(unit);
GLSMTextures.trackMaxBoundTextureUnit(unit);
}
}
@Override
public int bufferStorage(int target, FloatBuffer data, int usage) {
final int buffer = GLStateManager.glCreateBuffers();
GLStateManager.glNamedBufferData(buffer, data, usage);
final int buffer = GLSMBuffers.glCreateBuffers();
GLSMBuffers.glNamedBufferData(buffer, data, usage);
return buffer;
}
@@ -128,7 +131,7 @@ public class DSAARB extends DSAUnsupported {
@Override
public void framebufferTexture2D(int fb, int fbtarget, int attachment, int target, int texture, int levels) {
GLStateManager.glNamedFramebufferTexture(fb, attachment, texture, levels);
GLSMFramebuffer.glNamedFramebufferTexture(fb, attachment, texture, levels);
}
@Override
@@ -139,6 +142,6 @@ public class DSAARB extends DSAUnsupported {
@Override
public int createTexture(int target) {
return GLStateManager.glCreateTextures(target);
return GLSMTextures.glCreateTextures(target);
}
}
@@ -1,5 +1,8 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMFramebuffer;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.stacks.TextureBindingStack;
import com.gtnewhorizons.angelica.glsm.texture.TextureTargets;
@@ -17,7 +20,7 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void generateMipmaps(int texture, int target) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GLSMTextures.glBindTexture(GL11.GL_TEXTURE_2D, texture);
RENDER_BACKEND.generateMipmap(target);
}
@@ -56,40 +59,40 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void texParameteri(int texture, int target, int pname, int param) {
final int previous = bindForEdit(target, texture);
GLStateManager.glTexParameteri(target, pname, param);
GLSMTextures.glTexParameteri(target, pname, param);
restoreBinding(target, previous);
}
@Override
public void texParameterf(int texture, int target, int pname, float param) {
final int previous = bindForEdit(target, texture);
GLStateManager.glTexParameterf(target, pname, param);
GLSMTextures.glTexParameterf(target, pname, param);
restoreBinding(target, previous);
}
@Override
public void texParameteriv(int texture, int target, int pname, IntBuffer params) {
final int previous = bindForEdit(target, texture);
GLStateManager.glTexParameter(target, pname, params);
GLSMTextures.glTexParameter(target, pname, params);
restoreBinding(target, previous);
}
@Override
public void readBuffer(int framebuffer, int buffer) {
GLStateManager.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
GLSMFramebuffer.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
RENDER_BACKEND.readBuffer(buffer);
}
@Override
public void drawBuffers(int framebuffer, IntBuffer buffers) {
GLStateManager.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
GLSMFramebuffer.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
RENDER_BACKEND.drawBuffers(buffers);
}
@Override
public int getTexParameteri(int texture, int target, int pname) {
final int previous = bindForEdit(target, texture);
final int result = GLStateManager.glGetTexParameteri(target, pname);
final int result = GLSMTextures.glGetTexParameteri(target, pname);
restoreBinding(target, previous);
return result;
}
@@ -97,7 +100,7 @@ public class DSAUnsupported implements DSAAccess {
@Override
public float getTexParameterf(int texture, int target, int pname) {
final int previous = bindForEdit(target, texture);
final float result = GLStateManager.glGetTexParameterf(target, pname);
final float result = GLSMTextures.glGetTexParameterf(target, pname);
restoreBinding(target, previous);
return result;
}
@@ -114,29 +117,29 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void copyTexSubImage2D(int destTexture, int target, int i, int i1, int i2, int i3, int i4, int width, int height) {
final int previous = previous2D();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, destTexture);
GLSMTextures.glBindTexture(GL11.GL_TEXTURE_2D, destTexture);
RENDER_BACKEND.copyTexSubImage2D(target, i, i1, i2, i3, i4, width, height);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, previous);
GLSMTextures.glBindTexture(GL11.GL_TEXTURE_2D, previous);
}
@Override
public void bindTextureToUnit(int unit, int texture) {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLSMTextures.glBindTexture(GL11.GL_TEXTURE_2D, texture);
}
@Override
public void bindTextureToUnit(int target, int unit, int texture) {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLStateManager.glBindTexture(target, texture);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLSMTextures.glBindTexture(target, texture);
}
@Override
public int bufferStorage(int target, FloatBuffer data, int usage) {
final int buffer = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(target, buffer);
GLStateManager.glBufferData(target, data, usage);
GLStateManager.glBindBuffer(target, 0);
final int buffer = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(target, buffer);
GLSMBuffers.glBufferData(target, data, usage);
GLSMBuffers.glBindBuffer(target, 0);
return buffer;
}
@@ -144,28 +147,28 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void blitFramebuffer(int source, int dest, int offsetX, int offsetY, int width, int height, int offsetX2, int offsetY2, int width2, int height2,
int bufferChoice, int filter) {
GLStateManager.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, source);
GLStateManager.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, dest);
GLSMFramebuffer.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, source);
GLSMFramebuffer.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, dest);
RENDER_BACKEND.blitFramebuffer(offsetX, offsetY, width, height, offsetX2, offsetY2, width2, height2, bufferChoice, filter);
}
@Override
public void framebufferTexture2D(int fb, int fbtarget, int attachment, int target, int texture, int levels) {
GLStateManager.glBindFramebuffer(fbtarget, fb);
GLStateManager.glFramebufferTexture2D(fbtarget, attachment, target, texture, levels);
GLSMFramebuffer.glBindFramebuffer(fbtarget, fb);
GLSMFramebuffer.glFramebufferTexture2D(fbtarget, attachment, target, texture, levels);
}
@Override
public int createFramebuffer() {
final int framebuffer = GLStateManager.glGenFramebuffers();
GLStateManager.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
final int framebuffer = GLSMFramebuffer.glGenFramebuffers();
GLSMFramebuffer.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
return framebuffer;
}
@Override
public int createTexture(int target) {
final int texture = GLStateManager.glGenTextures();
GLStateManager.glBindTexture(target, texture);
final int texture = GLSMTextures.glGenTextures();
GLSMTextures.glBindTexture(target, texture);
return texture;
}
@@ -175,7 +178,7 @@ public class DSAUnsupported implements DSAAccess {
private static int previous2D() {
if (GLStateManager.isCachingEnabled()) {
final TextureBindingStack slot = GLStateManager.getTextures().getTextureUnitBindings(GLStateManager.getActiveTextureUnit());
final TextureBindingStack slot = GLSMTextures.getTextures().getTextureUnitBindings(GLSMTextures.getActiveTextureUnit());
final int t = slot.getTarget();
if (t == 0 || t == GL11.GL_TEXTURE_2D) return slot.getBinding();
}
@@ -184,13 +187,13 @@ public class DSAUnsupported implements DSAAccess {
private static int bindForEdit(int target, int texture) {
final int previous = previousBinding(target);
if (target == GL11.GL_TEXTURE_2D) GLStateManager.glBindTexture(target, texture);
if (target == GL11.GL_TEXTURE_2D) GLSMTextures.glBindTexture(target, texture);
else RENDER_BACKEND.bindTexture(target, texture);
return previous;
}
private static void restoreBinding(int target, int previous) {
if (target == GL11.GL_TEXTURE_2D) GLStateManager.glBindTexture(target, previous);
if (target == GL11.GL_TEXTURE_2D) GLSMTextures.glBindTexture(target, previous);
else RENDER_BACKEND.bindTexture(target, previous);
}
}
@@ -1,6 +1,12 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBlend;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMEnable;
import com.gtnewhorizons.angelica.glsm.GLSMLighting;
import com.gtnewhorizons.angelica.glsm.GLSMMatrices;
import com.gtnewhorizons.angelica.glsm.GLSMPrograms;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL11;
@@ -24,14 +30,14 @@ public final class CombinedGlint {
}
public static boolean begin(Matrix4fc secondTextureMatrix) {
if (active || GLStateManager.getActiveProgram() != 0 || GLStateManager.getLightingState().isEnabled() || GLStateManager.getColorSumState().isEnabled() || !GLStateManager.glIsEnabled(GL11.GL_BLEND)) return false;
final var blend = GLStateManager.getBlendState();
if (active || GLSMPrograms.getActiveProgram() != 0 || GLSMLighting.getLightingState().isEnabled() || GLSMCurrentAttribs.getColorSumState().isEnabled() || !GLSMEnable.glIsEnabled(GL11.GL_BLEND)) return false;
final var blend = GLSMBlend.getBlendState();
final boolean lastAlpha = blend.getSrcAlpha() == GL11.GL_ONE && blend.getDstAlpha() == GL11.GL_ZERO && blend.getEquationAlpha() == GL14.GL_FUNC_ADD;
final boolean preserveAlpha = blend.getSrcAlpha() == GL11.GL_ZERO && blend.getDstAlpha() == GL11.GL_ONE && (blend.getEquationAlpha() == GL14.GL_FUNC_ADD || blend.getEquationAlpha() == GL14.GL_FUNC_REVERSE_SUBTRACT);
if (blend.getSrcRgb() != GL11.GL_SRC_COLOR || blend.getDstRgb() != GL11.GL_ONE
|| (!lastAlpha && !preserveAlpha && (blend.getSrcAlpha() != GL11.GL_SRC_COLOR || blend.getDstAlpha() != GL11.GL_ONE || blend.getEquationAlpha() != blend.getEquationRgb()))
|| (blend.getEquationRgb() != GL14.GL_FUNC_ADD && blend.getEquationRgb() != GL14.GL_FUNC_REVERSE_SUBTRACT)) return false;
final var textures = GLStateManager.getTextures();
final var textures = GLSMTextures.getTextures();
if (!textures.getTextureUnitStates(0).isEnabled() || textures.getTextureUnitBindings(0).getBinding() == 0 || textures.getTexEnvState(0).mode != GL11.GL_MODULATE) return false;
if (textures.getTextureUnitStates(1).isEnabled() && textures.getTextureUnitBindings(1).getBinding() != 0 && textures.getTexEnvState(1).mode != GL11.GL_MODULATE) return false;
for (int unit = 2; unit < 4; unit++) {
@@ -41,7 +47,7 @@ public final class CombinedGlint {
relative.set(secondTextureMatrix).mul(inverse);
if (!relative.isFinite()) return false;
savedMatrix.set(textures.getTextureUnitMatrix(3));
GLStateManager.setTextureMatrix(3, relative);
GLSMMatrices.setTextureMatrix(3, relative);
replaceAlpha = lastAlpha;
active = true;
return true;
@@ -50,6 +56,6 @@ public final class CombinedGlint {
public static void end() {
if (!active) return;
active = false;
GLStateManager.setTextureMatrix(3, savedMatrix);
GLSMMatrices.setTextureMatrix(3, savedMatrix);
}
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import org.lwjgl.opengl.GL11;
public final class CubeInstancedAttribs {
@@ -14,8 +14,8 @@ public final class CubeInstancedAttribs {
public static void pointInstanceAttribs(long base) {
InstancedAttribs.pointHead(base, STRIDE);
GLStateManager.glVertexAttribPointer(LOC_LIGHTMAP_SCALE, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_LIGHTMAP_SCALE);
GLStateManager.glVertexAttribPointer(LOC_CUBE_TEX, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_CUBE_TEX);
GLSMVertexInput.glVertexAttribPointer(LOC_LIGHTMAP_SCALE, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_LIGHTMAP_SCALE);
GLSMVertexInput.glVertexAttribPointer(LOC_CUBE_TEX, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_CUBE_TEX);
}
static void enableInstanceArrays() {
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMLighting;
import com.gtnewhorizons.angelica.glsm.GLSMMatrices;
import com.gtnewhorizons.angelica.glsm.states.LightState;
import com.gtnewhorizons.angelica.glsm.states.MaterialState;
import org.joml.Matrix3f;
@@ -20,23 +21,23 @@ public final class FFPVertexLighting {
public static boolean modulatesVertexColor(Vector3f destFactor) {
destFactor.set(1.0f);
if (!GLStateManager.getLightingState().isEnabled()) return false;
if (!GLStateManager.getColorMaterial().isEnabled()) return false;
if (VertexKey.encodeColorMaterialMode(GLStateManager.getColorMaterialParameter().getValue()) != VertexKey.CM_AMBIENT_AND_DIFFUSE) return false;
if (!GLSMLighting.getLightingState().isEnabled()) return false;
if (!GLSMLighting.getColorMaterial().isEnabled()) return false;
if (VertexKey.encodeColorMaterialMode(GLSMLighting.getColorMaterialParameter().getValue()) != VertexKey.CM_AMBIENT_AND_DIFFUSE) return false;
final MaterialState material = GLStateManager.getFrontMaterial();
final MaterialState material = GLSMLighting.getFrontMaterial();
if (material.emission.x != 0.0f || material.emission.y != 0.0f || material.emission.z != 0.0f)
return false;
final boolean materialHasSpecular = material.shininess > 0.0f && (material.specular.x != 0.0f || material.specular.y != 0.0f || material.specular.z != 0.0f);
final Vector4f lightModelAmbient = GLStateManager.getLightModel().ambient;
final Vector4f lightModelAmbient = GLSMLighting.getLightModel().ambient;
float r = lightModelAmbient.x;
float g = lightModelAmbient.y;
float b = lightModelAmbient.z;
final var lightEnables = GLStateManager.getLightStates();
final var lightData = GLStateManager.getLightDataStates();
final var lightEnables = GLSMLighting.getLightStates();
final var lightData = GLSMLighting.getLightDataStates();
boolean normalReady = false;
for (int i = 0; i < VertexKey.FFP_LIGHT_COUNT; i++) {
@@ -61,12 +62,12 @@ public final class FFPVertexLighting {
}
private static void transformCurrentNormal() {
GLStateManager.getModelViewMatrix().normal(scratchNormalMat);
GLSMMatrices.getModelViewMatrix().normal(scratchNormalMat);
scratchNormal.set(ShaderManager.getCurrentNormal());
scratchNormalMat.transform(scratchNormal);
if (GLStateManager.getNormalizeState().isEnabled()) {
if (GLSMLighting.getNormalizeState().isEnabled()) {
scratchNormal.normalize();
} else if (GLStateManager.getRescaleNormalState().isEnabled()) {
} else if (GLSMLighting.getRescaleNormalState().isEnabled()) {
scratchNormal.mul(Uniforms.rescaleFactor(scratchNormalMat, scratchVec));
}
}
@@ -75,7 +76,7 @@ public final class FFPVertexLighting {
if (light.position.w == 0.0f) {
scratchLightVec.set(light.position.x, light.position.y, light.position.z);
} else {
scratchEyePos.set(0.0f, 0.0f, 0.0f, 1.0f).mul(GLStateManager.getModelViewMatrix());
scratchEyePos.set(0.0f, 0.0f, 0.0f, 1.0f).mul(GLSMMatrices.getModelViewMatrix());
scratchLightVec.set(light.position.x - scratchEyePos.x, light.position.y - scratchEyePos.y, light.position.z - scratchEyePos.z);
}
return scratchLightVec.normalize();
@@ -3,6 +3,9 @@ package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizon.gtnhlib.client.renderer.cel.api.util.NormI8;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.hooks.BatchStateGuard;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
@@ -213,24 +216,24 @@ public final class FfpExtendedAttribs {
final int extVbo = getOrBuild(h, pos, uv, normal, first, count, extPrim, mode);
if (extVbo == 0) return false;
final int savedVBO = GLStateManager.getBoundVBO();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, extVbo);
final int savedVBO = GLSMBuffers.getBoundVBO();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, extVbo);
ImmediateExtendedAttribHandler.setupExtAttribPointers(0L, ImmediateExtendedAttribHandler.EXT_STRIDE);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
return true;
}
public static void unbind() {
GLStateManager.glDisableVertexAttribArray(ImmediateExtendedAttribHandler.LOC_MID_TEX);
GLStateManager.glDisableVertexAttribArray(ImmediateExtendedAttribHandler.LOC_TANGENT);
GLSMVertexInput.glDisableVertexAttribArray(ImmediateExtendedAttribHandler.LOC_MID_TEX);
GLSMVertexInput.glDisableVertexAttribArray(ImmediateExtendedAttribHandler.LOC_TANGENT);
setNeutralCurrentValues();
}
public static void setNeutralCurrentValues() {
BatchStateGuard.suspend();
try {
GLStateManager.glVertexAttrib2f(ImmediateExtendedAttribHandler.LOC_MID_TEX, 0.5f, 0.5f);
GLStateManager.glVertexAttrib4f(ImmediateExtendedAttribHandler.LOC_TANGENT, 1.0f, 0.0f, 0.0f, 1.0f);
GLSMCurrentAttribs.glVertexAttrib2f(ImmediateExtendedAttribHandler.LOC_MID_TEX, 0.5f, 0.5f);
GLSMCurrentAttribs.glVertexAttrib4f(ImmediateExtendedAttribHandler.LOC_TANGENT, 1.0f, 0.0f, 0.0f, 1.0f);
} finally {
BatchStateGuard.resume();
}
@@ -372,22 +375,22 @@ public final class FfpExtendedAttribs {
final int newCap = Math.min(MAX_EXT_VERTS, Math.max(neededVerts, buf.capacityVerts * 2));
beginInternalGl();
try {
final int vbo = GLStateManager.glGenBuffers();
final int vbo = GLSMBuffers.glGenBuffers();
if (vbo == 0) return false;
final int savedVBO = GLStateManager.getBoundVBO();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, (long) newCap * extStride, GL15.GL_STATIC_DRAW);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
final int savedVBO = GLSMBuffers.getBoundVBO();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, (long) newCap * extStride, GL15.GL_STATIC_DRAW);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
if (buf.vbo != 0) {
final int savedRead = GLStateManager.getBoundCopyReadBuffer();
final int savedWrite = GLStateManager.getBoundCopyWriteBuffer();
GLStateManager.glBindBuffer(GL31.GL_COPY_READ_BUFFER, buf.vbo);
GLStateManager.glBindBuffer(GL31.GL_COPY_WRITE_BUFFER, vbo);
GLStateManager.glCopyBufferSubData(GL31.GL_COPY_READ_BUFFER, GL31.GL_COPY_WRITE_BUFFER, 0L, 0L,
final int savedRead = GLSMBuffers.getBoundCopyReadBuffer();
final int savedWrite = GLSMBuffers.getBoundCopyWriteBuffer();
GLSMBuffers.glBindBuffer(GL31.GL_COPY_READ_BUFFER, buf.vbo);
GLSMBuffers.glBindBuffer(GL31.GL_COPY_WRITE_BUFFER, vbo);
GLSMBuffers.glCopyBufferSubData(GL31.GL_COPY_READ_BUFFER, GL31.GL_COPY_WRITE_BUFFER, 0L, 0L,
(long) buf.capacityVerts * extStride);
GLStateManager.glBindBuffer(GL31.GL_COPY_READ_BUFFER, savedRead);
GLStateManager.glBindBuffer(GL31.GL_COPY_WRITE_BUFFER, savedWrite);
GLStateManager.glDeleteBuffers(buf.vbo);
GLSMBuffers.glBindBuffer(GL31.GL_COPY_READ_BUFFER, savedRead);
GLSMBuffers.glBindBuffer(GL31.GL_COPY_WRITE_BUFFER, savedWrite);
GLSMBuffers.glDeleteBuffers(buf.vbo);
}
buf.vbo = vbo;
buf.capacityVerts = newCap;
@@ -433,11 +436,11 @@ public final class FfpExtendedAttribs {
beginInternalGl();
try {
final int savedVBO = GLStateManager.getBoundVBO();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, extVbo);
final int savedVBO = GLSMBuffers.getBoundVBO();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, extVbo);
ext.position(0).limit(count * extStride);
GLStateManager.glBufferSubData(GL15.GL_ARRAY_BUFFER, (long) first * extStride, ext);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMBuffers.glBufferSubData(GL15.GL_ARRAY_BUFFER, (long) first * extStride, ext);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
} finally {
endInternalGl();
}
@@ -454,10 +457,10 @@ public final class FfpExtendedAttribs {
final int bytes = (count - 1) * stride + elementBytes;
final ByteBuffer dst = memAlloc(bytes).order(ByteOrder.nativeOrder());
dst.position(0).limit(bytes);
final int savedVBO = GLStateManager.getBoundVBO();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, a.vboId);
final int savedVBO = GLSMBuffers.getBoundVBO();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, a.vboId);
RENDER_BACKEND.getBufferSubData(GL15.GL_ARRAY_BUFFER, a.offset + (long) first * stride, dst);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
dst.position(0).limit(bytes);
return dst;
}
@@ -484,7 +487,7 @@ public final class FfpExtendedAttribs {
beginInternalGl();
try {
for (int i = 0; i < vbos.size(); i++) {
GLStateManager.glDeleteBuffers(vbos.getInt(i));
GLSMBuffers.glDeleteBuffers(vbos.getInt(i));
}
} finally {
endInternalGl();
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import org.lwjgl.opengl.GL11;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.memPutFloat;
@@ -68,20 +68,20 @@ public final class InstancedAttribs {
public static void pointHead(long base, int stride) {
for (int r = 0; r < 3; r++) {
GLStateManager.glVertexAttribPointer(LOC_ROW0 + r, 4, GL11.GL_FLOAT, false, stride, base + OFFSET_ROWS + r * 16L);
GLSMVertexInput.glVertexAttribPointer(LOC_ROW0 + r, 4, GL11.GL_FLOAT, false, stride, base + OFFSET_ROWS + r * 16L);
}
GLStateManager.glVertexAttribPointer(LOC_COLOR, 4, GL11.GL_UNSIGNED_BYTE, true, stride, base + OFFSET_COLOR);
GLStateManager.glVertexAttribPointer(LOC_OVERLAY, 4, GL11.GL_UNSIGNED_BYTE, true, stride, base + OFFSET_OVERLAY);
GLSMVertexInput.glVertexAttribPointer(LOC_COLOR, 4, GL11.GL_UNSIGNED_BYTE, true, stride, base + OFFSET_COLOR);
GLSMVertexInput.glVertexAttribPointer(LOC_OVERLAY, 4, GL11.GL_UNSIGNED_BYTE, true, stride, base + OFFSET_OVERLAY);
pointEntityIds(LOC_ENTITY, stride, base + OFFSET_ENTITY);
}
public static void pointEntityIds(int location, int stride, long offset) {
GLStateManager.glVertexAttribPointer(location, 4, GL11.GL_UNSIGNED_SHORT, true, stride, offset);
GLSMVertexInput.glVertexAttribPointer(location, 4, GL11.GL_UNSIGNED_SHORT, true, stride, offset);
}
public static void pointTemplate(long base) {
pointHead(base, STRIDE);
GLStateManager.glVertexAttribPointer(LOC_LIGHTMAP, 2, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_LIGHTMAP);
GLSMVertexInput.glVertexAttribPointer(LOC_LIGHTMAP, 2, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_LIGHTMAP);
}
public static void enableHeadArrays() {
@@ -91,8 +91,8 @@ public final class InstancedAttribs {
}
static void enableInstanced(int loc) {
GLStateManager.glEnableVertexAttribArray(loc);
GLStateManager.glVertexAttribDivisor(loc, 1);
GLSMVertexInput.glEnableVertexAttribArray(loc);
GLSMVertexInput.glVertexAttribDivisor(loc, 1);
}
private InstancedAttribs() {}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import org.lwjgl.opengl.GL11;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.memPutFloat;
@@ -20,10 +20,10 @@ public final class ParticleInstancedAttribs {
public static final int STRIDE = 48;
public static void pointInstanceAttribs(long base) {
GLStateManager.glVertexAttribPointer(LOC_CENTER_HALF, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_CENTER_HALF);
GLStateManager.glVertexAttribPointer(LOC_UV, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_UV);
GLStateManager.glVertexAttribPointer(LOC_COLOR, 4, GL11.GL_UNSIGNED_BYTE, true, STRIDE, base + OFFSET_COLOR);
GLStateManager.glVertexAttribPointer(LOC_LIGHTMAP, 2, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_LIGHTMAP);
GLSMVertexInput.glVertexAttribPointer(LOC_CENTER_HALF, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_CENTER_HALF);
GLSMVertexInput.glVertexAttribPointer(LOC_UV, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_UV);
GLSMVertexInput.glVertexAttribPointer(LOC_COLOR, 4, GL11.GL_UNSIGNED_BYTE, true, STRIDE, base + OFFSET_COLOR);
GLSMVertexInput.glVertexAttribPointer(LOC_LIGHTMAP, 2, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_LIGHTMAP);
}
static void enableInstanceArrays() {
@@ -3,7 +3,8 @@ package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizon.gtnhlib.client.renderer.cel.api.util.NormI8;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.hooks.ImmediateExtendedAttribHandler;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
@@ -76,11 +77,11 @@ public final class ParticleQuadMesh {
written = true;
write(memAddress0(staging), rotX, rotXZ, rotZ, rotYZ, rotXY);
final int savedVBO = GLStateManager.getBoundVBO();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
final int savedVBO = GLSMBuffers.getBoundVBO();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
staging.position(0).limit(VERTEX_COUNT * VERTEX_STRIDE);
GLStateManager.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0L, staging);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMBuffers.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0L, staging);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
}
private static void write(long dst, float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) {
@@ -116,13 +117,13 @@ public final class ParticleQuadMesh {
}
private static void build() {
final int savedVAO = GLStateManager.getBoundVAO();
final int savedVBO = GLStateManager.getBoundVBO();
vao = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(vao);
vbo = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, (long) VERTEX_COUNT * VERTEX_STRIDE, GL15.GL_DYNAMIC_DRAW);
final int savedVAO = GLSMVertexInput.getBoundVAO();
final int savedVBO = GLSMBuffers.getBoundVBO();
vao = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(vao);
vbo = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, (long) VERTEX_COUNT * VERTEX_STRIDE, GL15.GL_DYNAMIC_DRAW);
attrib(VertexFormatElement.Usage.POSITION.getAttributeLocation(), 3, GL11.GL_FLOAT, false, OFFSET_OFFSET);
attrib(VertexFormatElement.Usage.PRIMARY_UV.getAttributeLocation(), 2, GL11.GL_FLOAT, false, OFFSET_CORNER);
@@ -130,25 +131,25 @@ public final class ParticleQuadMesh {
ParticleInstancedAttribs.enableInstanceArrays();
GLStateManager.glBindVertexArray(savedVAO);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMVertexInput.glBindVertexArray(savedVAO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
if (staging == null) staging = memAlloc(VERTEX_COUNT * VERTEX_STRIDE);
written = false;
}
private static void attrib(int loc, int size, int type, boolean normalized, int offset) {
GLStateManager.glEnableVertexAttribArray(loc);
GLStateManager.glVertexAttribPointer(loc, size, type, normalized, VERTEX_STRIDE, offset);
GLSMVertexInput.glEnableVertexAttribArray(loc);
GLSMVertexInput.glVertexAttribPointer(loc, size, type, normalized, VERTEX_STRIDE, offset);
}
public static void delete() {
if (vbo != 0) {
GLStateManager.glDeleteBuffers(vbo);
GLSMBuffers.glDeleteBuffers(vbo);
vbo = 0;
}
if (vao != 0) {
GLStateManager.glDeleteVertexArrays(vao);
GLSMVertexInput.glDeleteVertexArrays(vao);
vao = 0;
}
if (staging != null) {
@@ -3,6 +3,7 @@ package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.config.SystemProperties;
import com.gtnewhorizons.angelica.glsm.CompatShaderTransformer;
import com.gtnewhorizons.angelica.glsm.GLDebug;
import com.gtnewhorizons.angelica.glsm.GLSMPrograms;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import com.gtnewhorizons.angelica.glsm.backend.RenderBackend;
@@ -45,7 +46,7 @@ public class Program {
}
public void destroy() {
GLStateManager.glDeleteProgram(programId);
GLSMPrograms.glDeleteProgram(programId);
}
/**
@@ -93,7 +94,7 @@ public class Program {
backend.uniformBlockBinding(program, blockIndex, FFPUniformBlock.BINDING_POINT);
}
final int previousProgram = GLStateManager.getActiveProgram();
final int previousProgram = GLSMPrograms.getActiveProgram();
backend.useProgram(program);
for (int i = 0; i < 4; i++) {
if (ffpProgram.locSampler[i] != -1) backend.uniform1i(ffpProgram.locSampler[i], i);
@@ -5,6 +5,7 @@ import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
import com.gtnewhorizons.angelica.config.SystemProperties;
import com.gtnewhorizons.angelica.glsm.CompatUniformManager;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.hooks.DeferredBlendHandler;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
@@ -132,14 +133,14 @@ public final class ShaderManager {
lastBoundProgramId = -1;
currentVertexKeyPacked = Long.MIN_VALUE;
currentFKLen = 0;
GLStateManager.forceAttribDefaultsDirty();
GLSMCurrentAttribs.forceAttribDefaultsDirty();
}
public void preDraw(GLContextState glCtx) {
GLSMHooks.resolvePendingProgram();
final DeferredBlendHandler bh = GLSMHooks.blendHandler;
if (bh != null) bh.flushDeferredBlend();
GLStateManager.flushEntityIds(glCtx);
GLSMCurrentAttribs.flushEntityIds(glCtx);
// Handle FFP & Iris uniforms
final int currentProgramId = glCtx.activeProgram;
@@ -154,7 +155,7 @@ public final class ShaderManager {
final boolean hasNormal = (vertexFlags & VertexFlags.NORMAL_BIT) != 0;
final boolean hasTexCoord = (vertexFlags & VertexFlags.TEXTURE_BIT) != 0;
final boolean hasLightmap = (vertexFlags & VertexFlags.BRIGHTNESS_BIT) != 0;
GLStateManager.flushDeferredVertexAttribs(glCtx, hasColor, hasNormal, hasTexCoord, hasLightmap);
GLSMCurrentAttribs.flushDeferredVertexAttribs(glCtx, hasColor, hasNormal, hasTexCoord, hasLightmap);
if (!active) return;
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.ClipPlaneState;
import com.gtnewhorizons.angelica.glsm.states.FogState;
@@ -225,7 +226,7 @@ public class Uniforms {
ring = new UniformRingBuffer(RING_CAPACITY, FFPUniformBlock.SIZE);
}
final int offset = ring.writeBlock(staging);
GLStateManager.glBindBufferRange(GL31.GL_UNIFORM_BUFFER, FFPUniformBlock.BINDING_POINT,
GLSMBuffers.glBindBufferRange(GL31.GL_UNIFORM_BUFFER, FFPUniformBlock.BINDING_POINT,
ring.getBufferId(), offset, FFPUniformBlock.SIZE);
bound = true;
blockWrites++;
@@ -3,7 +3,8 @@ package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizon.gtnhlib.client.renderer.cel.api.util.NormI8;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.hooks.ImmediateExtendedAttribHandler;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
@@ -113,19 +114,19 @@ public final class UnitCubeMesh {
}
private static void build() {
final int savedVAO = GLStateManager.getBoundVAO();
final int savedVBO = GLStateManager.getBoundVBO();
vao = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(vao);
vbo = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
final int savedVAO = GLSMVertexInput.getBoundVAO();
final int savedVBO = GLSMBuffers.getBoundVBO();
vao = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(vao);
vbo = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
final int bytes = VERTEX_COUNT * VERTEX_STRIDE;
final ByteBuffer data = memAlloc(bytes);
try {
write(memAddress0(data));
data.position(0).limit(bytes);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW);
} finally {
memFree(data);
}
@@ -139,22 +140,22 @@ public final class UnitCubeMesh {
CubeInstancedAttribs.enableInstanceArrays();
GLStateManager.glBindVertexArray(savedVAO);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMVertexInput.glBindVertexArray(savedVAO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
}
private static void attrib(int loc, int size, int type, boolean normalized, int offset) {
GLStateManager.glEnableVertexAttribArray(loc);
GLStateManager.glVertexAttribPointer(loc, size, type, normalized, VERTEX_STRIDE, offset);
GLSMVertexInput.glEnableVertexAttribArray(loc);
GLSMVertexInput.glVertexAttribPointer(loc, size, type, normalized, VERTEX_STRIDE, offset);
}
public static void delete() {
if (vbo != 0) {
GLStateManager.glDeleteBuffers(vbo);
GLSMBuffers.glDeleteBuffers(vbo);
vbo = 0;
}
if (vao != 0) {
GLStateManager.glDeleteVertexArrays(vao);
GLSMVertexInput.glDeleteVertexArrays(vao);
vao = 0;
}
}
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLTypes;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
@@ -630,8 +631,8 @@ public final class VAOManager {
clientArraysVBO = RENDER_BACKEND.genBuffers();
}
final int savedVBO = GLStateManager.getBoundVBO();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, clientArraysVBO);
final int savedVBO = GLSMBuffers.getBoundVBO();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, clientArraysVBO);
if (totalBytes > clientArraysVBOCapacity) {
int newCap = Math.max(4096, clientArraysVBOCapacity);
@@ -651,7 +652,7 @@ public final class VAOManager {
}
}
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, savedVBO);
}
@@ -3,6 +3,8 @@ package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizon.gtnhlib.client.renderer.MatrixHelper;
import com.gtnewhorizons.angelica.glsm.DisplayListManager;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMRasterizer;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.TexGenState;
import com.gtnewhorizons.angelica.glsm.states.TextureUnitArray;
@@ -230,11 +232,11 @@ public final class VertexKey {
if (hasTexCoord) bits |= (1L << BIT_HAS_VERTEX_TEX);
if (hasLightmap) bits |= (1L << BIT_HAS_VERTEX_LIGHTMAP);
if (GLStateManager.consumeUnit23TexCoordSetDuringDraw(glCtx) && hasTexCoord) {
if (GLSMCurrentAttribs.consumeUnit23TexCoordSetDuringDraw(glCtx) && hasTexCoord) {
bits |= (1L << BIT_UNIT23_UV_FROM_UNIT0);
}
if (GLStateManager.anyClipPlaneEnabled(glCtx)) {
if (GLSMRasterizer.anyClipPlaneEnabled(glCtx)) {
bits |= (1L << BIT_CLIP_PLANES);
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import org.lwjgl.opengl.GL11;
@@ -19,9 +19,9 @@ public final class WeatherInstancedAttribs {
public static final int STRIDE = 48;
public static void pointInstanceAttribs(long base) {
GLStateManager.glVertexAttribPointer(LOC_COLUMN_SPAN, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_COLUMN_SPAN);
GLStateManager.glVertexAttribPointer(LOC_JITTER, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_JITTER);
GLStateManager.glVertexAttribPointer(LOC_PARAMS, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_PARAMS);
GLSMVertexInput.glVertexAttribPointer(LOC_COLUMN_SPAN, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_COLUMN_SPAN);
GLSMVertexInput.glVertexAttribPointer(LOC_JITTER, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_JITTER);
GLSMVertexInput.glVertexAttribPointer(LOC_PARAMS, 4, GL11.GL_FLOAT, false, STRIDE, base + OFFSET_PARAMS);
}
static void enableInstanceArrays() {
@@ -2,7 +2,8 @@ package com.gtnewhorizons.angelica.glsm.ffp;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
@@ -32,37 +33,37 @@ public final class WeatherQuadMesh {
for (float corner : CORNERS) data.putFloat(corner);
data.flip();
vao = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(vao);
vbo = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW);
vao = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(vao);
vbo = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW);
final int corner = VertexFormatElement.Usage.PRIMARY_UV.getAttributeLocation();
GLStateManager.glEnableVertexAttribArray(corner);
GLStateManager.glVertexAttribPointer(corner, 2, GL11.GL_FLOAT, false, 2 * Float.BYTES, 0L);
GLSMVertexInput.glEnableVertexAttribArray(corner);
GLSMVertexInput.glVertexAttribPointer(corner, 2, GL11.GL_FLOAT, false, 2 * Float.BYTES, 0L);
WeatherInstancedAttribs.enableInstanceArrays();
GLStateManager.glBindVertexArray(0);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glBindVertexArray(0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
return vao;
}
public static void bindInstanceBuffer(int bufferId) {
GLStateManager.glBindVertexArray(vao());
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
GLSMVertexInput.glBindVertexArray(vao());
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
WeatherInstancedAttribs.pointInstanceAttribs(0L);
GLStateManager.glBindVertexArray(0);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glBindVertexArray(0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public static void delete() {
if (vbo != 0) {
GLStateManager.glDeleteBuffers(vbo);
GLSMBuffers.glDeleteBuffers(vbo);
vbo = 0;
}
if (vao != 0) {
GLStateManager.glDeleteVertexArrays(vao);
GLSMVertexInput.glDeleteVertexArrays(vao);
vao = 0;
}
}
@@ -3,6 +3,7 @@ package com.gtnewhorizons.angelica.glsm.hooks;
import com.gtnewhorizons.angelica.glsm.CaptureGate;
import com.gtnewhorizons.angelica.glsm.DisplayListManager;
import com.gtnewhorizons.angelica.glsm.GLDebug;
import com.gtnewhorizons.angelica.glsm.GLSMTextureLifetime;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.backend.BackendManager;
@@ -26,7 +27,7 @@ public final class FrameHooks {
}
public static void frameEnd() {
GLStateManager.onFrameEnd();
GLSMTextureLifetime.onFrameEnd();
popFrameGroup();
RENDER_BACKEND.onFrameEnd();
}
@@ -2,7 +2,7 @@ package com.gtnewhorizons.angelica.glsm.hooks;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.ffp.InstancedAttribs;
import org.lwjgl.opengl.GL11;
@@ -65,14 +65,14 @@ public interface ImmediateExtendedAttribHandler {
}
static void setupExtAttribPointers(long baseOffset, int stride) {
GLStateManager.glEnableVertexAttribArray(LOC_MID_TEX);
GLStateManager.glVertexAttribPointer(LOC_MID_TEX, 2, GL11.GL_FLOAT, false, stride, baseOffset);
GLStateManager.glEnableVertexAttribArray(LOC_TANGENT);
GLStateManager.glVertexAttribPointer(LOC_TANGENT, 4, GL11.GL_BYTE, true, stride, baseOffset + 8);
GLSMVertexInput.glEnableVertexAttribArray(LOC_MID_TEX);
GLSMVertexInput.glVertexAttribPointer(LOC_MID_TEX, 2, GL11.GL_FLOAT, false, stride, baseOffset);
GLSMVertexInput.glEnableVertexAttribArray(LOC_TANGENT);
GLSMVertexInput.glVertexAttribPointer(LOC_TANGENT, 4, GL11.GL_BYTE, true, stride, baseOffset + 8);
}
static void setupEntityIdsPointer(long offset, int stride) {
GLStateManager.glEnableVertexAttribArray(LOC_ENTITY_IDS);
GLSMVertexInput.glEnableVertexAttribArray(LOC_ENTITY_IDS);
InstancedAttribs.pointEntityIds(LOC_ENTITY_IDS, stride, offset);
}
}
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.glsm.hooks;
import com.gtnewhorizons.angelica.glsm.DisplayListManager;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import com.gtnewhorizons.angelica.glsm.backend.BackendManager;
@@ -26,12 +27,12 @@ public final class TextureUtilHooks {
private TextureUtilHooks() {}
public static void setMaxLevel(int mipmapLevels) {
GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, mipmapLevels);
GLSMTextures.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, mipmapLevels);
}
public static void captureBoundFilterTexture() {
final GLContextState ctx = GLStateManager.ctx();
final int id = GLStateManager.getBoundTextureForServerState();
final int id = GLSMTextures.getBoundTextureForServerState();
ctx.savedFilterTextureId = id;
final TextureInfo info = TextureInfoCache.INSTANCE.getInfo(id);
if (info != null) {
@@ -78,8 +79,8 @@ public final class TextureUtilHooks {
RenderSystem.texParameteri(id, GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, min);
RenderSystem.texParameteri(id, GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mag);
} else {
GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, min);
GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mag);
GLSMTextures.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, min);
GLSMTextures.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mag);
}
}
@@ -88,7 +89,7 @@ public final class TextureUtilHooks {
if (id != 0 && DisplayListManager.getRecordMode() == DisplayListManager.RecordMode.NONE) {
RenderSystem.texParameterf(id, GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
} else {
GLStateManager.glTexParameterf(GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
GLSMTextures.glTexParameterf(GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
}
}
@@ -116,7 +117,7 @@ public final class TextureUtilHooks {
/** TextureUtil.func_152777_a(false, false, 1) without using vanilla's single save slot, which the caller may hold. */
public static void forceNearestFilter() {
final int id = GLStateManager.getBoundTextureForServerState();
final int id = GLSMTextures.getBoundTextureForServerState();
final TextureInfo info = id != 0 ? TextureInfoCache.INSTANCE.getInfo(id) : null;
if (info == null) {
nearestTexture = 0;
@@ -143,9 +144,9 @@ public final class TextureUtilHooks {
RenderSystem.texParameteri(id, GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mag);
if (anisotropic) RenderSystem.texParameterf(id, GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
} else {
GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, min);
GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mag);
if (anisotropic) GLStateManager.glTexParameterf(GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
GLSMTextures.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, min);
GLSMTextures.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mag);
if (anisotropic) GLSMTextures.glTexParameterf(GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
}
}
}
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.loading;
import com.gtnewhorizons.angelica.glsm.redirect.GLSMRedirector;
import com.gtnewhorizons.angelica.glsm.redirect.LegacyRewriter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@@ -30,6 +31,14 @@ public class ModRedirector {
this.allExclusions = exclusions.toArray(new String[0]);
}
public void setLegacyHint(String hint) {
core.setLegacyHint(hint);
}
public void setLegacyRewriter(LegacyRewriter rewriter) {
core.setLegacyRewriter(rewriter);
}
public ClassDump getDump() {
return dump;
}
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.recording;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLTypes;
import com.gtnewhorizons.angelica.glsm.ffp.VAOManager;
@@ -67,7 +68,7 @@ public final class AttribSnapshot {
public static AttribSnapshot snapshot(int firstVertex, int vertexCount) {
final AttribDesc[] out = new AttribDesc[VAOManager.MAX_ATTRIBS];
final List<ByteBuffer> allocated = new ArrayList<>();
final int prevVBO = GLStateManager.getBoundVBO();
final int prevVBO = GLSMBuffers.getBoundVBO();
final VAOManager vaos = GLStateManager.ctx().vaos;
boolean success = false;
@@ -133,8 +134,8 @@ public final class AttribSnapshot {
}
if (buf == null) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, a.vboId);
final int bufferSize = GLStateManager.glGetBufferParameteri(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, a.vboId);
final int bufferSize = GLSMBuffers.glGetBufferParameteri(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
if (bufferSize <= 0) {
warnOnce("vbo-orphaned", "[AttribSnapshot] GL_BUFFER_SIZE={} for VBO {} -- skipping capture", bufferSize, a.vboId);
return null;
@@ -162,7 +163,7 @@ public final class AttribSnapshot {
}
buf = MemoryUtilities.memAlloc(rs);
GLStateManager.glGetBufferSubData(GL15.GL_ARRAY_BUFFER, ro, buf);
GLSMBuffers.glGetBufferSubData(GL15.GL_ARRAY_BUFFER, ro, buf);
allocated.add(buf);
readOffset = ro;
@@ -190,7 +191,7 @@ public final class AttribSnapshot {
success = true;
return new AttribSnapshot(out, allocated);
} finally {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
if (!success) {
for (ByteBuffer b : allocated) MemoryUtilities.memFree(b);
}
@@ -2,7 +2,20 @@ package com.gtnewhorizons.angelica.glsm.recording;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizons.angelica.glsm.DisplayListManager;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMAttribStack;
import com.gtnewhorizons.angelica.glsm.GLSMBlend;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMDepthStencilAlpha;
import com.gtnewhorizons.angelica.glsm.GLSMEnable;
import com.gtnewhorizons.angelica.glsm.GLSMFog;
import com.gtnewhorizons.angelica.glsm.GLSMFramebuffer;
import com.gtnewhorizons.angelica.glsm.GLSMLighting;
import com.gtnewhorizons.angelica.glsm.GLSMMatrices;
import com.gtnewhorizons.angelica.glsm.GLSMPrograms;
import com.gtnewhorizons.angelica.glsm.GLSMRasterizer;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.recording.commands.DisplayListCommand;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL15;
@@ -57,77 +70,77 @@ public final class CommandBufferExecutor {
switch (cmd) {
// === Single int commands ===
case GLCommand.ENABLE -> {
GLStateManager.glEnable(memGetInt(ptr));
GLSMEnable.glEnable(memGetInt(ptr));
ptr += 4;
}
case GLCommand.DISABLE -> {
GLStateManager.glDisable(memGetInt(ptr));
GLSMEnable.glDisable(memGetInt(ptr));
ptr += 4;
}
case GLCommand.CLEAR -> {
GLStateManager.glClear(memGetInt(ptr));
GLSMFramebuffer.glClear(memGetInt(ptr));
ptr += 4;
}
case GLCommand.CLEAR_STENCIL -> {
GLStateManager.glClearStencil(memGetInt(ptr));
GLSMDepthStencilAlpha.glClearStencil(memGetInt(ptr));
ptr += 4;
}
case GLCommand.CULL_FACE -> {
GLStateManager.glCullFace(memGetInt(ptr));
GLSMRasterizer.glCullFace(memGetInt(ptr));
ptr += 4;
}
case GLCommand.DEPTH_FUNC -> {
GLStateManager.glDepthFunc(memGetInt(ptr));
GLSMDepthStencilAlpha.glDepthFunc(memGetInt(ptr));
ptr += 4;
}
case GLCommand.SHADE_MODEL -> {
GLStateManager.glShadeModel(memGetInt(ptr));
GLSMRasterizer.glShadeModel(memGetInt(ptr));
ptr += 4;
}
case GLCommand.LOGIC_OP -> {
GLStateManager.glLogicOp(memGetInt(ptr));
GLSMBlend.glLogicOp(memGetInt(ptr));
ptr += 4;
}
case GLCommand.MATRIX_MODE -> {
GLStateManager.glMatrixMode(memGetInt(ptr));
GLSMMatrices.glMatrixMode(memGetInt(ptr));
ptr += 4;
}
case GLCommand.ACTIVE_TEXTURE -> {
GLStateManager.glActiveTexture(memGetInt(ptr));
GLSMTextures.glActiveTexture(memGetInt(ptr));
ptr += 4;
}
case GLCommand.USE_PROGRAM -> {
final int recordedProgram = memGetInt(ptr);
GLStateManager.glUseProgram(compiledDisplayList.resolveProgram(recordedProgram));
GLSMPrograms.glUseProgram(compiledDisplayList.resolveProgram(recordedProgram));
ptr += 4;
}
case GLCommand.PUSH_ATTRIB -> {
GLStateManager.glPushAttrib(memGetInt(ptr));
GLSMAttribStack.glPushAttrib(memGetInt(ptr));
ptr += 4;
}
case GLCommand.POP_ATTRIB -> {
GLStateManager.glPopAttrib();
GLSMAttribStack.glPopAttrib();
ptr += 4; // Skip unused padding
}
case GLCommand.LOAD_IDENTITY -> {
GLStateManager.glLoadIdentity();
GLSMMatrices.glLoadIdentity();
}
case GLCommand.PUSH_MATRIX -> {
GLStateManager.glPushMatrix();
GLSMMatrices.glPushMatrix();
}
case GLCommand.POP_MATRIX -> {
GLStateManager.glPopMatrix();
GLSMMatrices.glPopMatrix();
}
case GLCommand.STENCIL_MASK -> {
GLStateManager.glStencilMask(memGetInt(ptr));
GLSMDepthStencilAlpha.glStencilMask(memGetInt(ptr));
ptr += 4;
}
case GLCommand.DEPTH_MASK -> {
GLStateManager.glDepthMask(memGetInt(ptr) != 0);
GLSMDepthStencilAlpha.glDepthMask(memGetInt(ptr) != 0);
ptr += 4;
}
case GLCommand.FRONT_FACE -> {
GLStateManager.glFrontFace(memGetInt(ptr));
GLSMRasterizer.glFrontFace(memGetInt(ptr));
ptr += 4;
}
@@ -136,43 +149,43 @@ public final class CommandBufferExecutor {
final int target = memGetInt(ptr);
final int texture = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glBindTexture(target, texture);
GLSMTextures.glBindTexture(target, texture);
}
case GLCommand.POLYGON_MODE -> {
final int face = memGetInt(ptr);
final int mode = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glPolygonMode(face, mode);
GLSMRasterizer.glPolygonMode(face, mode);
}
case GLCommand.COLOR_MATERIAL -> {
final int face = memGetInt(ptr);
final int mode = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glColorMaterial(face, mode);
GLSMLighting.glColorMaterial(face, mode);
}
case GLCommand.LINE_STIPPLE -> {
final int factor = memGetInt(ptr);
final int pattern = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glLineStipple(factor, (short) pattern);
GLSMRasterizer.glLineStipple(factor, (short) pattern);
}
case GLCommand.STENCIL_MASK_SEPARATE -> {
final int face = memGetInt(ptr);
final int mask = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glStencilMaskSeparate(face, mask);
GLSMDepthStencilAlpha.glStencilMaskSeparate(face, mask);
}
case GLCommand.FOGI -> {
final int pname = memGetInt(ptr);
final int param = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glFogi(pname, param);
GLSMFog.glFogi(pname, param);
}
case GLCommand.HINT -> {
final int target = memGetInt(ptr);
final int mode = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glHint(target, mode);
GLSMRasterizer.glHint(target, mode);
}
// === Three int commands ===
@@ -181,21 +194,21 @@ public final class CommandBufferExecutor {
final int ref = memGetInt(ptr + 4);
final int mask = memGetInt(ptr + 8);
ptr += 12;
GLStateManager.glStencilFunc(func, ref, mask);
GLSMDepthStencilAlpha.glStencilFunc(func, ref, mask);
}
case GLCommand.STENCIL_OP -> {
final int fail = memGetInt(ptr);
final int zfail = memGetInt(ptr + 4);
final int zpass = memGetInt(ptr + 8);
ptr += 12;
GLStateManager.glStencilOp(fail, zfail, zpass);
GLSMDepthStencilAlpha.glStencilOp(fail, zfail, zpass);
}
case GLCommand.TEX_PARAMETERI -> {
final int target = memGetInt(ptr);
final int pname = memGetInt(ptr + 4);
final int param = memGetInt(ptr + 8);
ptr += 12;
GLStateManager.glTexParameteri(target, pname, param);
GLSMTextures.glTexParameteri(target, pname, param);
}
// === Four int commands ===
@@ -205,7 +218,7 @@ public final class CommandBufferExecutor {
final int width = memGetInt(ptr + 8);
final int height = memGetInt(ptr + 12);
ptr += 16;
GLStateManager.glViewport(x, y, width, height);
GLSMRasterizer.glViewport(x, y, width, height);
}
case GLCommand.SCISSOR -> {
final int x = memGetInt(ptr);
@@ -213,7 +226,7 @@ public final class CommandBufferExecutor {
final int width = memGetInt(ptr + 8);
final int height = memGetInt(ptr + 12);
ptr += 16;
GLStateManager.glScissor(x, y, width, height);
GLSMRasterizer.glScissor(x, y, width, height);
}
case GLCommand.BLEND_FUNC -> {
final int srcRgb = memGetInt(ptr);
@@ -222,9 +235,9 @@ public final class CommandBufferExecutor {
final int dstAlpha = memGetInt(ptr + 12);
ptr += 16;
if (srcRgb == srcAlpha && dstRgb == dstAlpha) {
GLStateManager.glBlendFunc(srcRgb, dstRgb);
GLSMBlend.glBlendFunc(srcRgb, dstRgb);
} else {
GLStateManager.tryBlendFuncSeparate(srcRgb, dstRgb, srcAlpha, dstAlpha);
GLSMBlend.tryBlendFuncSeparate(srcRgb, dstRgb, srcAlpha, dstAlpha);
}
}
case GLCommand.COLOR_MASK -> {
@@ -233,7 +246,7 @@ public final class CommandBufferExecutor {
final boolean b = memGetInt(ptr + 8) != 0;
final boolean a = memGetInt(ptr + 12) != 0;
ptr += 16;
GLStateManager.glColorMask(r, g, b, a);
GLSMBlend.glColorMask(r, g, b, a);
}
case GLCommand.STENCIL_FUNC_SEPARATE -> {
final int face = memGetInt(ptr);
@@ -241,7 +254,7 @@ public final class CommandBufferExecutor {
final int ref = memGetInt(ptr + 8);
final int mask = memGetInt(ptr + 12);
ptr += 16;
GLStateManager.glStencilFuncSeparate(face, func, ref, mask);
GLSMDepthStencilAlpha.glStencilFuncSeparate(face, func, ref, mask);
}
case GLCommand.STENCIL_OP_SEPARATE -> {
final int face = memGetInt(ptr);
@@ -249,28 +262,28 @@ public final class CommandBufferExecutor {
final int dpfail = memGetInt(ptr + 8);
final int dppass = memGetInt(ptr + 12);
ptr += 16;
GLStateManager.glStencilOpSeparate(face, sfail, dpfail, dppass);
GLSMDepthStencilAlpha.glStencilOpSeparate(face, sfail, dpfail, dppass);
}
// === Float commands ===
case GLCommand.VERTEX_ATTRIB -> {
GLStateManager.glVertexAttrib4f(memGetInt(ptr), memGetFloat(ptr + 4), memGetFloat(ptr + 8),
GLSMCurrentAttribs.glVertexAttrib4f(memGetInt(ptr), memGetFloat(ptr + 4), memGetFloat(ptr + 8),
memGetFloat(ptr + 12), memGetFloat(ptr + 16));
ptr += 20;
}
case GLCommand.POINT_SIZE -> {
GLStateManager.glPointSize(memGetFloat(ptr));
GLSMRasterizer.glPointSize(memGetFloat(ptr));
ptr += 4;
}
case GLCommand.LINE_WIDTH -> {
GLStateManager.glLineWidth(memGetFloat(ptr));
GLSMRasterizer.glLineWidth(memGetFloat(ptr));
ptr += 4;
}
case GLCommand.POLYGON_OFFSET -> {
final float factor = memGetFloat(ptr);
final float units = memGetFloat(ptr + 4);
ptr += 8;
GLStateManager.glPolygonOffset(factor, units);
GLSMRasterizer.glPolygonOffset(factor, units);
}
case GLCommand.COLOR -> {
final float r = memGetFloat(ptr);
@@ -278,14 +291,14 @@ public final class CommandBufferExecutor {
final float b = memGetFloat(ptr + 8);
final float a = memGetFloat(ptr + 12);
ptr += 16;
GLStateManager.glColor4f(r, g, b, a);
GLSMCurrentAttribs.glColor4f(r, g, b, a);
}
case GLCommand.SECONDARY_COLOR -> {
final float r = memGetFloat(ptr);
final float g = memGetFloat(ptr + 4);
final float b = memGetFloat(ptr + 8);
ptr += 12;
GLStateManager.glSecondaryColor3f(r, g, b);
GLSMCurrentAttribs.glSecondaryColor3f(r, g, b);
}
case GLCommand.CLEAR_COLOR -> {
final float r = memGetFloat(ptr);
@@ -293,12 +306,12 @@ public final class CommandBufferExecutor {
final float b = memGetFloat(ptr + 8);
final float a = memGetFloat(ptr + 12);
ptr += 16;
GLStateManager.glClearColor(r, g, b, a);
GLSMBlend.glClearColor(r, g, b, a);
}
case GLCommand.CLEAR_DEPTH -> {
final double depth = memGetDouble(ptr);
ptr += 8;
GLStateManager.glClearDepth(depth);
GLSMDepthStencilAlpha.glClearDepth(depth);
}
case GLCommand.BLEND_COLOR -> {
final float r = memGetFloat(ptr);
@@ -306,7 +319,7 @@ public final class CommandBufferExecutor {
final float b = memGetFloat(ptr + 8);
final float a = memGetFloat(ptr + 12);
ptr += 16;
GLStateManager.glBlendColor(r, g, b, a);
GLSMBlend.glBlendColor(r, g, b, a);
}
// === Mixed int+float commands ===
@@ -314,53 +327,53 @@ public final class CommandBufferExecutor {
final int func = memGetInt(ptr);
final float ref = memGetFloat(ptr + 4);
ptr += 8;
GLStateManager.glAlphaFunc(func, ref);
GLSMDepthStencilAlpha.glAlphaFunc(func, ref);
}
case GLCommand.FOGF -> {
final int pname = memGetInt(ptr);
final float param = memGetFloat(ptr + 4);
ptr += 8;
GLStateManager.glFogf(pname, param);
GLSMFog.glFogf(pname, param);
}
case GLCommand.LIGHTF -> {
final int light = memGetInt(ptr);
final int pname = memGetInt(ptr + 4);
final float param = memGetFloat(ptr + 8);
ptr += 12;
GLStateManager.glLightf(light, pname, param);
GLSMLighting.glLightf(light, pname, param);
}
case GLCommand.LIGHT_MODELF -> {
final int pname = memGetInt(ptr);
final float param = memGetFloat(ptr + 4);
ptr += 8;
GLStateManager.glLightModelf(pname, param);
GLSMLighting.glLightModelf(pname, param);
}
case GLCommand.LIGHTI -> {
final int light = memGetInt(ptr);
final int pname = memGetInt(ptr + 4);
final int param = memGetInt(ptr + 8);
ptr += 12;
GLStateManager.glLighti(light, pname, param);
GLSMLighting.glLighti(light, pname, param);
}
case GLCommand.LIGHT_MODELI -> {
final int pname = memGetInt(ptr);
final int param = memGetInt(ptr + 4);
ptr += 8;
GLStateManager.glLightModeli(pname, param);
GLSMLighting.glLightModeli(pname, param);
}
case GLCommand.MATERIALF -> {
final int face = memGetInt(ptr);
final int pname = memGetInt(ptr + 4);
final float param = memGetFloat(ptr + 8);
ptr += 12;
GLStateManager.glMaterialf(face, pname, param);
GLSMLighting.glMaterialf(face, pname, param);
}
case GLCommand.TEX_PARAMETERF -> {
final int target = memGetInt(ptr);
final int pname = memGetInt(ptr + 4);
final float param = memGetFloat(ptr + 8);
ptr += 12;
GLStateManager.glTexParameterf(target, pname, param);
GLSMTextures.glTexParameterf(target, pname, param);
}
// === Matrix commands ===
@@ -372,21 +385,21 @@ public final class CommandBufferExecutor {
ptr += 4;
}
MATRIX_BUFFER.flip();
GLStateManager.glMultMatrix(MATRIX_BUFFER);
GLSMMatrices.glMultMatrix(MATRIX_BUFFER);
}
case GLCommand.TRANSLATE -> {
final float x = memGetFloat(ptr);
final float y = memGetFloat(ptr + 4);
final float z = memGetFloat(ptr + 8);
ptr += 12;
GLStateManager.glTranslatef(x, y, z);
GLSMMatrices.glTranslatef(x, y, z);
}
case GLCommand.SCALE -> {
final float x = memGetFloat(ptr);
final float y = memGetFloat(ptr + 4);
final float z = memGetFloat(ptr + 8);
ptr += 12;
GLStateManager.glScalef(x, y, z);
GLSMMatrices.glScalef(x, y, z);
}
case GLCommand.LOAD_MATRIX -> {
MATRIX_BUFFER.clear();
@@ -395,7 +408,7 @@ public final class CommandBufferExecutor {
ptr += 4;
}
MATRIX_BUFFER.flip();
GLStateManager.glLoadMatrix(MATRIX_BUFFER);
GLSMMatrices.glLoadMatrix(MATRIX_BUFFER);
}
// === Buffer commands ===
@@ -409,7 +422,7 @@ public final class CommandBufferExecutor {
ptr += 4;
}
PARAMS_BUFFER.flip();
GLStateManager.glFog(pname, PARAMS_BUFFER);
GLSMFog.glFog(pname, PARAMS_BUFFER);
}
case GLCommand.LIGHT -> {
final int light = memGetInt(ptr);
@@ -422,7 +435,7 @@ public final class CommandBufferExecutor {
ptr += 4;
}
PARAMS_BUFFER.flip();
GLStateManager.glLight(light, pname, PARAMS_BUFFER);
GLSMLighting.glLight(light, pname, PARAMS_BUFFER);
}
case GLCommand.LIGHT_MODEL -> {
final int pname = memGetInt(ptr);
@@ -434,7 +447,7 @@ public final class CommandBufferExecutor {
ptr += 4;
}
PARAMS_BUFFER.flip();
GLStateManager.glLightModel(pname, PARAMS_BUFFER);
GLSMLighting.glLightModel(pname, PARAMS_BUFFER);
}
case GLCommand.MATERIAL -> {
final int face = memGetInt(ptr);
@@ -447,7 +460,7 @@ public final class CommandBufferExecutor {
ptr += 4;
}
PARAMS_BUFFER.flip();
GLStateManager.glMaterial(face, pname, PARAMS_BUFFER);
GLSMLighting.glMaterial(face, pname, PARAMS_BUFFER);
}
case GLCommand.CLIP_PLANE -> {
@@ -460,7 +473,7 @@ public final class CommandBufferExecutor {
PARAMS_DOUBLE_BUFFER.clear();
PARAMS_DOUBLE_BUFFER.put(a).put(b).put(c).put(d);
PARAMS_DOUBLE_BUFFER.flip();
GLStateManager.glClipPlane(plane, PARAMS_DOUBLE_BUFFER);
GLSMRasterizer.glClipPlane(plane, PARAMS_DOUBLE_BUFFER);
}
// === Draw commands ===
@@ -484,19 +497,19 @@ public final class CommandBufferExecutor {
final byte b = (byte) ((color >> 16) & 0xFF);
final byte g = (byte) ((color >> 8) & 0xFF);
final byte r = (byte) ((color & 0xFF));
GLStateManager.glColor4ub(r, g, b, a);
GLSMCurrentAttribs.glColor4ub(r, g, b, a);
}
if ((flags & VertexFlags.NORMAL_BIT) != 0) {
final int normal = memGetInt(ptr + 12);
float nx = (byte)(normal) / 127.0f;
float ny = (byte)(normal >> 8) / 127.0f;
float nz = (byte)(normal >> 16) / 127.0f;
GLStateManager.glNormal3f(nx, ny, nz);
GLSMCurrentAttribs.glNormal3f(nx, ny, nz);
}
if ((flags & VertexFlags.TEXTURE_BIT) != 0) {
final float s = memGetFloat(ptr + 16);
final float t = memGetFloat(ptr + 20);
GLStateManager.glTexCoord2f(s, t);
GLSMCurrentAttribs.glTexCoord2f(s, t);
}
ptr += 24; // Skip full command size (28 - 4 for cmd already read)
}
@@ -506,7 +519,7 @@ public final class CommandBufferExecutor {
DisplayListManager.glCallList(listId);
}
case GLCommand.DRAW_BUFFER -> {
GLStateManager.glDrawBuffer(memGetInt(ptr));
GLSMFramebuffer.glDrawBuffer(memGetInt(ptr));
ptr += 4;
}
case GLCommand.DRAW_BUFFERS -> {
@@ -518,16 +531,16 @@ public final class CommandBufferExecutor {
}
DRAW_BUFFERS_BUFFER.flip();
ptr += 4 * MAX_DRAW_BUFFERS;
GLStateManager.glDrawBuffers(DRAW_BUFFERS_BUFFER);
GLSMFramebuffer.glDrawBuffers(DRAW_BUFFERS_BUFFER);
}
case GLCommand.BIND_VBO -> {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, memGetInt(ptr));
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, memGetInt(ptr));
ptr += 4;
}
case GLCommand.BIND_VAO -> {
final int vao = memGetInt(ptr);
ptr += 4;
if (compiledDisplayList.replaysVertexArrayBind(vao)) GLStateManager.glBindVertexArray(vao);
if (compiledDisplayList.replaysVertexArrayBind(vao)) GLSMVertexInput.glBindVertexArray(vao);
}
// === Complex object reference ===
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.glsm.recording;
import com.gtnewhorizons.angelica.glsm.DisplayListManager;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMPrograms;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.recording.commands.DisplayListCommand;
import com.gtnewhorizons.angelica.glsm.recording.commands.IndexedDrawBatch;
@@ -43,15 +44,15 @@ public final class CompiledDisplayList {
int resolveProgram(int program) {
if (program == 0) return 0;
final long generation = GLStateManager.getProgramLifetimeGeneration();
final long generation = GLSMPrograms.getProgramLifetimeGeneration();
if (replayPrograms == null) replayPrograms = new Int2IntOpenHashMap();
if (programLifetimeGeneration != generation) {
replayPrograms.clear();
programLifetimeGeneration = generation;
}
if (replayPrograms.containsKey(program)) return replayPrograms.get(program);
final boolean valid = GLStateManager.glIsProgram(program);
if (!valid || !GLStateManager.isProgramPendingDeletion(program)) {
final boolean valid = GLSMPrograms.glIsProgram(program);
if (!valid || !GLSMPrograms.isProgramPendingDeletion(program)) {
replayPrograms.put(program, valid ? program : 0);
}
return valid ? program : 0;
@@ -1,7 +1,8 @@
package com.gtnewhorizons.angelica.glsm.recording;
import com.gtnewhorizon.gtnhlib.client.renderer.vao.IVertexArrayObject;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
import com.gtnewhorizons.angelica.glsm.hooks.ImmediateExtendedAttribHandler;
import com.gtnewhorizons.angelica.glsm.streaming.LineQuads;
import org.lwjgl.opengl.GL11;
@@ -32,7 +33,7 @@ public final class DisplayListVBO {
}
if (extVbos != null) {
for (int extVbo : extVbos) {
if (extVbo != 0) GLStateManager.glDeleteBuffers(extVbo);
if (extVbo != 0) GLSMBuffers.glDeleteBuffers(extVbo);
}
}
}
@@ -98,15 +99,15 @@ public final class DisplayListVBO {
public void render() {
if (vao == null) return;
if (lineQuads != null && GLStateManager.ffpWidensLineQuads()) {
if (lineQuads != null && GLSMDraws.ffpWidensLineQuads()) {
renderLineQuads();
return;
}
vao.bind();
if (pendingExtVbo != 0) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, pendingExtVbo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, pendingExtVbo);
ImmediateExtendedAttribHandler.setupExtAttribPointers(0L, ImmediateExtendedAttribHandler.EXT_STRIDE);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
pendingExtVbo = 0;
}
if (count <= 0) { vao.unbind(); return; }
@@ -9,6 +9,8 @@ import com.gtnewhorizon.gtnhlib.client.renderer.vbo.IVertexBuffer;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.DefaultVertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMRasterizer;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMConfig;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
@@ -80,7 +82,7 @@ public final class DisplayListVBOBuilder {
final IntArrayList extCounts = wantExt ? new IntArrayList() : null;
final IntArrayList extPrims = wantExt ? new IntArrayList() : null;
// drawIndex, start, vertexCount, drawMode for each line draw
final IntArrayList lineDraws = GLStateManager.wideLineEmulationEnabled ? new IntArrayList() : null;
final IntArrayList lineDraws = GLSMRasterizer.wideLineEmulationEnabled ? new IntArrayList() : null;
for (FormatData data : formatData) {
int vertexCount;
@@ -212,11 +214,11 @@ public final class DisplayListVBOBuilder {
extAddr + (long) rStart * extStride, extStride);
}
final int extVbo = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, extVbo);
final int extVbo = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, extVbo);
ext.position(0).limit(extVerts * extStride);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, ext, GL15.GL_STATIC_DRAW);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, ext, GL15.GL_STATIC_DRAW);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
memFree(ext);
return extVbo;
}
@@ -4,6 +4,7 @@ import com.gtnewhorizon.gtnhlib.client.renderer.CallbackTessellator;
import com.gtnewhorizon.gtnhlib.client.renderer.DirectTessellator;
import com.gtnewhorizon.gtnhlib.client.renderer.TessellatorManager;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLTypes;
import com.gtnewhorizons.angelica.glsm.QuadConverter;
@@ -77,7 +78,7 @@ public final class ImmediateModeRecorder {
/**
* Set the current lightmap coordinate as packed brightness.
* Called by GLStateManager.glMultiTexCoord2f for unit 1 during recording/drawing.
* Called by GLSMCurrentAttribs.glMultiTexCoord2f for unit 1 during recording/drawing.
*/
public static void setLightmapCoord(float s, float t) {
tessellator().setBrightness(((int) t << 16) | ((int) s & 0xFFFF));
@@ -119,7 +120,7 @@ public final class ImmediateModeRecorder {
final DirectTessellator t = tessellator();
t.reset();
t.startDrawing(primitiveType);
final var c = GLStateManager.getColor();
final var c = GLSMCurrentAttribs.getColor();
t.setColorRGBA((int) (c.getRed() * 255.0f), (int) (c.getGreen() * 255.0f), (int) (c.getBlue() * 255.0f), (int) (c.getAlpha() * 255.0f));
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
public final class BatchedIndexedDrawCmd implements DisplayListCommand {
private IndexedDrawBatch batch;
@@ -26,7 +26,7 @@ public final class BatchedIndexedDrawCmd implements DisplayListCommand {
public void execute() {
if (batch == null) return;
batch.bind();
GLStateManager.glDrawElements(drawMode, indexCount, indexType, indexByteOffset);
GLSMDraws.glDrawElements(drawMode, indexCount, indexType, indexByteOffset);
}
@Override
@@ -1,6 +1,8 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.lwjgl.opengl.GL15;
@@ -24,21 +26,21 @@ public final class IndexedDrawBatch {
public void bind() {
final GLContextState glCtx = GLStateManager.ctx();
if (vaoCtx == glCtx) {
GLStateManager.glBindVertexArray(vao);
GLSMVertexInput.glBindVertexArray(vao);
return;
}
final int prevVBO = GLStateManager.getBoundVBO();
final int v = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(v);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, sharedVBO);
final int prevVBO = GLSMBuffers.getBoundVBO();
final int v = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(v);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, sharedVBO);
final int stride = layout.stride();
for (int i = 0; i < layout.locations.length; i++) {
final int loc = layout.locations[i];
GLStateManager.glVertexAttribPointer(loc, layout.sizes[i], layout.types[i], layout.normalized[i], stride, layout.offset(i));
GLStateManager.glEnableVertexAttribArray(loc);
GLSMVertexInput.glVertexAttribPointer(loc, layout.sizes[i], layout.types[i], layout.normalized[i], stride, layout.offset(i));
GLSMVertexInput.glEnableVertexAttribArray(loc);
}
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, sharedEBO);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, sharedEBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
vao = v;
vaoCtx = glCtx;
}
@@ -46,9 +48,9 @@ public final class IndexedDrawBatch {
public void delete() {
if (deleted) return;
deleted = true;
if (vaoCtx == GLStateManager.ctx()) GLStateManager.glDeleteVertexArrays(vao);
if (sharedVBO != 0) GLStateManager.glDeleteBuffers(sharedVBO);
if (sharedEBO != 0) GLStateManager.glDeleteBuffers(sharedEBO);
if (vaoCtx == GLStateManager.ctx()) GLSMVertexInput.glDeleteVertexArrays(vao);
if (sharedVBO != 0) GLSMBuffers.glDeleteBuffers(sharedVBO);
if (sharedEBO != 0) GLSMBuffers.glDeleteBuffers(sharedEBO);
vao = sharedVBO = sharedEBO = 0;
vaoCtx = null;
}
@@ -1,7 +1,8 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
@@ -35,8 +36,8 @@ public final class IndexedDrawBatchBuilder {
final List<IndexedDrawBatch> out = new ArrayList<>();
if (captures.isEmpty()) return out;
final int prevVBO = GLStateManager.getBoundVBO();
final int prevEBO = GLStateManager.getBoundEBO();
final int prevVBO = GLSMBuffers.getBoundVBO();
final int prevEBO = GLSMVertexInput.getBoundEBO();
final List<GroupResult> results = new ArrayList<>();
boolean success = false;
@@ -57,8 +58,8 @@ public final class IndexedDrawBatchBuilder {
if (!success) {
for (GroupResult r : results) r.batch.delete();
}
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, prevEBO);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, prevEBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
}
return out;
@@ -95,12 +96,12 @@ public final class IndexedDrawBatchBuilder {
final long[] indexOffsets = new long[n];
try {
sharedVBO = GLStateManager.glGenBuffers();
sharedEBO = GLStateManager.glGenBuffers();
sharedVBO = GLSMBuffers.glGenBuffers();
sharedEBO = GLSMBuffers.glGenBuffers();
eboData = MemoryUtilities.memAlloc((int) totalIndexBytes);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, sharedVBO);
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, totalVertexBytes, GL15.GL_STATIC_DRAW);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, sharedVBO);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, totalVertexBytes, GL15.GL_STATIC_DRAW);
int vboBytePos = 0;
int eboBytePos = 0;
@@ -110,7 +111,7 @@ public final class IndexedDrawBatchBuilder {
for (int g = 0; g < n; g++) {
final IndexedDrawCapture c = group.get(g);
final int vBytes = c.vertexCount * c.layoutKey.stride();
GLStateManager.glBufferSubData(GL15.GL_ARRAY_BUFFER, vboBytePos, c.vertexData);
GLSMBuffers.glBufferSubData(GL15.GL_ARRAY_BUFFER, vboBytePos, c.vertexData);
final long srcIdxAddr = memAddress0(c.indexData);
final int idxBytes = c.indexCount * 4;
@@ -137,8 +138,8 @@ public final class IndexedDrawBatchBuilder {
eboData.position(0).limit((int) totalIndexBytes);
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, sharedEBO);
GLStateManager.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, eboData, GL15.GL_STATIC_DRAW);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, sharedEBO);
GLSMBuffers.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, eboData, GL15.GL_STATIC_DRAW);
success = true;
return new GroupResult(new IndexedDrawBatch(group.get(0).layoutKey, sharedVBO, sharedEBO),
@@ -146,8 +147,8 @@ public final class IndexedDrawBatchBuilder {
} finally {
if (eboData != null) MemoryUtilities.memFree(eboData);
if (!success) {
if (sharedVBO != 0) GLStateManager.glDeleteBuffers(sharedVBO);
if (sharedEBO != 0) GLStateManager.glDeleteBuffers(sharedEBO);
if (sharedVBO != 0) GLSMBuffers.glDeleteBuffers(sharedVBO);
if (sharedEBO != 0) GLSMBuffers.glDeleteBuffers(sharedEBO);
}
}
}
@@ -1,6 +1,8 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLTypes;
import com.gtnewhorizons.angelica.glsm.QuadConverter;
@@ -64,12 +66,12 @@ public final class IndexedDrawCapture {
final int srcIndexSize = GLTypes.sizeBytes(srcIndexType);
if (srcIndexSize <= 0) return null;
final int prevEBO = GLStateManager.getBoundEBO();
final int prevVBO = GLStateManager.getBoundVBO();
final int prevEBO = GLSMVertexInput.getBoundEBO();
final int prevVBO = GLSMBuffers.getBoundVBO();
ByteBuffer eboSrc = null;
try {
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, eboId);
final int eboBufferSize = GLStateManager.glGetBufferParameteri(GL15.GL_ELEMENT_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, eboId);
final int eboBufferSize = GLSMBuffers.glGetBufferParameteri(GL15.GL_ELEMENT_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
if (eboBufferSize <= 0) {
GLStateManager.warnOnce("ebo-size", "[IndexedDrawCapture] GL_BUFFER_SIZE={} for EBO {}", eboBufferSize, eboId);
return null;
@@ -80,12 +82,12 @@ public final class IndexedDrawCapture {
return null;
}
eboSrc = MemoryUtilities.memAlloc((int) eboReadSize);
GLStateManager.glGetBufferSubData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesOffset, eboSrc);
GLSMBuffers.glGetBufferSubData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesOffset, eboSrc);
return bake(mode, indicesCount, srcIndexType, MemoryUtilities.memAddress0(eboSrc));
} finally {
if (eboSrc != null) MemoryUtilities.memFree(eboSrc);
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, prevEBO);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, prevEBO);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, prevVBO);
}
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMMatrices;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
@@ -26,7 +26,7 @@ public record MultMatrixCmd(Matrix4f matrix, FloatBuffer buffer) implements Disp
@Override
public void execute() {
buffer.rewind();
GLStateManager.glMultMatrix(buffer);
GLSMMatrices.glMultMatrix(buffer);
}
@Override
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizons.angelica.glsm.GLDebug;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLTypes;
import com.gtnewhorizons.angelica.glsm.states.PixelStoreState;
import org.jetbrains.annotations.NotNull;
@@ -56,14 +56,14 @@ public record TexImage2DCmd(
@Override
public void execute() {
if (pixels == null) {
GLStateManager.glTexImage2D(target, level, internalformat, width, height, border, format, type, (ByteBuffer) null);
GLSMTextures.glTexImage2D(target, level, internalformat, width, height, border, format, type, (ByteBuffer) null);
return;
}
GLStateManager.forcePixelUnpackState(unpack);
GLSMTextures.forcePixelUnpackState(unpack);
try {
GLStateManager.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
GLSMTextures.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
} finally {
GLStateManager.restorePixelUnpackState(unpack);
GLSMTextures.restorePixelUnpackState(unpack);
}
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.glsm.recording.commands;
import com.gtnewhorizons.angelica.glsm.GLDebug;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLTypes;
import com.gtnewhorizons.angelica.glsm.states.PixelStoreState;
import org.jetbrains.annotations.NotNull;
@@ -56,14 +56,14 @@ public record TexSubImage2DCmd(
@Override
public void execute() {
if (pixels == null) {
GLStateManager.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, (ByteBuffer) null);
GLSMTextures.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, (ByteBuffer) null);
return;
}
GLStateManager.forcePixelUnpackState(unpack);
GLSMTextures.forcePixelUnpackState(unpack);
try {
GLStateManager.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
GLSMTextures.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
} finally {
GLStateManager.restorePixelUnpackState(unpack);
GLSMTextures.restorePixelUnpackState(unpack);
}
}
@@ -0,0 +1,174 @@
package com.gtnewhorizons.angelica.glsm.redirect;
final class GLSMOwners {
static final String[][] METHODS = {
{"com/gtnewhorizons/angelica/glsm/GLSMAttribStack",
"applyRetainedState", "getAttribDepth", "glPopAttrib", "glPopClientAttrib", "glPushAttrib",
"glPushClientAttrib", "isPoppingAttributes", "popState", "popStateTo", "pushState", "registerModifiedState",
"replayStateToBackend", "retainModifiedState"},
{"com/gtnewhorizons/angelica/glsm/GLSMBlend",
"defaultBlendFunc", "disableBlend", "enableBlend", "getBlendMode", "getBlendState", "getClearColor",
"getColorLogicOpState", "getColorMask", "getEffectiveBlendState", "getEffectiveColorMask",
"getIndexLogicOpState", "getLogicOpMode", "glBlendColor", "glBlendEquation", "glBlendEquationSeparate",
"glBlendFunc", "glBlendFuncSeparate", "glBlendFuncSeparatei", "glClearColor", "glColorMask", "glLogicOp",
"isEffectiveBlendEnabled", "setHudCacheOverride", "tryBlendFuncSeparate"},
{"com/gtnewhorizons/angelica/glsm/GLSMBuffers",
"getBoundCopyReadBuffer", "getBoundCopyWriteBuffer", "getBoundVBO", "getIndexedBufferBinding",
"glBindBuffer", "glBindBufferBase", "glBindBufferRange", "glBufferData", "glBufferStorage",
"glBufferSubData", "glClearBufferData", "glClearBufferSubData", "glClientWaitSync", "glCopyBufferSubData",
"glCreateBuffers", "glDeleteBuffers", "glDeleteSync", "glFenceSync", "glFlushMappedBufferRange",
"glGenBuffers", "glGetBufferParameter", "glGetBufferParameteri", "glGetBufferParameteriv",
"glGetBufferSubData", "glGetSynci", "glIsBuffer", "glMapBuffer", "glMapBufferRange",
"glMapBufferRangeAddress", "glMemoryBarrier", "glNamedBufferData", "glNamedBufferSubData", "glUnmapBuffer",
"glWaitSync", "nglBufferData", "nglBufferSubData", "nglGetBufferSubData", "nglMapBuffer"},
{"com/gtnewhorizons/angelica/glsm/GLSMCurrentAttribs",
"consumeUnit23TexCoordSetDuringDraw", "flushDeferredVertexAttribs", "flushEntityIds",
"forceAttribDefaultsDirty", "getColor", "getColorSumState", "getOverlayA", "getOverlayB", "getOverlayG",
"getOverlayR", "getSecondaryColor", "getShaderColorA", "getShaderColorB", "getShaderColorG",
"getShaderColorR", "glColor3b", "glColor3d", "glColor3f", "glColor3ub", "glColor4b", "glColor4d",
"glColor4f", "glColor4ub", "glEdgeFlag", "glMultiTexCoord2d", "glMultiTexCoord2f", "glMultiTexCoord2s",
"glNormal3b", "glNormal3d", "glNormal3f", "glNormal3i", "glSecondaryColor3b", "glSecondaryColor3d",
"glSecondaryColor3f", "glSecondaryColor3ub", "glTexCoord1d", "glTexCoord1f", "glTexCoord2d", "glTexCoord2f",
"glTexCoord3d", "glTexCoord3f", "glTexCoord4d", "glTexCoord4f", "glVertexAttrib2f", "glVertexAttrib2s",
"glVertexAttrib3f", "glVertexAttrib4f", "setEntityIds", "setLightmapTextureCoords", "setOverlayColor",
"setShaderColor"},
{"com/gtnewhorizons/angelica/glsm/GLSMDepthStencilAlpha",
"disableAlphaTest", "disableDepthTest", "enableAlphaTest", "enableDepthTest", "getAlphaState",
"getAlphaTest", "getDepthState", "getDepthTest", "getEffectiveAlphaState", "getStencilState",
"getStencilTest", "glAlphaFunc", "glClearDepth", "glClearStencil", "glDepthFunc", "glDepthMask",
"glDepthRange", "glStencilFunc", "glStencilFuncSeparate", "glStencilMask", "glStencilMaskSeparate",
"glStencilOp", "glStencilOpSeparate", "isEffectiveAlphaTestEnabled", "isEffectiveDepthMaskEnabled"},
{"com/gtnewhorizons/angelica/glsm/GLSMDraws",
"displayListExists", "ffpWidensLineQuads", "getDisplayList", "getListMode", "glAccum", "glBegin",
"glCallList", "glCallLists", "glDebugMessageCallback", "glDebugMessageControl", "glDebugMessageInsert",
"glDeleteLists", "glDrawArrays", "glDrawArraysInstanced", "glDrawElements", "glDrawElementsBaseVertex",
"glDrawElementsInstanced", "glDrawRangeElements", "glDrawRangeElementsBaseVertex", "glEnd", "glEndList",
"glFeedbackBuffer", "glFinish", "glFlush", "glGenLists", "glGetDebugMessageLog", "glGetObjectLabel",
"glInitNames", "glIsList", "glListBase", "glLoadName", "glMultiDrawArrays",
"glMultiDrawArraysIndirectCount", "glMultiDrawElementsBaseVertex", "glMultiDrawElementsIndirect",
"glMultiDrawElementsIndirectCount", "glNewList", "glObjectLabel", "glPassThrough", "glPixelTransferf",
"glPixelTransferi", "glPopDebugGroup", "glPopName", "glPrimitiveRestartIndex", "glPushDebugGroup",
"glPushName", "glRasterPos2d", "glRasterPos2f", "glRasterPos2i", "glRasterPos3d", "glRasterPos3f",
"glRasterPos3i", "glRasterPos4d", "glRasterPos4f", "glRasterPos4i", "glRenderMode", "glSelectBuffer",
"glVertex2d", "glVertex2f", "glVertex2i", "glVertex3d", "glVertex3f", "glVertex3i", "isContinuousDraw",
"nglMultiDrawElementsBaseVertex", "preDraw", "registerDebugMessageListener"},
{"com/gtnewhorizons/angelica/glsm/GLSMEnable",
"glDisable", "glDisablei", "glEnable", "glEnablei", "glIsEnabled"},
{"com/gtnewhorizons/angelica/glsm/GLSMFog",
"disableFog", "enableFog", "fogColor", "getFogColor", "getFogMode", "getFogState", "glFog", "glFogf",
"glFogi"},
{"com/gtnewhorizons/angelica/glsm/GLSMFramebuffer",
"attachTextureForReading", "framebufferCompletenessIsMeaningful", "getDrawBuffer", "getDrawFramebuffer",
"getDrawFramebufferGeneration", "getReadFramebuffer", "glBindFramebuffer", "glBindRenderbuffer",
"glBlitFramebuffer", "glCheckFramebufferStatus", "glClear", "glDeleteFramebuffers", "glDeleteRenderbuffers",
"glDrawBuffer", "glDrawBuffers", "glFramebufferRenderbuffer", "glFramebufferTexture",
"glFramebufferTexture1D", "glFramebufferTexture2D", "glFramebufferTexture3D", "glFramebufferTextureFace",
"glFramebufferTextureLayer", "glGenFramebuffers", "glGenRenderbuffers",
"glGetFramebufferAttachmentParameteri", "glIsFramebuffer", "glIsRenderbuffer",
"glNamedFramebufferRenderbuffer", "glNamedFramebufferTexture", "glNamedFramebufferTexture1DEXT",
"glNamedFramebufferTexture2DEXT", "glNamedFramebufferTexture3DEXT", "glNamedFramebufferTextureEXT",
"glNamedFramebufferTextureFaceEXT", "glNamedFramebufferTextureLayer", "glReadBuffer", "glReadPixels",
"glRenderbufferStorage", "glRenderbufferStorageMultisample", "isFramebufferEnabled",
"takeFirstClearBlockNanos"},
{"com/gtnewhorizons/angelica/glsm/GLSMLighting",
"applyLighting", "captureLighting", "disableColorMaterial", "disableLight", "disableLighting",
"disableRescaleNormal", "enableColorMaterial", "enableLight", "enableLighting", "enableRescaleNormal",
"getBackMaterial", "getColorMaterial", "getColorMaterialFace", "getColorMaterialParameter",
"getFrontMaterial", "getLightDataStates", "getLightModel", "getLightStates", "getLightingGeneration",
"getLightingState", "getNormalizeState", "getRescaleNormalState", "glColorMaterial", "glGetLight",
"glGetMaterial", "glLight", "glLightModel", "glLightModelf", "glLightModeli", "glLightf", "glLighti",
"glMaterial", "glMaterialf", "glMateriali", "i2f"},
{"com/gtnewhorizons/angelica/glsm/GLSMMatrices",
"applyMultMatrix", "getMatrixMode", "getMatrixStack", "getMatrixStackDepth", "getModelViewMatrix",
"getMvGeneration", "getMvLinearGeneration", "getProjGeneration", "getProjectionMatrix",
"getTexMatrixGeneration", "glFrustum", "glLoadIdentity", "glLoadMatrix", "glMatrixMode", "glMultMatrix",
"glOrtho", "glPopMatrix", "glPushMatrix", "glRotated", "glRotatef", "glScaled", "glScalef", "glTranslated",
"glTranslatef", "gluBuild2DMipmaps", "gluErrorString", "gluLookAt", "gluOrtho2D", "gluPerspective",
"gluPickMatrix", "gluUnProject", "setModelViewMatrix", "setProjectionMatrix", "setTextureMatrix"},
{"com/gtnewhorizons/angelica/glsm/GLSMPrograms",
"getActiveProgram", "getProgramGeneration", "getProgramLifetimeGeneration", "getProgramStack",
"getVertexProgramTwoSideState", "glAttachShader", "glBindAttribLocation", "glBindFragDataLocation",
"glCompileShader", "glCreateProgram", "glCreateShader", "glDeleteObjectARB", "glDeleteProgram",
"glDeleteShader", "glDetachShader", "glDispatchCompute", "glGetActiveAttrib", "glGetActiveUniform",
"glGetAttachedShaders", "glGetAttribLocation", "glGetHandleARB", "glGetInfoLogARB",
"glGetObjectParameterARB", "glGetObjectParameteriARB", "glGetProgramBinary", "glGetProgramInfoLog",
"glGetProgrami", "glGetShaderInfoLog", "glGetShaderSource", "glGetShaderi", "glGetUniform",
"glGetUniformBlockIndex", "glGetUniformLocation", "glIsProgram", "glIsShader", "glLinkProgram",
"glProgramBinary", "glProgramParameteri", "glShaderSource", "glSpecializeShader", "glUniform1",
"glUniform1f", "glUniform1i", "glUniform2", "glUniform2f", "glUniform2i", "glUniform3", "glUniform3f",
"glUniform3i", "glUniform4", "glUniform4f", "glUniform4i", "glUniformBlockBinding", "glUniformMatrix2",
"glUniformMatrix3", "glUniformMatrix4", "glUseProgram", "glValidateProgram", "isProgramPendingDeletion",
"nglShaderSource", "setFfpInstancing"},
{"com/gtnewhorizons/angelica/glsm/GLSMQueries",
"checkGLError", "glBeginQuery", "glDeleteQueries", "glEndQuery", "glGenQueries", "glGetBoolean",
"glGetBooleani", "glGetBooleani_v", "glGetDouble", "glGetError", "glGetFloat", "glGetInteger",
"glGetIntegeri", "glGetIntegeri_v", "glGetQueryObjecti", "glGetQueryObjectui", "glGetQueryObjectui64",
"glGetString", "glGetStringi", "glIsQuery", "glQueryCounter"},
{"com/gtnewhorizons/angelica/glsm/GLSMRasterizer",
"anyClipPlaneEnabled", "disableCull", "disableScissorTest", "enableCull", "enableScissorTest",
"getAutoNormalState", "getClipPlaneState", "getClipPlaneStates", "getCullState", "getDitherState",
"getEdgeFlagState", "getHintState", "getLineSmoothState", "getLineState", "getLineStippleState",
"getMap1Color4State", "getMap1IndexState", "getMap1NormalState", "getMap1TextureCoord1State",
"getMap1TextureCoord2State", "getMap1TextureCoord3State", "getMap1TextureCoord4State",
"getMap1Vertex3State", "getMap1Vertex4State", "getMap2Color4State", "getMap2IndexState",
"getMap2NormalState", "getMap2TextureCoord1State", "getMap2TextureCoord2State", "getMap2TextureCoord3State",
"getMap2TextureCoord4State", "getMap2Vertex3State", "getMap2Vertex4State", "getMultisampleState",
"getPointSmoothState", "getPointSpriteState", "getPointState", "getPolygonOffsetFillState",
"getPolygonOffsetLineState", "getPolygonOffsetPointState", "getPolygonSmoothState", "getPolygonState",
"getPolygonStippleState", "getSampleAlphaToCoverageState", "getSampleAlphaToOneState",
"getSampleCoverageState", "getScissorState", "getScissorTest", "getShadeModelState", "getViewportState",
"glClipPlane", "glCullFace", "glFrontFace", "glGetClipPlane", "glHint", "glLineStipple", "glLineWidth",
"glPointParameter", "glPointParameterf", "glPointParameteri", "glPointSize", "glPolygonMode",
"glPolygonOffset", "glPolygonOffsetClamp", "glPolygonStipple", "glSampleCoverage", "glScissor",
"glShadeModel", "glViewport"},
{"com/gtnewhorizons/angelica/glsm/GLSMTexEnvGen",
"glGetTexEnv", "glGetTexEnvf", "glGetTexEnvi", "glGetTexGen", "glGetTexGend", "glGetTexGenf",
"glGetTexGeni", "glTexEnv", "glTexEnvf", "glTexEnvi", "glTexGen", "glTexGend", "glTexGenf", "glTexGeni"},
{"com/gtnewhorizons/angelica/glsm/GLSMTextureLifetime",
"deferredTexturesAwaitingRelease", "onFrameEnd"},
{"com/gtnewhorizons/angelica/glsm/GLSMTextures",
"abandonTextureStaging", "beginTextureStaging", "commitTextureStaging", "disableTexture", "enableTexture",
"forcePixelUnpackState", "getActiveTextureUnit", "getActiveTextureUnitForServerState",
"getActiveTextureUnitStack", "getBoundTextureForServerState", "getClientActiveTextureUnit",
"getImageUnitBinding", "getMaxBoundTextureUnit", "getSamplerBinding", "getSamplerUnitCount", "getTextures",
"glActiveTexture", "glActiveTextureARB", "glBindImageTexture", "glBindImageTextures",
"glBindMultiTextureEXT", "glBindSampler", "glBindSamplers", "glBindTexture", "glBindTextureUnit",
"glBindTextures", "glClearTexImage", "glClientActiveTexture", "glCopyImageSubData", "glCopyTexImage1D",
"glCopyTexImage2D", "glCopyTexSubImage1D", "glCopyTexSubImage2D", "glCopyTexSubImage3D", "glCreateTextures",
"glDeleteSamplers", "glDeleteTextures", "glGenSamplers", "glGenTextures", "glGenerateMipmap",
"glGetTexImage", "glGetTexLevelParameteri", "glGetTexParameterf", "glGetTexParameteri", "glIsSampler",
"glIsTexture", "glPixelStoref", "glPixelStorei", "glSamplerParameterf", "glSamplerParameteri",
"glTexImage1D", "glTexImage2D", "glTexImage3D", "glTexParameter", "glTexParameterf", "glTexParameteri",
"glTexStorage2D", "glTexSubImage1D", "glTexSubImage2D", "glTexSubImage3D", "lookupTexParameteri",
"markTextureAsAtlas", "remapTexClamp", "remapTexClampBuffer", "remapTexImageForGLES",
"restorePixelUnpackState", "setActiveTexture", "setFilter", "setTextureSupersamplingSamples",
"trackMaxBoundTextureUnit", "trimTextureStaging", "unbindAllSamplers", "updateTexParameterfCache",
"updateTexParameteriCache"},
{"com/gtnewhorizons/angelica/glsm/GLSMVertexInput",
"getBoundEBO", "getBoundVAO", "glBindVertexArray", "glBindVertexArrayAPPLE", "glBindVertexBuffer",
"glColorPointer", "glDeleteVertexArrays", "glDisableClientState", "glDisableVertexAttribArray",
"glEdgeFlagPointer", "glEnableClientState", "glEnableVertexAttribArray", "glFogCoordPointer",
"glGenVertexArrays", "glGetPointer", "glInterleavedArrays", "glIsVertexArray", "glNormalPointer",
"glSecondaryColorPointer", "glTexCoordPointer", "glVertexAttribBinding", "glVertexAttribDivisor",
"glVertexAttribDivisorARB", "glVertexAttribFormat", "glVertexAttribIFormat", "glVertexAttribIPointer",
"glVertexAttribPointer", "glVertexPointer"},
};
static final String[][] FIELDS = {
{"com/gtnewhorizons/angelica/glsm/GLSMAttribStack",
"attribBackendCalls", "attribDiscards", "attribPushes", "attribSlotsSaved", "attribValueRestores"},
{"com/gtnewhorizons/angelica/glsm/GLSMDraws",
"drawCalls"},
{"com/gtnewhorizons/angelica/glsm/GLSMFramebuffer",
"DEFAULT_DRAW_BUFFER"},
{"com/gtnewhorizons/angelica/glsm/GLSMPrograms",
"programSwitches"},
{"com/gtnewhorizons/angelica/glsm/GLSMRasterizer",
"wideLineEmulationEnabled"},
{"com/gtnewhorizons/angelica/glsm/GLSMTextures",
"TEX_PARAM_MISS", "texBindMisses"},
};
private GLSMOwners() {}
}
@@ -11,6 +11,8 @@ import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
@@ -21,13 +23,15 @@ import org.objectweb.asm.tree.TypeInsnNode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
/**
* Core GL call redirector for GLSM. Rewrites bytecode so that GL calls go through {@code GLStateManager} for state tracking and backend abstraction.
* Core GL call redirector for GLSM. Rewrites bytecode so GL calls go through the GLSM classes for state tracking and backend abstraction.
* <p>
* THIS CLASS MIGHT BE LOADED ON A DIFFERENT CLASS LOADER.
* IT SHOULD NOT CALL ANY CODE FROM THE MAIN MOD.
@@ -186,6 +190,12 @@ public class GLSMRedirector {
private static final Map<String, String> typeRedirects = new HashMap<>();
private static final ClassConstantPoolParser cstPoolParser;
private static final String[] CONSTANT_POOL_SEARCH_STRINGS;
private static final Map<String, String> methodOwner = new HashMap<>(512);
private static final Map<String, String> fieldOwner = new HashMap<>(64);
static final String[] CORE_REWRITE_TARGETS = {"makeCurrent", "releaseContext", "swapBuffers", "updateDisplay", "isCurrent"};
private static final Set<String> LEGACY_WARNED = ConcurrentHashMap.newKeySet();
private String legacyHint = "";
private LegacyRewriter legacyRewriter;
private static final String[] CORE_EXCLUSIONS = {
"org.lwjgl",
@@ -540,7 +550,9 @@ public class GLSMRedirector {
.add("glIsFramebuffer")
.add("glIsRenderbuffer")
.add("glBindBufferBase")
.add("glBindBufferRange");
.add("glBindBufferRange")
.add("glEnablei")
.add("glDisablei");
final var gl31 = RedirectMap.newMap()
.add("glDrawElementsInstanced")
.add("glDrawArraysInstanced")
@@ -574,7 +586,8 @@ public class GLSMRedirector {
.add("glVertexAttribFormat")
.add("glVertexAttribIFormat")
.add("glVertexAttribBinding")
.add("glMultiDrawElementsIndirect");
.add("glMultiDrawElementsIndirect")
.add("glCopyImageSubData");
final var gl44 = RedirectMap.newMap()
.add("glBufferStorage")
.add("glBindSamplers")
@@ -899,10 +912,34 @@ public class GLSMRedirector {
stringsToSearch.add(Drawable);
stringsToSearch.add(SharedDrawable);
stringsToSearch.add(Display);
stringsToSearch.add(GLStateManager);
stringsToSearch.addAll(typeRedirects.keySet());
stringsToSearch.addAll(methodRedirects.keySet());
CONSTANT_POOL_SEARCH_STRINGS = stringsToSearch.toArray(new String[0]);
cstPoolParser = new ClassConstantPoolParser(CONSTANT_POOL_SEARCH_STRINGS);
fillOwners(methodOwner, GLSMOwners.METHODS);
fillOwners(fieldOwner, GLSMOwners.FIELDS);
}
private static void fillOwners(Map<String, String> owners, String[][] table) {
for (String[] row : table) {
for (int i = 1; i < row.length; i++) owners.put(row[i], row[0]);
}
}
static Set<String> redirectTargets() {
final Set<String> targets = new TreeSet<>(glMethodRedirects.values());
targets.addAll(glDescRedirects.values());
for (Map<String, String> inner : methodRedirects.values()) targets.addAll(inner.values());
for (String cap : glCapRedirects.values()) {
targets.add("enable" + cap);
targets.add("disable" + cap);
}
targets.add("glEnable");
targets.add("glDisable");
Collections.addAll(targets, CORE_REWRITE_TARGETS);
return targets;
}
public String[] getCoreExclusions() {
@@ -915,9 +952,46 @@ public class GLSMRedirector {
public static String getGLPrefix() { return GL_PREFIX; }
public static String getTargetClassName() { return GLStateManager; }
public static String getTargetOwner(String glsmName) { return methodOwner.getOrDefault(glsmName, GLStateManager); }
/** Key: original method name, value: GLStateManager method name. */
public static List<String> glsmClasses() {
final Set<String> classes = new LinkedHashSet<>();
classes.add(GLStateManager);
for (String[] row : GLSMOwners.METHODS) classes.add(row[0]);
for (String[] row : GLSMOwners.FIELDS) classes.add(row[0]);
return List.copyOf(classes);
}
public void setLegacyHint(String hint) { this.legacyHint = hint; }
public void setLegacyRewriter(LegacyRewriter rewriter) { this.legacyRewriter = rewriter; }
private static String simpleName(String internalName) {
return internalName.substring(internalName.lastIndexOf('/') + 1);
}
private void warnLegacy(String transformedName, String name, String newOwner) {
warnLegacyUse(transformedName, name, "moved to " + simpleName(newOwner) + "." + name);
}
private void warnLegacyUse(String transformedName, String name, String outcome) {
final int dot = transformedName.lastIndexOf('.');
final String key = dot < 0 ? transformedName : transformedName.substring(0, dot);
if (LEGACY_WARNED.add(key)) {
LOGGER.warn("{} uses GLStateManager.{}, {}; rewritten at load.{}", transformedName, name, outcome, legacyHint.isEmpty() ? "" : " " + legacyHint);
}
}
private boolean tryLegacyRewrite(String transformedName, InsnList instructions, MethodInsnNode call) {
if (legacyRewriter == null) return false;
final String name = call.name;
final String replacement = legacyRewriter.rewrite(instructions, call);
if (replacement == null) return false;
warnLegacyUse(transformedName, name, "redirected to " + replacement);
return true;
}
/** @return Map from GL method name to GLSM method name. {@link #getTargetOwner} gives its class. */
public static Map<String, String> getGLPrefixMethodRedirects() {
return Collections.unmodifiableMap(glMethodRedirects);
}
@@ -943,7 +1017,9 @@ public class GLSMRedirector {
if (isOpenGlHelper && (mn.name.equals("glBlendFunc") || mn.name.equals("func_148821_a"))) {
continue;
}
boolean rewroteLegacy = false;
for (AbstractInsnNode node : mn.instructions.toArray()) {
if (rewroteLegacy && !mn.instructions.contains(node)) continue;
if (node instanceof TypeInsnNode tNode) {
if (tNode.getOpcode() == Opcodes.NEW || tNode.getOpcode() == Opcodes.CHECKCAST) {
final String redirect = typeRedirects.get(tNode.desc);
@@ -955,7 +1031,29 @@ public class GLSMRedirector {
changed = true;
}
}
} else if (node instanceof FieldInsnNode fNode) {
if (fNode.owner.equals(GLStateManager) && (fNode.getOpcode() == Opcodes.GETSTATIC || fNode.getOpcode() == Opcodes.PUTSTATIC)) {
final String newOwner = fieldOwner.get(fNode.name);
if (newOwner != null) {
warnLegacy(transformedName, fNode.name, newOwner);
fNode.owner = newOwner;
changed = true;
}
}
} else if (node instanceof MethodInsnNode mNode) {
if (mNode.owner.equals(GLStateManager)) {
if (tryLegacyRewrite(transformedName, mn.instructions, mNode)) {
rewroteLegacy = true;
changed = true;
continue;
}
final String newOwner = methodOwner.get(mNode.name);
if (newOwner != null) {
warnLegacy(transformedName, mNode.name, newOwner);
mNode.owner = newOwner;
changed = true;
}
}
if (mNode.desc.equals("(I)V") && mNode.owner.startsWith(GL_PREFIX) && (mNode.name.equals("glEnable") || mNode.name.equals("glDisable"))) {
final AbstractInsnNode prevNode = node.getPrevious();
String name = null;
@@ -974,12 +1072,12 @@ public class GLSMRedirector {
if (LOG_SPAM) {
final String shortOwner = mNode.owner.substring(mNode.owner.lastIndexOf("/") + 1);
if (name == null) {
LOGGER.info("Redirecting call in {} from {}.{}(I)V to GLStateManager.{}(I)V", transformedName, shortOwner, mNode.name, mNode.name);
LOGGER.info("Redirecting call in {} from {}.{}(I)V to {}.{}(I)V", transformedName, shortOwner, mNode.name, simpleName(getTargetOwner(mNode.name)), mNode.name);
} else {
LOGGER.info("Redirecting call in {} from {}.{}(I)V to GLStateManager.{}()V", transformedName, shortOwner, mNode.name, name);
LOGGER.info("Redirecting call in {} from {}.{}(I)V to {}.{}()V", transformedName, shortOwner, mNode.name, simpleName(getTargetOwner(name)), name);
}
}
mNode.owner = GLStateManager;
mNode.owner = getTargetOwner(name != null ? name : mNode.name);
if (name != null) {
mNode.name = name;
mNode.desc = "()V";
@@ -1039,9 +1137,9 @@ public class GLSMRedirector {
} else if (glsmName != null) {
if (LOG_SPAM) {
final String shortOwner = mNode.owner.substring(mNode.owner.lastIndexOf("/") + 1);
LOGGER.info("Redirecting call in {} from {}.{}{} to GLStateManager.{}{}", transformedName, shortOwner, mNode.name, mNode.desc, glsmName, mNode.desc);
LOGGER.info("Redirecting call in {} from {}.{}{} to {}.{}{}", transformedName, shortOwner, mNode.name, mNode.desc, simpleName(getTargetOwner(glsmName)), glsmName, mNode.desc);
}
mNode.owner = GLStateManager;
mNode.owner = getTargetOwner(glsmName);
mNode.name = glsmName;
changed = true;
} else if (lwjgl3Aware && mNode.owner.startsWith(LWJGL_GL_PACKAGE) && hasLwjglTypedDescriptor(mNode.desc) && !isAwareNonDispatching(mNode.owner, mNode.name)) {
@@ -1066,6 +1164,17 @@ public class GLSMRedirector {
// Redirect method handles in invokedynamic bootstrap arguments
for (int i = 0; i < dynNode.bsmArgs.length; i++) {
if (!(dynNode.bsmArgs[i] instanceof Handle handle)) continue;
if (handle.getOwner().equals(GLStateManager)) {
final int tag = handle.getTag();
final String newOwner = tag == Opcodes.H_INVOKESTATIC ? methodOwner.get(handle.getName())
: tag == Opcodes.H_GETSTATIC || tag == Opcodes.H_PUTSTATIC ? fieldOwner.get(handle.getName()) : null;
if (newOwner != null) {
warnLegacy(transformedName, handle.getName(), newOwner);
dynNode.bsmArgs[i] = new Handle(tag, newOwner, handle.getName(), handle.getDesc());
changed = true;
continue;
}
}
String glsmName = glDescRedirects.get(handle.getOwner() + " " + handle.getName() + handle.getDesc());
if (glsmName == null) {
final Map<String, String> redirects = handle.getOwner().startsWith(GL_PREFIX) ? glMethodRedirects : methodRedirects.get(handle.getOwner());
@@ -1081,9 +1190,9 @@ public class GLSMRedirector {
}
if (LOG_SPAM) {
final String shortOwner = handle.getOwner().substring(handle.getOwner().lastIndexOf("/") + 1);
LOGGER.info("Redirecting invokedynamic handle in {} from {}.{}{} to GLStateManager.{}{}", transformedName, shortOwner, handle.getName(), handle.getDesc(), glsmName, handle.getDesc());
LOGGER.info("Redirecting invokedynamic handle in {} from {}.{}{} to {}.{}{}", transformedName, shortOwner, handle.getName(), handle.getDesc(), simpleName(getTargetOwner(glsmName)), glsmName, handle.getDesc());
}
dynNode.bsmArgs[i] = new Handle(handle.getTag(), GLStateManager, glsmName, handle.getDesc());
dynNode.bsmArgs[i] = new Handle(handle.getTag(), getTargetOwner(glsmName), glsmName, handle.getDesc());
changed = true;
}
}
@@ -0,0 +1,10 @@
package com.gtnewhorizons.angelica.glsm.redirect;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
public interface LegacyRewriter {
/** Replaces {@code call} in place and returns the replacement's name for the legacy warning, or null to leave it alone. */
String rewrite(InsnList instructions, MethodInsnNode call);
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.glsm.shader;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMPrograms;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import com.gtnewhorizons.angelica.glsm.ffp.ShaderManager;
import com.gtnewhorizons.angelica.glsm.threading.AngelicaWorkers;
@@ -73,7 +73,7 @@ public final class ProgramBinaryCache {
}
public static void markRetrievable(int program) {
GLStateManager.glProgramParameteri(program, GL41.GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL11.GL_TRUE);
GLSMPrograms.glProgramParameteri(program, GL41.GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL11.GL_TRUE);
}
public static int load(Key key) {
@@ -87,16 +87,16 @@ public final class ProgramBinaryCache {
ShaderDiskCache.remove(diskKey);
return 0;
}
final int program = GLStateManager.glCreateProgram();
final int program = GLSMPrograms.glCreateProgram();
final ByteBuffer data = MemoryUtilities.memAlloc(blob.data().length);
try {
data.put(blob.data()).flip();
GLStateManager.glProgramBinary(program, format, data);
GLSMPrograms.glProgramBinary(program, format, data);
} finally {
MemoryUtilities.memFree(data);
}
if (GLStateManager.glGetProgrami(program, GL20.GL_LINK_STATUS) != GL11.GL_TRUE) {
GLStateManager.glDeleteProgram(program);
if (GLSMPrograms.glGetProgrami(program, GL20.GL_LINK_STATUS) != GL11.GL_TRUE) {
GLSMPrograms.glDeleteProgram(program);
ShaderDiskCache.remove(diskKey);
if (rejectWarned.compareAndSet(false, true)) LOGGER.error("Driver rejected a saved shader program!! Recompiling rejected programs from source");
return 0;
@@ -112,13 +112,13 @@ public final class ProgramBinaryCache {
}
private static boolean saveBinary(Key key, int program) {
final int length = GLStateManager.glGetProgrami(program, GL41.GL_PROGRAM_BINARY_LENGTH);
final int length = GLSMPrograms.glGetProgrami(program, GL41.GL_PROGRAM_BINARY_LENGTH);
if (length <= 0) return false;
final ByteBuffer data = MemoryUtilities.memAlloc(length);
final IntBuffer written = MemoryUtilities.memAllocInt(1);
final IntBuffer format = MemoryUtilities.memAllocInt(1);
try {
GLStateManager.glGetProgramBinary(program, written, format, data);
GLSMPrograms.glGetProgramBinary(program, written, format, data);
if (written.get(0) <= 0) return false;
data.limit(written.get(0));
final byte[] binary = ShaderCacheIO.toHeap(data);
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMAttribStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.hooks.VanillaBooleanLayer;
import com.gtnewhorizons.angelica.glsm.states.BooleanState;
@@ -90,7 +91,7 @@ public class BooleanStateStack extends BooleanState implements CowStateStack<Boo
@Override
public int getDepth() {
return GLStateManager.getAttribDepth();
return GLSMAttribStack.getAttribDepth();
}
@Override
@@ -2,7 +2,7 @@ package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMAttribStack;
/**
* __n__n__
@@ -56,7 +56,7 @@ public interface CowStateStack<T> extends IStateStack<T> {
final int depth = o.attribDepth;
if (depth == 0 || d.claimedAt(depth) || !o.savesState(d.id)) return;
captureSlot(d.claim(depth));
GLStateManager.registerModifiedState(o, d.id);
GLSMAttribStack.registerModifiedState(o, d.id);
}
@Override
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.backend.BackendManager;
import com.gtnewhorizons.angelica.glsm.hooks.GLSMHooks;
@@ -50,7 +51,7 @@ public final class TextureUnitBooleanStateStack extends BooleanStateStack {
}
if (!ffpStateOnly) {
final int currentUnit = GLStateManager.getActiveTextureUnit();
final int currentUnit = GLSMTextures.getActiveTextureUnit();
final boolean needsSwitch = currentUnit != unitIndex;
if (needsSwitch) BackendManager.RENDER_BACKEND.activeTexture(GL13.GL_TEXTURE0 + unitIndex);
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.states;
import com.gtnewhorizons.angelica.glsm.GLSMAttribStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import lombok.Getter;
import org.lwjgl.opengl.GL11;
@@ -45,7 +46,7 @@ public class BooleanState implements ISettableState<BooleanState> {
public void setEnabled(boolean enabled) {
final boolean bypass = !GLStateManager.isCachingEnabled();
if (stateUnknown || bypass || enabled != this.enabled || (this.glCap == GL11.GL_BLEND && GLStateManager.vendorIsAMD() && GLStateManager.isPoppingAttributes())) {
if (stateUnknown || bypass || enabled != this.enabled || (this.glCap == GL11.GL_BLEND && GLStateManager.vendorIsAMD() && GLSMAttribStack.isPoppingAttributes())) {
GLStateManager.beforeUncapturedCapabilityChange(glCap);
stateUnknown = false;
this.enabled = enabled;
@@ -8,7 +8,7 @@ import org.lwjgl.opengl.GL12;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.i2f;
import static com.gtnewhorizons.angelica.glsm.GLSMLighting.i2f;
public class LightModelState implements ISettableState<LightModelState> {
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.states;
import com.gtnewhorizons.angelica.glsm.GLSMMatrices;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.joml.Matrix3f;
import org.joml.Vector3f;
@@ -11,7 +12,7 @@ import org.lwjgl.opengl.GL11;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.i2f;
import static com.gtnewhorizons.angelica.glsm.GLSMLighting.i2f;
public class LightState implements ISettableState<LightState> {
@@ -73,14 +74,14 @@ public class LightState implements ISettableState<LightState> {
this.rawPosition = new Vector4f(position);
this.position = position;
this.position.mul(GLStateManager.getModelViewMatrix());
this.posMvGeneration = GLStateManager.getMvGeneration();
this.position.mul(GLSMMatrices.getModelViewMatrix());
this.posMvGeneration = GLSMMatrices.getMvGeneration();
this.rawSpotDirection = new Vector3f(spotDirection);
this.spotDirection = spotDirection;
GLStateManager.getModelViewMatrix().get3x3(matrix3f);
GLSMMatrices.getModelViewMatrix().get3x3(matrix3f);
this.spotDirection.mul(matrix3f);
this.spotDirLinearGeneration = GLStateManager.getMvLinearGeneration();
this.spotDirLinearGeneration = GLSMMatrices.getMvLinearGeneration();
}
public boolean setAmbient(FloatBuffer newBuffer) {
@@ -152,12 +153,12 @@ public class LightState implements ISettableState<LightState> {
}
private boolean applyPosition(Vector4f raw) {
final int mvGen = GLStateManager.getMvGeneration();
final int mvGen = GLSMMatrices.getMvGeneration();
if (!GLStateManager.isCachingEnabled() || this.posMvGeneration != mvGen || !this.rawPosition.equals(raw)) {
this.rawPosition.set(raw);
this.posMvGeneration = mvGen;
this.position.set(raw);
this.position.mul(GLStateManager.getModelViewMatrix());
this.position.mul(GLSMMatrices.getModelViewMatrix());
return true;
}
return false;
@@ -175,11 +176,11 @@ public class LightState implements ISettableState<LightState> {
}
private boolean applySpotDirection(Vector3f raw) {
final int mvLinearGen = GLStateManager.getMvLinearGeneration();
final int mvLinearGen = GLSMMatrices.getMvLinearGeneration();
if (!GLStateManager.isCachingEnabled() || this.spotDirLinearGeneration != mvLinearGen || !this.rawSpotDirection.equals(raw)) {
this.rawSpotDirection.set(raw);
this.spotDirLinearGeneration = mvLinearGen;
GLStateManager.getModelViewMatrix().get3x3(matrix3f);
GLSMMatrices.getModelViewMatrix().get3x3(matrix3f);
this.spotDirection.set(raw);
this.spotDirection.mul(matrix3f);
return true;
@@ -9,7 +9,7 @@ import org.joml.Vector4i;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static com.gtnewhorizons.angelica.glsm.GLStateManager.i2f;
import static com.gtnewhorizons.angelica.glsm.GLSMLighting.i2f;
public class MaterialState implements ISettableState<MaterialState> {
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.streaming;
import com.gtnewhorizons.angelica.config.SystemProperties;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import org.lwjgl.opengl.GL30;
@@ -50,15 +51,15 @@ final class GlStreamingRing {
static GlStreamingRing create(int target, int capacity, boolean forceOrphan) {
if (forceOrphan || !RenderSystem.supportsBufferStorage()) return null;
final int id = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(target, id);
final int id = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(target, id);
final int storageFlags = GL44.GL_MAP_PERSISTENT_BIT | GL30.GL_MAP_WRITE_BIT | GL44.GL_MAP_COHERENT_BIT | GL44.GL_CLIENT_STORAGE_BIT;
RenderSystem.bufferStorage(target, capacity, storageFlags);
final int mapFlags = GL44.GL_MAP_PERSISTENT_BIT | GL30.GL_MAP_WRITE_BIT | GL44.GL_MAP_COHERENT_BIT;
final ByteBuffer mapped = GLStateManager.glMapBufferRange(target, 0, capacity, mapFlags);
GLStateManager.glBindBuffer(target, 0);
final ByteBuffer mapped = GLSMBuffers.glMapBufferRange(target, 0, capacity, mapFlags);
GLSMBuffers.glBindBuffer(target, 0);
if (mapped == null) {
GLStateManager.glDeleteBuffers(id);
GLSMBuffers.glDeleteBuffers(id);
GLStateManager.LOGGER.warn("Persistent map failed for streaming ring (target=0x{}, {} bytes)", Integer.toHexString(target), capacity);
return null;
}
@@ -102,7 +103,7 @@ final class GlStreamingRing {
private void fence() {
if (pendingBytes > 0) {
fences.enqueue(GLStateManager.glFenceSync(GL32.GL_SYNC_GPU_COMMANDS_COMPLETE, 0), pendingBytes);
fences.enqueue(GLSMBuffers.glFenceSync(GL32.GL_SYNC_GPU_COMMANDS_COMPLETE, 0), pendingBytes);
pendingBytes = 0;
fencesIssued++;
totalFencesIssued++;
@@ -116,8 +117,8 @@ final class GlStreamingRing {
private void reclaim() {
while (!fences.isEmpty()) {
final long fenceId = fences.firstId();
if (!signaled(GLStateManager.glClientWaitSync(fenceId, 0, 0L))) break;
GLStateManager.glDeleteSync(fenceId);
if (!signaled(GLSMBuffers.glClientWaitSync(fenceId, 0, 0L))) break;
GLSMBuffers.glDeleteSync(fenceId);
remaining += fences.firstBytes();
fences.dequeue();
}
@@ -132,14 +133,14 @@ final class GlStreamingRing {
long remainingNanos = SYNC_WAIT_TOTAL_NANOS;
int status;
do {
status = GLStateManager.glClientWaitSync(fenceId, GL32.GL_SYNC_FLUSH_COMMANDS_BIT,
status = GLSMBuffers.glClientWaitSync(fenceId, GL32.GL_SYNC_FLUSH_COMMANDS_BIT,
Math.min(SYNC_WAIT_SLICE_NANOS, remainingNanos));
remainingNanos = deadline - System.nanoTime();
} while (status == GL32.GL_TIMEOUT_EXPIRED && remainingNanos > 0);
if (!signaled(status)) {
GLStateManager.LOGGER.warn("Streaming ring fence wait did not signal (status=0x{}); reclaiming anyway", Integer.toHexString(status));
}
GLStateManager.glDeleteSync(fenceId);
GLSMBuffers.glDeleteSync(fenceId);
remaining += bytes;
reclaim();
}
@@ -161,14 +162,14 @@ final class GlStreamingRing {
void destroy() {
while (!fences.isEmpty()) {
GLStateManager.glDeleteSync(fences.firstId());
GLSMBuffers.glDeleteSync(fences.firstId());
fences.dequeue();
}
if (bufferId != 0) {
GLStateManager.glBindBuffer(target, bufferId);
GLStateManager.glUnmapBuffer(target);
GLStateManager.glBindBuffer(target, 0);
GLStateManager.glDeleteBuffers(bufferId);
GLSMBuffers.glBindBuffer(target, bufferId);
GLSMBuffers.glUnmapBuffer(target);
GLSMBuffers.glBindBuffer(target, 0);
GLSMBuffers.glDeleteBuffers(bufferId);
bufferId = 0;
}
}
@@ -4,6 +4,7 @@ import com.gtnewhorizon.gtnhlib.client.renderer.vertex.DefaultVertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement;
import com.gtnewhorizons.angelica.glsm.GLSMRasterizer;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.ffp.VAOManager;
import org.lwjgl.opengl.GL11;
@@ -60,16 +61,16 @@ public final class LineQuads {
}
public static boolean disableCulling() {
final boolean wasEnabled = GLStateManager.getCullState().isEnabled();
final boolean wasEnabled = GLSMRasterizer.getCullState().isEnabled();
if (wasEnabled) {
GLStateManager.disableCull();
GLSMRasterizer.disableCull();
}
return wasEnabled;
}
public static void restoreCulling(boolean wasEnabled) {
if (wasEnabled) {
GLStateManager.enableCull();
GLSMRasterizer.enableCull();
}
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.streaming;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import org.lwjgl.opengl.GL15;
import java.nio.ByteBuffer;
@@ -14,19 +14,19 @@ public final class OrphanStreamingBuffer {
private int capacity;
public OrphanStreamingBuffer() {
this.bufferId = GLStateManager.glGenBuffers();
this.bufferId = GLSMBuffers.glGenBuffers();
}
public void upload(ByteBuffer data) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
capacity = StreamingUploader.upload(data, capacity);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
void upload(StreamingUploader.UploadStrategy strategy, ByteBuffer data) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
capacity = StreamingUploader.upload(strategy, data, capacity);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public int getCapacity() {
@@ -39,7 +39,7 @@ public final class OrphanStreamingBuffer {
public void destroy() {
if (bufferId != 0) {
GLStateManager.glDeleteBuffers(bufferId);
GLSMBuffers.glDeleteBuffers(bufferId);
bufferId = 0;
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.streaming;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
@@ -27,30 +28,30 @@ public final class StreamingUploader {
public static int upload(UploadStrategy strategy, ByteBuffer data, int capacity) {
switch (strategy) {
case BUFFER_DATA -> {
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
return data.remaining();
}
case BUFFER_SUB_DATA -> {
if (data.remaining() > capacity) {
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
return data.remaining();
}
GLStateManager.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, data);
GLSMBuffers.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, data);
return capacity;
}
case MAP_BUFFER_RANGE -> {
if (data.remaining() > capacity) {
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
return data.remaining();
}
final int dataSize = data.remaining();
final long dst = GLStateManager.glMapBufferRangeAddress(GL15.GL_ARRAY_BUFFER, 0, dataSize, MAP_WRITE_INVALIDATE_BUFFER);
final long dst = GLSMBuffers.glMapBufferRangeAddress(GL15.GL_ARRAY_BUFFER, 0, dataSize, MAP_WRITE_INVALIDATE_BUFFER);
if (dst == 0L) {
GLStateManager.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
GLSMBuffers.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STREAM_DRAW);
return data.remaining();
}
memCopy(memAddress0(data), dst, dataSize);
GLStateManager.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
GLSMBuffers.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
return capacity;
}
default -> throw new UnsupportedOperationException();
@@ -7,6 +7,10 @@ import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormatElement;
import com.gtnewhorizons.angelica.config.SystemProperties;
import com.gtnewhorizons.angelica.glsm.GLContextState;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import com.gtnewhorizons.angelica.glsm.GLSMCurrentAttribs;
import com.gtnewhorizons.angelica.glsm.GLSMDraws;
import com.gtnewhorizons.angelica.glsm.GLSMVertexInput;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.QuadConverter;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
@@ -179,7 +183,7 @@ public class TessellatorStreamingDrawer {
final int[] rawBuffer = tess.rawBuffer;
final int defaultColor;
if (!tess.hasColor) {
final var c = GLStateManager.getColor();
final var c = GLSMCurrentAttribs.getColor();
defaultColor = ((int)(clamp(0f, 1f, c.getAlpha()) * 255) << 24) | ((int)(clamp(0f, 1f, c.getBlue()) * 255) << 16)
| ((int)(clamp(0f, 1f, c.getGreen()) * 255) << 8) | (int)(clamp(0f, 1f, c.getRed()) * 255);
} else {
@@ -367,10 +371,10 @@ public class TessellatorStreamingDrawer {
final boolean fromRing = firstVertex >= 0;
if (fromRing) {
GLStateManager.glBindVertexArray(persistentVAOs[flags]);
GLSMVertexInput.glBindVertexArray(persistentVAOs[flags]);
} else {
if (Tracy.ENABLED && persistentBuffer != null) orphanFallbacks++;
GLStateManager.glBindVertexArray(orphanVAOs[flags]);
GLSMVertexInput.glBindVertexArray(orphanVAOs[flags]);
orphanBuffers[flags].upload(packed);
firstVertex = 0;
}
@@ -382,7 +386,7 @@ public class TessellatorStreamingDrawer {
}
drawWithQuadConversion(glCtx, drawMode, firstVertex, vertexCount);
GLStateManager.glBindVertexArray(0);
GLSMVertexInput.glBindVertexArray(0);
} finally {
if (locked) GLStateManager.releaseDrawLock();
Tracy.endZone();
@@ -403,7 +407,7 @@ public class TessellatorStreamingDrawer {
}
return true;
}
if (GLStateManager.ffpWidensLineQuads()) {
if (GLSMDraws.ffpWidensLineQuads()) {
final GLContextState glCtx = GLStateManager.ctx();
glCtx.lineQuadsActive = true;
try {
@@ -463,10 +467,10 @@ public class TessellatorStreamingDrawer {
FfpExtendedAttribs.beginInternalDraw();
try {
if (drawMode == GL11.GL_QUADS) {
GLStateManager.drawCalls++;
GLSMDraws.drawCalls++;
QuadConverter.drawQuadsAsTriangles(glCtx, firstVertex, vertexCount);
} else {
GLStateManager.glDrawArrays(drawMode, firstVertex, vertexCount);
GLSMDraws.glDrawArrays(drawMode, firstVertex, vertexCount);
}
} finally {
FfpExtendedAttribs.endInternalDraw();
@@ -486,36 +490,36 @@ public class TessellatorStreamingDrawer {
}
if (firstVertex >= 0) {
GLStateManager.glBindVertexArray(vaos.extendedPersistent(layout)[flags]);
GLSMVertexInput.glBindVertexArray(vaos.extendedPersistent(layout)[flags]);
} else {
GLStateManager.glBindVertexArray(vaos.extendedOrphan(layout)[flags]);
GLSMVertexInput.glBindVertexArray(vaos.extendedOrphan(layout)[flags]);
orphanBuffers[flags].upload(combined);
firstVertex = 0;
}
drawWithQuadConversion(glCtx, drawMode, firstVertex, vertexCount);
GLStateManager.glBindVertexArray(0);
GLSMVertexInput.glBindVertexArray(0);
}
private static void ensureExtendedVAOs(StreamingVaos vaos, int flags, VertexFormat format, int layout) {
final int[] extendedOrphanVAOs = vaos.extendedOrphan(layout);
final int[] extendedPersistentVAOs = vaos.extendedPersistent(layout);
if (extendedOrphanVAOs[flags] == 0) {
extendedOrphanVAOs[flags] = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(extendedOrphanVAOs[flags]);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, orphanBuffers[flags].getBufferId());
extendedOrphanVAOs[flags] = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(extendedOrphanVAOs[flags]);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, orphanBuffers[flags].getBufferId());
setupExtendedBufferState(format, layout);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glBindVertexArray(0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glBindVertexArray(0);
}
if (persistentBuffer != null && extendedPersistentVAOs[flags] == 0) {
extendedPersistentVAOs[flags] = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(extendedPersistentVAOs[flags]);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, persistentBuffer.getBufferId());
extendedPersistentVAOs[flags] = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(extendedPersistentVAOs[flags]);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, persistentBuffer.getBufferId());
setupExtendedBufferState(format, layout);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glBindVertexArray(0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glBindVertexArray(0);
}
}
@@ -606,19 +610,19 @@ public class TessellatorStreamingDrawer {
if (orphanBuffers[flags] == null) orphanBuffers[flags] = new OrphanStreamingBuffer();
if (orphanVAOs[flags] == 0) {
orphanVAOs[flags] = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(orphanVAOs[flags]);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, orphanBuffers[flags].getBufferId());
orphanVAOs[flags] = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(orphanVAOs[flags]);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, orphanBuffers[flags].getBufferId());
format.setupBufferState(0L);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
if (persistentBuffer != null && persistentVAOs[flags] == 0) {
persistentVAOs[flags] = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(persistentVAOs[flags]);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, persistentBuffer.getBufferId());
persistentVAOs[flags] = GLSMVertexInput.glGenVertexArrays();
GLSMVertexInput.glBindVertexArray(persistentVAOs[flags]);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, persistentBuffer.getBufferId());
format.setupBufferState(0L);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.glsm.streaming;
import com.gtnewhorizons.angelica.config.SystemProperties;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMBuffers;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
@@ -34,10 +34,10 @@ public final class UniformRingBuffer {
this.stride = (blockSize + OFFSET_ALIGNMENT - 1) & -OFFSET_ALIGNMENT;
this.ring = GlStreamingRing.create(GL31.GL_UNIFORM_BUFFER, capacity, forceOrphan);
if (ring == null) {
orphanBufferId = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL31.GL_UNIFORM_BUFFER, orphanBufferId);
GLStateManager.glBufferData(GL31.GL_UNIFORM_BUFFER, capacity, GL15.GL_STREAM_DRAW);
GLStateManager.glBindBuffer(GL31.GL_UNIFORM_BUFFER, 0);
orphanBufferId = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(GL31.GL_UNIFORM_BUFFER, orphanBufferId);
GLSMBuffers.glBufferData(GL31.GL_UNIFORM_BUFFER, capacity, GL15.GL_STREAM_DRAW);
GLSMBuffers.glBindBuffer(GL31.GL_UNIFORM_BUFFER, 0);
}
}
@@ -55,20 +55,20 @@ public final class UniformRingBuffer {
}
private int writeOrphan(long srcAddress) {
GLStateManager.glBindBuffer(GL31.GL_UNIFORM_BUFFER, orphanBufferId);
GLSMBuffers.glBindBuffer(GL31.GL_UNIFORM_BUFFER, orphanBufferId);
int offset = writePos;
if (offset + stride > capacity) {
GLStateManager.glBufferData(GL31.GL_UNIFORM_BUFFER, capacity, GL15.GL_STREAM_DRAW);
GLSMBuffers.glBufferData(GL31.GL_UNIFORM_BUFFER, capacity, GL15.GL_STREAM_DRAW);
offset = 0;
orphanWraps++;
}
final long dst = GLStateManager.glMapBufferRangeAddress(GL31.GL_UNIFORM_BUFFER, offset, blockSize, GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_INVALIDATE_RANGE_BIT | GL30.GL_MAP_UNSYNCHRONIZED_BIT);
final long dst = GLSMBuffers.glMapBufferRangeAddress(GL31.GL_UNIFORM_BUFFER, offset, blockSize, GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_INVALIDATE_RANGE_BIT | GL30.GL_MAP_UNSYNCHRONIZED_BIT);
if (dst == 0L) {
throw new IllegalStateException("mapBufferRange failed on uniform ring (offset=" + offset + ")");
}
memCopy(srcAddress, dst, blockSize);
GLStateManager.glUnmapBuffer(GL31.GL_UNIFORM_BUFFER);
GLStateManager.glBindBuffer(GL31.GL_UNIFORM_BUFFER, 0);
GLSMBuffers.glUnmapBuffer(GL31.GL_UNIFORM_BUFFER);
GLSMBuffers.glBindBuffer(GL31.GL_UNIFORM_BUFFER, 0);
writePos = offset + stride;
return offset;
}
@@ -91,7 +91,7 @@ public final class UniformRingBuffer {
if (ring != null) {
ring.destroy();
} else if (orphanBufferId != 0) {
GLStateManager.glDeleteBuffers(orphanBufferId);
GLSMBuffers.glDeleteBuffers(orphanBufferId);
orphanBufferId = 0;
}
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.glsm.texture;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import lombok.Getter;
import lombok.Setter;
@@ -126,14 +126,14 @@ public class TextureInfo {
}
private int queryParameteri(int pname) {
if (GLStateManager.getBoundTextureForServerState() == id) {
if (GLSMTextures.getBoundTextureForServerState() == id) {
return RENDER_BACKEND.getTexParameteri(target, pname);
}
return RENDER_BACKEND.getTextureParameteri(id, target, pname);
}
private float queryParameterf(int pname) {
if (GLStateManager.getBoundTextureForServerState() == id) {
if (GLSMTextures.getBoundTextureForServerState() == id) {
return RENDER_BACKEND.getTexParameterf(target, pname);
}
return RENDER_BACKEND.getTextureParameterf(id, target, pname);
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.texture;
import com.gtnewhorizons.angelica.glsm.GLSMTextures;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@@ -86,15 +87,15 @@ public class TextureInfoCache {
}
public void onTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, @Nullable Buffer pixels) {
if (isTrackedTarget(target) && level == 0) defineLevelZero(GLStateManager.getBoundTextureForServerState(), target, internalformat, width, height);
if (isTrackedTarget(target) && level == 0) defineLevelZero(GLSMTextures.getBoundTextureForServerState(), target, internalformat, width, height);
}
public void onTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, long pixels_buffer_offset) {
if (isTrackedTarget(target) && level == 0) defineLevelZero(GLStateManager.getBoundTextureForServerState(), target, internalformat, width, height);
if (isTrackedTarget(target) && level == 0) defineLevelZero(GLSMTextures.getBoundTextureForServerState(), target, internalformat, width, height);
}
public void onCopyTexImage2D(int target, int level, int internalformat, int width, int height) {
if (isTrackedTarget(target) && level == 0) defineLevelZero(GLStateManager.getBoundTextureForServerState(), target, internalformat, width, height);
if (isTrackedTarget(target) && level == 0) defineLevelZero(GLSMTextures.getBoundTextureForServerState(), target, internalformat, width, height);
}
public void onTextureImage2D(int texture, int target, int level, int internalformat, int width, int height) {
@@ -102,11 +103,11 @@ public class TextureInfoCache {
}
public void onTexStorage2D(int target, int internalformat, int width, int height) {
if (isTrackedTarget(target)) defineLevelZero(GLStateManager.getBoundTextureForServerState(), target, internalformat, width, height);
if (isTrackedTarget(target)) defineLevelZero(GLSMTextures.getBoundTextureForServerState(), target, internalformat, width, height);
}
public void onTexSubImage2D(int target, int level) {
if (isTrackedTarget(target) && level == 0) onContentsChanged(GLStateManager.getBoundTextureForServerState());
if (isTrackedTarget(target) && level == 0) onContentsChanged(GLSMTextures.getBoundTextureForServerState());
}
public static boolean isGenericCompressedInternalFormat(int internalFormat) {
@@ -29,7 +29,7 @@ class ArrayUniformUploadGLTest {
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);
GLSMPrograms.glUniform2(GL20.glGetUniformLocation(p, "cosmicuvs"), buf);
final FloatBuffer read = BufferUtils.createFloatBuffer(2);
for (int i = 0; i < 10; i++) {
@@ -42,7 +42,7 @@ class ArrayUniformUploadGLTest {
}
} finally {
GL20.glUseProgram(0);
GLStateManager.glDeleteProgram(p);
GLSMPrograms.glDeleteProgram(p);
}
}
@@ -59,7 +59,7 @@ class ArrayUniformUploadGLTest {
final IntBuffer buf = BufferUtils.createIntBuffer(4);
buf.put(11).put(22).put(33).put(44).flip();
GLStateManager.glUniform1(GL20.glGetUniformLocation(p, "vals"), buf);
GLSMPrograms.glUniform1(GL20.glGetUniformLocation(p, "vals"), buf);
final IntBuffer read = BufferUtils.createIntBuffer(1);
final int[] expect = {11, 22, 33, 44};
@@ -72,7 +72,7 @@ class ArrayUniformUploadGLTest {
}
} finally {
GL20.glUseProgram(0);
GLStateManager.glDeleteProgram(p);
GLSMPrograms.glDeleteProgram(p);
}
}
}
@@ -21,7 +21,7 @@ class CompatUniformManagerTest {
void cleanup() {
if (program != 0) {
GL20.glUseProgram(0);
GLStateManager.glDeleteProgram(program);
GLSMPrograms.glDeleteProgram(program);
program = 0;
}
}
@@ -19,15 +19,15 @@ class DisplayListCompilationParityTest {
enum Caller {
GLSM {
void newList(int list, int mode) { GLStateManager.glNewList(list, mode); }
void endList() { GLStateManager.glEndList(); }
void callList(int list) { GLStateManager.glCallList(list); }
void enable(int cap) { GLStateManager.glEnable(cap); }
void translate(float x, float y, float z) { GLStateManager.glTranslatef(x, y, z); }
void pushMatrix() { GLStateManager.glPushMatrix(); }
void popMatrix() { GLStateManager.glPopMatrix(); }
void matrixMode(int mode) { GLStateManager.glMatrixMode(mode); }
void getFloat(int pname, FloatBuffer dst) { GLStateManager.glGetFloat(pname, dst); }
void newList(int list, int mode) { GLSMDraws.glNewList(list, mode); }
void endList() { GLSMDraws.glEndList(); }
void callList(int list) { GLSMDraws.glCallList(list); }
void enable(int cap) { GLSMEnable.glEnable(cap); }
void translate(float x, float y, float z) { GLSMMatrices.glTranslatef(x, y, z); }
void pushMatrix() { GLSMMatrices.glPushMatrix(); }
void popMatrix() { GLSMMatrices.glPopMatrix(); }
void matrixMode(int mode) { GLSMMatrices.glMatrixMode(mode); }
void getFloat(int pname, FloatBuffer dst) { GLSMQueries.glGetFloat(pname, dst); }
void flushMatrix() { DisplayListManager.flushMatrix(); }
},
RAW {
@@ -68,35 +68,35 @@ class DisplayListCompilationParityTest {
@BeforeEach
void setup() {
if (DisplayListManager.isRecording()) {
try { GLStateManager.glEndList(); } catch (Exception ignored) {}
try { GLSMDraws.glEndList(); } catch (Exception ignored) {}
}
GLStateManager.disableBlend();
GLStateManager.disableDepthTest();
GLStateManager.disableCull();
GLSMBlend.disableBlend();
GLSMDepthStencilAlpha.disableDepthTest();
GLSMRasterizer.disableCull();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_CULL_FACE);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
}
@AfterEach
void cleanup() {
if (DisplayListManager.isRecording()) {
try { GLStateManager.glEndList(); } catch (Exception ignored) {}
try { GLSMDraws.glEndList(); } catch (Exception ignored) {}
}
if (testList > 0) {
GLStateManager.glDeleteLists(testList, 1);
GLSMDraws.glDeleteLists(testList, 1);
testList = -1;
}
GLStateManager.disableBlend();
GLStateManager.disableDepthTest();
GLStateManager.disableCull();
GLSMBlend.disableBlend();
GLSMDepthStencilAlpha.disableDepthTest();
GLSMRasterizer.disableCull();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_CULL_FACE);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
}
@ParameterizedTest
@@ -21,73 +21,73 @@ class DisplayListCompilationTest {
@BeforeEach
void setup() {
if (DisplayListManager.isRecording()) {
try { GLStateManager.glEndList(); } catch (Exception ignored) {}
try { GLSMDraws.glEndList(); } catch (Exception ignored) {}
}
GLStateManager.disableBlend();
GLStateManager.disableDepthTest();
GLStateManager.disableCull();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLSMBlend.disableBlend();
GLSMDepthStencilAlpha.disableDepthTest();
GLSMRasterizer.disableCull();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
}
@AfterEach
void cleanup() {
if (DisplayListManager.isRecording()) {
try { GLStateManager.glEndList(); } catch (Exception ignored) {}
try { GLSMDraws.glEndList(); } catch (Exception ignored) {}
}
if (testList > 0) {
GLStateManager.glDeleteLists(testList, 1);
GLSMDraws.glDeleteLists(testList, 1);
testList = -1;
}
GLStateManager.disableBlend();
GLStateManager.disableDepthTest();
GLStateManager.disableCull();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLSMBlend.disableBlend();
GLSMDepthStencilAlpha.disableDepthTest();
GLSMRasterizer.disableCull();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
}
@Test
void glsm_compileAndExecute_matrixModeWithTransforms() {
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glLoadIdentity();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glLoadIdentity();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
testList = GL11.glGenLists(1);
GLStateManager.glNewList(testList, GL11.GL_COMPILE_AND_EXECUTE);
GLSMDraws.glNewList(testList, GL11.GL_COMPILE_AND_EXECUTE);
GLStateManager.glTranslatef(10, 0, 0);
GLStateManager.glRotatef(45, 0, 1, 0);
GLSMMatrices.glTranslatef(10, 0, 0);
GLSMMatrices.glRotatef(45, 0, 1, 0);
DisplayListManager.flushMatrix();
assertNotEquals(0.0f, matrix(GL11.GL_MODELVIEW_MATRIX).get(12), "After transforms: applied immediately");
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
assertEquals(0.0f, matrix(GL11.GL_PROJECTION_MATRIX).get(12), 0.001f, "PROJECTION still identity");
GLStateManager.glEndList();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLSMDraws.glEndList();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
}
@Test
void glsm_unsupportedOpInList_abortsCleanly() {
testList = GL11.glGenLists(1);
GLStateManager.glNewList(testList, GL11.GL_COMPILE);
GLSMDraws.glNewList(testList, GL11.GL_COMPILE);
assertTrue(DisplayListManager.isRecording(), "recording after glNewList");
assertThrows(UnsupportedOperationException.class, () -> GLStateManager.glReadBuffer(GL11.GL_FRONT));
assertThrows(UnsupportedOperationException.class, () -> GLSMFramebuffer.glReadBuffer(GL11.GL_FRONT));
assertFalse(DisplayListManager.isRecording(), "recording state must be reset after an in-list throw");
assertEquals(DisplayListManager.RecordMode.NONE, DisplayListManager.getRecordMode());
assertDoesNotThrow(() -> GLStateManager.glReadBuffer(GL11.GL_FRONT));
assertDoesNotThrow(GLStateManager::glEndList);
GLStateManager.glReadBuffer(GL11.GL_BACK);
assertDoesNotThrow(() -> GLSMFramebuffer.glReadBuffer(GL11.GL_FRONT));
assertDoesNotThrow(GLSMDraws::glEndList);
GLSMFramebuffer.glReadBuffer(GL11.GL_BACK);
}
@Test
void glsm_abortIfLeaked_recoversOpenList() {
testList = GL11.glGenLists(1);
GLStateManager.glNewList(testList, GL11.GL_COMPILE);
GLSMDraws.glNewList(testList, GL11.GL_COMPILE);
assertTrue(DisplayListManager.isRecording());
DisplayListManager.abortIfLeaked();
@@ -19,14 +19,14 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
for (int target : new int[] { GL11.GL_MODELVIEW, GL11.GL_PROJECTION, GL11.GL_TEXTURE }) {
resetMatrices();
int list = newList();
GLStateManager.glNewList(list, compileMode);
GLStateManager.glMatrixMode(target);
GLStateManager.glScalef(-2, 3, -4);
GLStateManager.glEndList();
GLSMDraws.glNewList(list, compileMode);
GLSMMatrices.glMatrixMode(target);
GLSMMatrices.glScalef(-2, 3, -4);
GLSMDraws.glEndList();
resetMatrices();
GLStateManager.glCallList(list);
GLSMDraws.glCallList(list);
FloatBuffer matrix = BufferUtils.createFloatBuffer(16);
GLStateManager.glGetFloat(switch (target) {
GLSMQueries.glGetFloat(switch (target) {
case GL11.GL_PROJECTION -> GL11.GL_PROJECTION_MATRIX;
case GL11.GL_TEXTURE -> GL11.GL_TEXTURE_MATRIX;
default -> GL11.GL_MODELVIEW_MATRIX;
@@ -42,15 +42,15 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
@AfterEach
void resetMatrices() {
for (int unit = 0; unit < 2; unit++) {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glLoadIdentity();
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glLoadIdentity();
}
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glLoadIdentity();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glLoadIdentity();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
}
private static float translation(int target) {
@@ -62,23 +62,23 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
for (int mask : new int[] { GL11.GL_TRANSFORM_BIT, GL11.GL_ALL_ATTRIB_BITS }) {
for (int compileMode : new int[] { GL11.GL_COMPILE, GL11.GL_COMPILE_AND_EXECUTE }) {
int list = newList();
GLStateManager.glNewList(list, compileMode);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glPushAttrib(mask);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLStateManager.glTranslatef(3, 0, 0);
GLStateManager.glPopAttrib();
GLStateManager.glLoadIdentity();
GLStateManager.glEndList();
GLSMDraws.glNewList(list, compileMode);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMAttribStack.glPushAttrib(mask);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
GLSMMatrices.glTranslatef(3, 0, 0);
GLSMAttribStack.glPopAttrib();
GLSMMatrices.glLoadIdentity();
GLSMDraws.glEndList();
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glLoadIdentity();
GLStateManager.glTranslatef(9, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLStateManager.glTranslatef(5, 0, 0);
GLStateManager.glCallList(list);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glLoadIdentity();
GLSMMatrices.glTranslatef(9, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
GLSMMatrices.glTranslatef(5, 0, 0);
GLSMDraws.glCallList(list);
assertEquals(3f, translation(GL11.GL_MODELVIEW_MATRIX));
assertEquals(0f, translation(GL11.GL_TEXTURE_MATRIX));
}
@@ -88,46 +88,46 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
@Test
void nestedAttributesRestoreInheritedCallerMode() {
int list = newList();
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.glPushAttrib(GL11.GL_TRANSFORM_BIT);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glPushAttrib(GL11.GL_ENABLE_BIT);
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glPopAttrib();
GLStateManager.glLoadIdentity();
GLStateManager.glPopAttrib();
GLStateManager.glLoadIdentity();
GLStateManager.glEndList();
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMAttribStack.glPushAttrib(GL11.GL_TRANSFORM_BIT);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMAttribStack.glPushAttrib(GL11.GL_ENABLE_BIT);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMAttribStack.glPopAttrib();
GLSMMatrices.glLoadIdentity();
GLSMAttribStack.glPopAttrib();
GLSMMatrices.glLoadIdentity();
GLSMDraws.glEndList();
GLStateManager.glTranslatef(5, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glTranslatef(7, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glTranslatef(9, 0, 0);
GLStateManager.glCallList(list);
GLSMMatrices.glTranslatef(5, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glTranslatef(7, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glTranslatef(9, 0, 0);
GLSMDraws.glCallList(list);
assertEquals(5f, translation(GL11.GL_MODELVIEW_MATRIX));
assertEquals(0f, translation(GL11.GL_PROJECTION_MATRIX));
assertEquals(0f, translation(GL11.GL_TEXTURE_MATRIX));
assertEquals(GL11.GL_TEXTURE, GLStateManager.glGetInteger(GL11.GL_MATRIX_MODE));
assertEquals(GL11.GL_TEXTURE, GLSMQueries.glGetInteger(GL11.GL_MATRIX_MODE));
}
@Test
void implicitMatrixCommandsAndEmptyListsInheritCallerTarget() {
int empty = newList();
GLStateManager.glNewList(empty, GL11.GL_COMPILE);
GLStateManager.glEndList();
GLSMDraws.glNewList(empty, GL11.GL_COMPILE);
GLSMDraws.glEndList();
int load = newList();
GLStateManager.glNewList(load, GL11.GL_COMPILE);
GLStateManager.glLoadIdentity();
GLStateManager.glEndList();
GLStateManager.glTranslatef(5, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glTranslatef(9, 0, 0);
GLStateManager.glCallList(empty);
assertEquals(GL11.GL_TEXTURE, GLStateManager.glGetInteger(GL11.GL_MATRIX_MODE));
GLSMDraws.glNewList(load, GL11.GL_COMPILE);
GLSMMatrices.glLoadIdentity();
GLSMDraws.glEndList();
GLSMMatrices.glTranslatef(5, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glTranslatef(9, 0, 0);
GLSMDraws.glCallList(empty);
assertEquals(GL11.GL_TEXTURE, GLSMQueries.glGetInteger(GL11.GL_MATRIX_MODE));
assertEquals(9f, translation(GL11.GL_TEXTURE_MATRIX));
GLStateManager.glCallList(load);
assertEquals(GL11.GL_TEXTURE, GLStateManager.glGetInteger(GL11.GL_MATRIX_MODE));
GLSMDraws.glCallList(load);
assertEquals(GL11.GL_TEXTURE, GLSMQueries.glGetInteger(GL11.GL_MATRIX_MODE));
assertEquals(0f, translation(GL11.GL_TEXTURE_MATRIX));
assertEquals(5f, translation(GL11.GL_MODELVIEW_MATRIX));
}
@@ -135,14 +135,14 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
@Test
void explicitInitialModelviewSurvivesReplayFromTexture() {
int list = newList();
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glLoadIdentity();
GLStateManager.glEndList();
GLStateManager.glTranslatef(5, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glTranslatef(9, 0, 0);
GLStateManager.glCallList(list);
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glLoadIdentity();
GLSMDraws.glEndList();
GLSMMatrices.glTranslatef(5, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glTranslatef(9, 0, 0);
GLSMDraws.glCallList(list);
assertEquals(0f, translation(GL11.GL_MODELVIEW_MATRIX));
assertEquals(9f, translation(GL11.GL_TEXTURE_MATRIX));
}
@@ -153,16 +153,16 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
for (int compileMode : new int[] { GL11.GL_COMPILE, GL11.GL_COMPILE_AND_EXECUTE }) {
resetMatrices();
int list = newList();
GLStateManager.glNewList(list, compileMode);
GLStateManager.glTranslatef(5, 0, 0);
GLStateManager.glMatrixMode(explicitTarget);
GLStateManager.glTranslatef(7, 0, 0);
GLStateManager.glEndList();
GLSMDraws.glNewList(list, compileMode);
GLSMMatrices.glTranslatef(5, 0, 0);
GLSMMatrices.glMatrixMode(explicitTarget);
GLSMMatrices.glTranslatef(7, 0, 0);
GLSMDraws.glEndList();
for (int callerTarget : new int[] { GL11.GL_MODELVIEW, GL11.GL_PROJECTION, GL11.GL_TEXTURE }) {
resetMatrices();
GLStateManager.glMatrixMode(callerTarget);
GLStateManager.glCallList(list);
GLSMMatrices.glMatrixMode(callerTarget);
GLSMDraws.glCallList(list);
String context = "compileMode=" + compileMode + ", callerTarget=" + callerTarget;
assertEquals((callerTarget == GL11.GL_MODELVIEW ? 5f : 0f) + (explicitTarget == GL11.GL_MODELVIEW ? 7f : 0f),
translation(GL11.GL_MODELVIEW_MATRIX), context);
@@ -180,27 +180,27 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
for (int compileMode : new int[] { GL11.GL_COMPILE, GL11.GL_COMPILE_AND_EXECUTE }) {
resetMatrices();
int list = newList();
GLStateManager.glNewList(list, compileMode);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glPushAttrib(mask);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE1);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glTranslatef(7, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glTranslatef(3, 0, 0);
GLStateManager.glPushAttrib(GL11.GL_ENABLE_BIT);
GLStateManager.glPopAttrib();
GLStateManager.glPopAttrib();
GLStateManager.glEndList();
GLSMDraws.glNewList(list, compileMode);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0);
GLSMAttribStack.glPushAttrib(mask);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE1);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glTranslatef(7, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glTranslatef(3, 0, 0);
GLSMAttribStack.glPushAttrib(GL11.GL_ENABLE_BIT);
GLSMAttribStack.glPopAttrib();
GLSMAttribStack.glPopAttrib();
GLSMDraws.glEndList();
resetMatrices();
GLStateManager.glCallList(list);
GLSMDraws.glCallList(list);
String context = "compileMode=" + compileMode;
assertEquals(GL13.GL_TEXTURE0, GLStateManager.glGetInteger(GL13.GL_ACTIVE_TEXTURE), context);
assertEquals(GL13.GL_TEXTURE0, GLSMQueries.glGetInteger(GL13.GL_ACTIVE_TEXTURE), context);
assertEquals(GL13.GL_TEXTURE0, GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE), context);
assertEquals(3f, translation(GL11.GL_MODELVIEW_MATRIX), context);
assertEquals(0f, translation(GL11.GL_TEXTURE_MATRIX), context);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE1);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE1);
assertEquals(7f, translation(GL11.GL_TEXTURE_MATRIX), context);
}
}
@@ -208,38 +208,38 @@ class DisplayListMatrixRestorationTest extends DisplayListTestFixture {
@Test
void pendingTextureTransformStaysOnOriginalUnit() {
int list = newList();
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glTranslatef(7, 0, 0);
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE1);
GLStateManager.glEndList();
GLStateManager.glCallList(list);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glTranslatef(7, 0, 0);
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE1);
GLSMDraws.glEndList();
GLSMDraws.glCallList(list);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE0);
assertEquals(7f, translation(GL11.GL_TEXTURE_MATRIX));
GLStateManager.glActiveTexture(GL13.GL_TEXTURE1);
GLSMTextures.glActiveTexture(GL13.GL_TEXTURE1);
assertEquals(0f, translation(GL11.GL_TEXTURE_MATRIX));
}
@Test
void explicitModeAfterNestedListIsNotDeduplicated() {
int child = newList();
GLStateManager.glNewList(child, GL11.GL_COMPILE);
GLStateManager.glMatrixMode(GL11.GL_PROJECTION);
GLStateManager.glLoadIdentity();
GLStateManager.glMatrixMode(GL11.GL_MODELVIEW);
GLStateManager.glTranslatef(5, 0, 0);
GLStateManager.glEndList();
GLSMDraws.glNewList(child, GL11.GL_COMPILE);
GLSMMatrices.glMatrixMode(GL11.GL_PROJECTION);
GLSMMatrices.glLoadIdentity();
GLSMMatrices.glMatrixMode(GL11.GL_MODELVIEW);
GLSMMatrices.glTranslatef(5, 0, 0);
GLSMDraws.glEndList();
int parent = newList();
GLStateManager.glNewList(parent, GL11.GL_COMPILE);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glLoadIdentity();
GLStateManager.glCallList(child);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glLoadIdentity();
GLStateManager.glEndList();
GLStateManager.glCallList(parent);
GLSMDraws.glNewList(parent, GL11.GL_COMPILE);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glLoadIdentity();
GLSMDraws.glCallList(child);
GLSMMatrices.glMatrixMode(GL11.GL_TEXTURE);
GLSMMatrices.glLoadIdentity();
GLSMDraws.glEndList();
GLSMDraws.glCallList(parent);
assertEquals(5f, translation(GL11.GL_MODELVIEW_MATRIX));
}
}
@@ -62,9 +62,9 @@ public final class DisplayListTestHelper {
public static CompiledDisplayList createDisplayList(Runnable runnable) {
int list = GL11.glGenLists(1);
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
runnable.run();
GLStateManager.glEndList();
GLSMDraws.glEndList();
CompiledDisplayList compiled = DisplayListManager.getDisplayList(list);
assertNotNull(compiled, "Display list should be compiled");
return compiled;
@@ -72,13 +72,13 @@ public final class DisplayListTestHelper {
/** Calls {@code list} on an identity modelview and returns the resulting matrix. The caller's matrix is restored. */
public static FloatBuffer modelviewAfterCall(int list) {
GLStateManager.glPushMatrix();
GLSMMatrices.glPushMatrix();
try {
GLStateManager.glLoadIdentity();
GLStateManager.glCallList(list);
GLSMMatrices.glLoadIdentity();
GLSMDraws.glCallList(list);
return GlTestSupport.modelview();
} finally {
GLStateManager.glPopMatrix();
GLSMMatrices.glPopMatrix();
}
}
@@ -96,12 +96,12 @@ public final class DisplayListTestHelper {
/** Immediate-mode quad from the origin to (size, size) at z = 0. */
public static void immediateQuad(float size) {
GLStateManager.glBegin(GL11.GL_QUADS);
GLStateManager.glVertex3f(0.0f, 0.0f, 0.0f);
GLStateManager.glVertex3f(size, 0.0f, 0.0f);
GLStateManager.glVertex3f(size, size, 0.0f);
GLStateManager.glVertex3f(0.0f, size, 0.0f);
GLStateManager.glEnd();
GLSMDraws.glBegin(GL11.GL_QUADS);
GLSMDraws.glVertex3f(0.0f, 0.0f, 0.0f);
GLSMDraws.glVertex3f(size, 0.0f, 0.0f);
GLSMDraws.glVertex3f(size, size, 0.0f);
GLSMDraws.glVertex3f(0.0f, size, 0.0f);
GLSMDraws.glEnd();
}
/** Textured quad written straight into the vanilla Tessellator's raw buffer and handed to the draw interceptor. */
@@ -120,28 +120,28 @@ class FeedbackManagerTest {
}
private static int feedbackDraw(int mode, float... verts) {
GLStateManager.getModelViewMatrix().identity();
GLStateManager.getProjectionMatrix().identity();
GLStateManager.getViewportState().setViewPort(0, 0, 800, 600);
GLStateManager.getViewportState().setDepthRange(0.0, 1.0);
GLSMMatrices.getModelViewMatrix().identity();
GLSMMatrices.getProjectionMatrix().identity();
GLSMRasterizer.getViewportState().setViewPort(0, 0, 800, 600);
GLSMRasterizer.getViewportState().setDepthRange(0.0, 1.0);
final int vao = GL30.glGenVertexArrays();
GLStateManager.glBindVertexArray(vao);
GLSMVertexInput.glBindVertexArray(vao);
final FloatBuffer vertBuf = BufferUtils.createFloatBuffer(verts.length);
vertBuf.put(verts).flip();
final int vbo = GL15.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertBuf, GL15.GL_STATIC_DRAW);
GLStateManager.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 12, 0);
GLStateManager.glEnableVertexAttribArray(0);
GLSMVertexInput.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 12, 0);
GLSMVertexInput.glEnableVertexAttribArray(0);
try {
FeedbackManager.processDrawArrays(mode, 0, verts.length / 3);
return FeedbackManager.glRenderMode(GL11.GL_RENDER);
} finally {
GLStateManager.glDisableVertexAttribArray(0);
GLStateManager.glBindVertexArray(0);
GLSMVertexInput.glDisableVertexAttribArray(0);
GLSMVertexInput.glBindVertexArray(0);
GL15.glDeleteBuffers(vbo);
GLStateManager.glDeleteVertexArrays(vao);
GLSMVertexInput.glDeleteVertexArrays(vao);
}
}
}
@@ -27,13 +27,13 @@ class GLSM_BlendFuncUnknownState_GLTest {
@AfterEach
void restoreDefaultBlendFunc() {
if (!RenderSystem.supportsBufferBlending()) return;
GLStateManager.tryBlendFuncSeparate(GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_ZERO);
GLStateManager.tryBlendFuncSeparate(GL11.GL_ONE, GL11.GL_ZERO, GL11.GL_ONE, GL11.GL_ZERO);
GLSMBlend.tryBlendFuncSeparate(GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_ZERO);
GLSMBlend.tryBlendFuncSeparate(GL11.GL_ONE, GL11.GL_ZERO, GL11.GL_ONE, GL11.GL_ZERO);
}
private static void seedVanillaSeparate() {
GLStateManager.tryBlendFuncSeparate(GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE);
GLStateManager.tryBlendFuncSeparate(VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
GLSMBlend.tryBlendFuncSeparate(GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE);
GLSMBlend.tryBlendFuncSeparate(VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
}
private static void overrideBufferZero() {
@@ -52,7 +52,7 @@ class GLSM_BlendFuncUnknownState_GLTest {
for (int buffer = 0; buffer < 2; buffer++) {
assertBufferBlend(buffer, VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
}
assertFalse(GLStateManager.getBlendState().isFuncUnknown(), "forward must clear the unknown flag");
assertFalse(GLSMBlend.getBlendState().isFuncUnknown(), "forward must clear the unknown flag");
}
@Test
@@ -60,34 +60,34 @@ class GLSM_BlendFuncUnknownState_GLTest {
seedVanillaSeparate();
overrideBufferZero();
GLStateManager.tryBlendFuncSeparate(VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
GLSMBlend.tryBlendFuncSeparate(VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
assertVanillaOnBothBuffers();
}
@Test
void glBlendFuncForwardsAfterIndexedOverride() {
GLStateManager.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
GLStateManager.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GLSMBlend.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
GLSMBlend.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
overrideBufferZero();
GLStateManager.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GLSMBlend.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
for (int buffer = 0; buffer < 2; buffer++) {
assertBufferBlend(buffer, GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
assertFalse(GLStateManager.getBlendState().isFuncUnknown(), "forward must clear the unknown flag");
assertFalse(GLSMBlend.getBlendState().isFuncUnknown(), "forward must clear the unknown flag");
}
@Test
void popAttribForwardsAfterIndexedOverride() {
seedVanillaSeparate();
GLStateManager.glPushAttrib(GL11.GL_COLOR_BUFFER_BIT);
GLSMAttribStack.glPushAttrib(GL11.GL_COLOR_BUFFER_BIT);
try {
overrideBufferZero();
} finally {
GLStateManager.glPopAttrib();
GLSMAttribStack.glPopAttrib();
}
assertVanillaOnBothBuffers();
@@ -95,20 +95,20 @@ class GLSM_BlendFuncUnknownState_GLTest {
@Test
void displayListReplayForwardsAfterIndexedOverride() {
final int list = GLStateManager.glGenLists(1);
final int list = GLSMDraws.glGenLists(1);
try {
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.tryBlendFuncSeparate(VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
GLStateManager.glEndList();
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMBlend.tryBlendFuncSeparate(VANILLA_SRC_RGB, VANILLA_DST_RGB, VANILLA_SRC_ALPHA, VANILLA_DST_ALPHA);
GLSMDraws.glEndList();
seedVanillaSeparate();
overrideBufferZero();
GLStateManager.glCallList(list);
GLSMDraws.glCallList(list);
assertVanillaOnBothBuffers();
} finally {
GLStateManager.glDeleteLists(list, 1);
GLSMDraws.glDeleteLists(list, 1);
}
}
}
@@ -33,20 +33,20 @@ class GLSM_BlendUnknownState_UnitTest {
@Test
void testSetUnknownStateForcesCacheBypass() {
// Enable blend via GLSM — both cache and GL should agree
GLStateManager.enableBlend();
GLSMBlend.enableBlend();
assertTrue(GL11.glIsEnabled(GL11.GL_BLEND), "GL blend should be enabled");
assertTrue(GLStateManager.getBlendMode().isEnabled(), "GLSM blend cache should be enabled");
assertTrue(GLSMBlend.getBlendMode().isEnabled(), "GLSM blend cache should be enabled");
// Simulate a per-buffer disable that bypasses the cache (as glDisablei does)
GL30.glDisablei(GL11.GL_BLEND, 0);
GLStateManager.getBlendMode().setUnknownState();
GLSMBlend.getBlendMode().setUnknownState();
// Cache still says enabled, but GL state for buffer 0 is now disabled
assertTrue(GLStateManager.getBlendMode().isEnabled(), "GLSM cache should still say enabled");
assertTrue(GLSMBlend.getBlendMode().isEnabled(), "GLSM cache should still say enabled");
// Re-enable blend via GLSM — without setUnknownState, this would be a no-op
// because the cache thinks blend is already enabled
GLStateManager.enableBlend();
GLSMBlend.enableBlend();
// Per GL spec, glEnable(GL_BLEND) enables blend for ALL draw buffers,
// overriding any per-buffer disables
@@ -72,9 +72,9 @@ class GLSM_BlendUnknownState_UnitTest {
private static void setBlend(boolean enabled) {
if (enabled) {
GLStateManager.enableBlend();
GLSMBlend.enableBlend();
} else {
GLStateManager.disableBlend();
GLSMBlend.disableBlend();
}
}
}
@@ -42,17 +42,17 @@ public class GLSM_ClientArrays_GLTest {
@BeforeEach
void bindFreshVertexArray() {
savedVao = GLStateManager.getBoundVAO();
vao = GLStateManager.glGenVertexArrays();
vbo = GLStateManager.glGenBuffers();
GLStateManager.glBindVertexArray(vao);
savedVao = GLSMVertexInput.getBoundVAO();
vao = GLSMVertexInput.glGenVertexArrays();
vbo = GLSMBuffers.glGenBuffers();
GLSMVertexInput.glBindVertexArray(vao);
}
@AfterEach
void deleteVertexArray() {
GLStateManager.glBindVertexArray(savedVao);
GLStateManager.glDeleteVertexArrays(vao);
GLStateManager.glDeleteBuffers(vbo);
GLSMVertexInput.glBindVertexArray(savedVao);
GLSMVertexInput.glDeleteVertexArrays(vao);
GLSMBuffers.glDeleteBuffers(vbo);
}
private static boolean attribHasSize3(Usage usage) {
@@ -76,10 +76,10 @@ public class GLSM_ClientArrays_GLTest {
}
private static void assertClientArray(String name, int sizePname, int size, int typePname, int type, int stridePname, int stride, int bindingPname, int binding) {
if (sizePname != 0) assertEquals(size, GLStateManager.glGetInteger(sizePname), name + " size");
if (typePname != 0) assertEquals(type, GLStateManager.glGetInteger(typePname), name + " type");
assertEquals(stride, GLStateManager.glGetInteger(stridePname), name + " stride");
assertEquals(binding, GLStateManager.glGetInteger(bindingPname), name + " buffer binding");
if (sizePname != 0) assertEquals(size, GLSMQueries.glGetInteger(sizePname), name + " size");
if (typePname != 0) assertEquals(type, GLSMQueries.glGetInteger(typePname), name + " type");
assertEquals(stride, GLSMQueries.glGetInteger(stridePname), name + " stride");
assertEquals(binding, GLSMQueries.glGetInteger(bindingPname), name + " buffer binding");
}
private static void assertVertexArray(String name, int size, int type, int stride, int binding) {
@@ -95,79 +95,79 @@ public class GLSM_ClientArrays_GLTest {
void vertexArrayStateRestoredOnlyWithVertexArrayBit() {
final int position = Usage.POSITION.getAttributeLocation();
try {
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
final int flagsBefore = GLStateManager.ctx().vaos.getVertexFlags();
assertFalse(positionArrayEnabled());
assertFalse(colorArrayEnabled());
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE1);
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE1);
assertTrue(positionArrayEnabled());
assertTrue(colorArrayEnabled());
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPopClientAttrib();
assertFalse(positionArrayEnabled(), "pop disables an array enabled inside the push");
assertEquals(GL11.GL_FALSE, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
assertFalse(colorArrayEnabled());
assertEquals(flagsBefore, GLStateManager.ctx().vaos.getVertexFlags());
assertEquals(0, GLStateManager.getClientActiveTextureUnit());
assertEquals(0, GLSMTextures.getClientActiveTextureUnit());
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glPopClientAttrib();
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMAttribStack.glPopClientAttrib();
assertTrue(positionArrayEnabled(), "pop re-enables an array disabled inside the push");
assertEquals(GL11.GL_TRUE, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_PIXEL_STORE_BIT);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE1);
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_PIXEL_STORE_BIT);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE1);
GLSMAttribStack.glPopClientAttrib();
assertTrue(positionArrayEnabled(), "a pixel-store push must not restore array enables");
assertTrue(colorArrayEnabled());
assertEquals(1, GLStateManager.getClientActiveTextureUnit());
assertEquals(1, GLSMTextures.getClientActiveTextureUnit());
} finally {
drainClientAttribStack();
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glDisableClientState(GL11.GL_COLOR_ARRAY);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glDisableClientState(GL11.GL_COLOR_ARRAY);
}
}
@Test
void clientActiveTextureRoundTrips() {
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
assertEquals(GLStateManager.MAX_TEXTURE_COORDS, GLStateManager.glGetInteger(GL20.GL_MAX_TEXTURE_COORDS));
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
assertEquals(GLStateManager.MAX_TEXTURE_COORDS, GLSMQueries.glGetInteger(GL20.GL_MAX_TEXTURE_COORDS));
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE1);
assertEquals(GL13.GL_TEXTURE1, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLStateManager.glClientActiveTexture(0);
assertEquals(GL13.GL_TEXTURE1, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0 + GLStateManager.MAX_TEXTURE_UNITS);
assertEquals(GL13.GL_TEXTURE1, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0 + GLStateManager.MAX_TEXTURE_COORDS);
assertEquals(GL13.GL_TEXTURE1, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE), "units past GL_MAX_TEXTURE_COORDS are rejected");
assertEquals(1, GLStateManager.getClientActiveTextureUnit());
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE1);
assertEquals(GL13.GL_TEXTURE1, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLSMTextures.glClientActiveTexture(0);
assertEquals(GL13.GL_TEXTURE1, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0 + GLStateManager.MAX_TEXTURE_UNITS);
assertEquals(GL13.GL_TEXTURE1, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0 + GLStateManager.MAX_TEXTURE_COORDS);
assertEquals(GL13.GL_TEXTURE1, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE), "units past GL_MAX_TEXTURE_COORDS are rejected");
assertEquals(1, GLSMTextures.getClientActiveTextureUnit());
GLStateManager.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0L);
GLSMVertexInput.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0L);
final VAOManager.Attrib attrib = GLStateManager.ctx().vaos.attrib(Usage.SECONDARY_UV.getAttributeLocation());
assertNotNull(attrib);
assertEquals(2, attrib.size);
assumeTrue(GLStateManager.MAX_TEXTURE_COORDS > 5);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE5);
assertEquals(GL13.GL_TEXTURE5, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLStateManager.glTexCoordPointer(3, GL11.GL_FLOAT, 0, 0L);
assertEquals(3, GLStateManager.glGetInteger(GL11.GL_TEXTURE_COORD_ARRAY_SIZE));
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE5);
assertEquals(GL13.GL_TEXTURE5, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
GLSMVertexInput.glTexCoordPointer(3, GL11.GL_FLOAT, 0, 0L);
assertEquals(3, GLSMQueries.glGetInteger(GL11.GL_TEXTURE_COORD_ARRAY_SIZE));
assertFalse(attribHasSize3(Usage.PRIMARY_UV));
assertFalse(attribHasSize3(Usage.SECONDARY_UV));
} finally {
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@@ -175,22 +175,22 @@ public class GLSM_ClientArrays_GLTest {
void conventionalPointerSurvivesGenericOverride() {
final int position = Usage.POSITION.getAttributeLocation();
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glVertexAttribPointer(position, 2, GL11.GL_FLOAT, false, 8, 4L);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glVertexAttribPointer(position, 2, GL11.GL_FLOAT, false, 8, 4L);
assertEquals(3, VAOManager.get(position).size, "disabled generic pointer must not displace an enabled conventional array");
assertEquals(3, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_SIZE));
GLStateManager.glEnableVertexAttribArray(position);
GLSMVertexInput.glEnableVertexAttribArray(position);
assertEquals(2, VAOManager.get(position).size, "enabled generic attribute wins");
assertTrue(VAOManager.get(position).genericPointer);
assertEquals(2, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_SIZE));
assertEquals(8, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_STRIDE));
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glDisableVertexAttribArray(position);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDisableVertexAttribArray(position);
assertEquals(3, VAOManager.get(position).size, "conventional pointer must come back when the generic attribute is disabled");
assertEquals(12, VAOManager.get(position).stride);
assertFalse(VAOManager.get(position).genericPointer);
@@ -198,12 +198,12 @@ public class GLSM_ClientArrays_GLTest {
assertEquals(12, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_STRIDE));
assertEquals(vbo, driverAttrib(position, GL15.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING));
assertEquals(GL11.GL_TRUE, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED), "conventional array stays enabled at draw level");
assertTrue(GLStateManager.glIsEnabled(GL11.GL_VERTEX_ARRAY));
assertEquals(0, GLStateManager.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING), "repoint must restore the array buffer binding");
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_VERTEX_ARRAY));
assertEquals(0, GLSMQueries.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING), "repoint must restore the array buffer binding");
} finally {
GLStateManager.glDisableVertexAttribArray(position);
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDisableVertexAttribArray(position);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@@ -211,55 +211,55 @@ public class GLSM_ClientArrays_GLTest {
void conventionalPointerSetUnderEnabledGenericAppliesOnceGenericIsDisabled() {
final int position = Usage.POSITION.getAttributeLocation();
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glVertexAttribPointer(position, 2, GL11.GL_FLOAT, false, 8, 0L);
GLStateManager.glEnableVertexAttribArray(position);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glVertexAttribPointer(position, 2, GL11.GL_FLOAT, false, 8, 0L);
GLSMVertexInput.glEnableVertexAttribArray(position);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
assertEquals(2, VAOManager.get(position).size);
assertEquals(2, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_SIZE));
GLStateManager.glDisableVertexAttribArray(position);
GLSMVertexInput.glDisableVertexAttribArray(position);
assertEquals(3, VAOManager.get(position).size);
assertEquals(3, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_SIZE));
assertEquals(GL11.GL_TRUE, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
assertEquals(GL11.GL_FALSE, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
assertFalse(positionArrayEnabled());
} finally {
GLStateManager.glDisableVertexAttribArray(position);
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDisableVertexAttribArray(position);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@Test
void drawVertexFlagsDoNotAnswerClientArrayEnables() {
try {
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
VAOManager.setCurrentVertexFlags(VertexFlags.COLOR_BIT | VertexFlags.NORMAL_BIT | VertexFlags.TEXTURE_BIT);
assertFalse(GLStateManager.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertFalse(GLStateManager.glIsEnabled(GL11.GL_NORMAL_ARRAY));
assertFalse(GLStateManager.glIsEnabled(GL11.GL_TEXTURE_COORD_ARRAY));
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_NORMAL_ARRAY));
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_TEXTURE_COORD_ARRAY));
GLStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_COLOR_ARRAY);
VAOManager.setCurrentVertexFlags(0);
assertTrue(GLStateManager.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_COLOR_ARRAY));
} finally {
GLStateManager.glDisableClientState(GL11.GL_COLOR_ARRAY);
GLSMVertexInput.glDisableClientState(GL11.GL_COLOR_ARRAY);
VAOManager.setCurrentVertexFlags(0);
}
}
@Test
void clientArrayPointerQueriesAreAnsweredFromCache() {
final int vaoB = GLStateManager.glGenVertexArrays();
final int vaoB = GLSMVertexInput.glGenVertexArrays();
final IntBuffer ints = BufferUtils.createIntBuffer(16);
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
assertVertexArray("default vertex", 4, GL11.GL_FLOAT, 0, 0);
assertClientArray("default normal", 0, 0, GL11.GL_NORMAL_ARRAY_TYPE, GL11.GL_FLOAT, GL11.GL_NORMAL_ARRAY_STRIDE, 0, GL15.GL_NORMAL_ARRAY_BUFFER_BINDING, 0);
@@ -271,15 +271,15 @@ public class GLSM_ClientArrays_GLTest {
assertClientArray("default index", 0, 0, GL11.GL_INDEX_ARRAY_TYPE, GL11.GL_FLOAT, GL11.GL_INDEX_ARRAY_STRIDE, 0, GL15.GL_INDEX_ARRAY_BUFFER_BINDING, 0);
assertClientArray("default edge flag", 0, 0, 0, 0, GL11.GL_EDGE_FLAG_ARRAY_STRIDE, 0, GL15.GL_EDGE_FLAG_ARRAY_BUFFER_BINDING, 0);
assertTexCoordArray("default texcoord", 4, GL11.GL_FLOAT, 0, 0);
assertNull(GLStateManager.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4));
assertNull(GLSMVertexInput.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4));
GLStateManager.glVertexPointer(3, GL11.GL_SHORT, 20, 8L);
GLStateManager.glNormalPointer(GL11.GL_BYTE, 16, 4L);
GLStateManager.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 16, 12L);
GLStateManager.glSecondaryColorPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glFogCoordPointer(GL11.GL_FLOAT, 4, 0L);
GLStateManager.glEdgeFlagPointer(7, 0L);
GLStateManager.glTexCoordPointer(2, GL11.GL_FLOAT, 8, 0L);
GLSMVertexInput.glVertexPointer(3, GL11.GL_SHORT, 20, 8L);
GLSMVertexInput.glNormalPointer(GL11.GL_BYTE, 16, 4L);
GLSMVertexInput.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 16, 12L);
GLSMVertexInput.glSecondaryColorPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glFogCoordPointer(GL11.GL_FLOAT, 4, 0L);
GLSMVertexInput.glEdgeFlagPointer(7, 0L);
GLSMVertexInput.glTexCoordPointer(2, GL11.GL_FLOAT, 8, 0L);
assertVertexArray("vertex", 3, GL11.GL_SHORT, 20, vbo);
assertClientArray("normal", 0, 0, GL11.GL_NORMAL_ARRAY_TYPE, GL11.GL_BYTE, GL11.GL_NORMAL_ARRAY_STRIDE, 16, GL15.GL_NORMAL_ARRAY_BUFFER_BINDING, vbo);
@@ -292,98 +292,98 @@ public class GLSM_ClientArrays_GLTest {
assertClientArray("edge flag", 0, 0, 0, 0, GL11.GL_EDGE_FLAG_ARRAY_STRIDE, 7, GL15.GL_EDGE_FLAG_ARRAY_BUFFER_BINDING, vbo);
assertTexCoordArray("texcoord unit 0", 2, GL11.GL_FLOAT, 8, vbo);
assertEquals(3.0f, GLStateManager.glGetFloat(GL11.GL_VERTEX_ARRAY_SIZE));
GLStateManager.glGetInteger(GL11.GL_VERTEX_ARRAY_STRIDE, ints);
assertEquals(3.0f, GLSMQueries.glGetFloat(GL11.GL_VERTEX_ARRAY_SIZE));
GLSMQueries.glGetInteger(GL11.GL_VERTEX_ARRAY_STRIDE, ints);
assertEquals(20, ints.get(0));
assertEquals(8L, MemoryUtilities.memAddress(GLStateManager.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4)));
assertEquals(12L, MemoryUtilities.memAddress(GLStateManager.glGetPointer(GL11.GL_COLOR_ARRAY_POINTER, 4)));
assertEquals(8L, MemoryUtilities.memAddress(GLSMVertexInput.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4)));
assertEquals(12L, MemoryUtilities.memAddress(GLSMVertexInput.glGetPointer(GL11.GL_COLOR_ARRAY_POINTER, 4)));
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0 + GLStateManager.MAX_TEXTURE_COORDS - 1);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0 + GLStateManager.MAX_TEXTURE_COORDS - 1);
assertTexCoordArray("unset texcoord unit", 4, GL11.GL_FLOAT, 0, 0);
GLStateManager.glTexCoordPointer(3, GL11.GL_SHORT, 6, 0L);
GLSMVertexInput.glTexCoordPointer(3, GL11.GL_SHORT, 6, 0L);
assertTexCoordArray("last texcoord unit", 3, GL11.GL_SHORT, 6, vbo);
assertFalse(attribHasSize3(Usage.PRIMARY_UV));
assertFalse(attribHasSize3(Usage.SECONDARY_UV));
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
assertTexCoordArray("texcoord unit 0 again", 2, GL11.GL_FLOAT, 8, vbo);
GLStateManager.glBindVertexArray(vaoB);
GLSMVertexInput.glBindVertexArray(vaoB);
assertVertexArray("other vao", 4, GL11.GL_FLOAT, 0, 0);
final FloatBuffer client = BufferUtils.createFloatBuffer(12);
GLStateManager.glVertexPointer(2, 0, client);
GLSMVertexInput.glVertexPointer(2, 0, client);
assertVertexArray("client pointer", 2, GL11.GL_FLOAT, 0, 0);
assertEquals(MemoryUtilities.memAddress(client), MemoryUtilities.memAddress(GLStateManager.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4)));
GLStateManager.glBindVertexArray(vao);
assertEquals(MemoryUtilities.memAddress(client), MemoryUtilities.memAddress(GLSMVertexInput.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4)));
GLSMVertexInput.glBindVertexArray(vao);
assertVertexArray("first vao again", 3, GL11.GL_SHORT, 20, vbo);
} finally {
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glDeleteVertexArrays(vaoB);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDeleteVertexArrays(vaoB);
}
}
@Test
void interleavedArraysSetClientStateWithoutAnActiveFfpProgram() {
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
assumeFalse(GLStateManager.ctx().ffp.isActive());
GLStateManager.glInterleavedArrays(GL11.GL_C4UB_V3F, 0, 0L);
assertTrue(GLStateManager.glIsEnabled(GL11.GL_VERTEX_ARRAY));
assertTrue(GLStateManager.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertFalse(GLStateManager.glIsEnabled(GL11.GL_NORMAL_ARRAY));
GLSMVertexInput.glInterleavedArrays(GL11.GL_C4UB_V3F, 0, 0L);
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_VERTEX_ARRAY));
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_NORMAL_ARRAY));
assertVertexArray("interleaved vertex", 3, GL11.GL_FLOAT, 16, vbo);
assertEquals(GL11.GL_UNSIGNED_BYTE, GLStateManager.glGetInteger(GL11.GL_COLOR_ARRAY_TYPE));
assertEquals(GL11.GL_UNSIGNED_BYTE, GLSMQueries.glGetInteger(GL11.GL_COLOR_ARRAY_TYPE));
} finally {
for (final int cap : CLIENT_ARRAY_CAPS) {
GLStateManager.glDisableClientState(cap);
GLSMVertexInput.glDisableClientState(cap);
}
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@Test
void clientVertexArrayBitRestoresPointersEnablesAndBindings() {
final int vaoB = GLStateManager.glGenVertexArrays();
final int vbo2 = GLStateManager.glGenBuffers();
final int ebo = GLStateManager.glGenBuffers();
final int vaoB = GLSMVertexInput.glGenVertexArrays();
final int vbo2 = GLSMBuffers.glGenBuffers();
final int ebo = GLSMBuffers.glGenBuffers();
final int position = Usage.POSITION.getAttributeLocation();
final int color = Usage.COLOR.getAttributeLocation();
final int normal = Usage.NORMAL.getAttributeLocation();
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 16, 12L);
GLStateManager.glFogCoordPointer(GL11.GL_FLOAT, 4, 0L);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 16, 12L);
GLSMVertexInput.glFogCoordPointer(GL11.GL_FLOAT, 4, 0L);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_COLOR_ARRAY);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo2);
GLStateManager.glVertexPointer(2, GL11.GL_SHORT, 4, 4L);
GLStateManager.glFogCoordPointer(GL11.GL_FLOAT, 8, 0L);
GLStateManager.glDisableClientState(GL11.GL_COLOR_ARRAY);
GLStateManager.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GLStateManager.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, 4, 0L);
GLStateManager.glEnableVertexAttribArray(5);
GLStateManager.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE1);
GLStateManager.glBindVertexArray(vaoB);
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo2);
GLSMVertexInput.glVertexPointer(2, GL11.GL_SHORT, 4, 4L);
GLSMVertexInput.glFogCoordPointer(GL11.GL_FLOAT, 8, 0L);
GLSMVertexInput.glDisableClientState(GL11.GL_COLOR_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GLSMVertexInput.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, 4, 0L);
GLSMVertexInput.glEnableVertexAttribArray(5);
GLSMBuffers.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE1);
GLSMVertexInput.glBindVertexArray(vaoB);
GLSMAttribStack.glPopClientAttrib();
assertEquals(vao, GLStateManager.getBoundVAO());
assertEquals(vbo, GLStateManager.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING));
assertEquals(ebo, GLStateManager.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING));
assertEquals(vao, GLSMVertexInput.getBoundVAO());
assertEquals(vbo, GLSMQueries.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING));
assertEquals(ebo, GLSMQueries.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING));
assertEquals(ebo, GL11.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING));
assertEquals(GL13.GL_TEXTURE0, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
assertEquals(GL13.GL_TEXTURE0, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
assertVertexArray("restored vertex", 3, GL11.GL_FLOAT, 12, vbo);
assertEquals(4, GLStateManager.glGetInteger(GL14.GL_FOG_COORDINATE_ARRAY_STRIDE));
assertEquals(vbo, GLStateManager.glGetInteger(GL15.GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING));
assertTrue(GLStateManager.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertFalse(GLStateManager.glIsEnabled(GL11.GL_NORMAL_ARRAY));
assertEquals(4, GLSMQueries.glGetInteger(GL14.GL_FOG_COORDINATE_ARRAY_STRIDE));
assertEquals(vbo, GLSMQueries.glGetInteger(GL15.GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING));
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_COLOR_ARRAY));
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_NORMAL_ARRAY));
assertTrue(colorArrayEnabled());
assertEquals(3, driverAttrib(position, GL20.GL_VERTEX_ATTRIB_ARRAY_SIZE));
@@ -395,24 +395,24 @@ public class GLSM_ClientArrays_GLTest {
assertEquals(GL11.GL_FALSE, driverAttrib(normal, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
assertEquals(GL11.GL_FALSE, driverAttrib(5, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
GLStateManager.glBindVertexArray(vaoB);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glBindVertexArray(vao);
GLStateManager.glDeleteVertexArrays(vaoB);
GLStateManager.glPopClientAttrib();
assertEquals(vao, GLStateManager.getBoundVAO(), "a deleted VAO must not be restored");
GLSMVertexInput.glBindVertexArray(vaoB);
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMVertexInput.glBindVertexArray(vao);
GLSMVertexInput.glDeleteVertexArrays(vaoB);
GLSMAttribStack.glPopClientAttrib();
assertEquals(vao, GLSMVertexInput.getBoundVAO(), "a deleted VAO must not be restored");
assertVertexArray("after dead-vao pop", 3, GL11.GL_FLOAT, 12, vbo);
} finally {
drainClientAttribStack();
GLStateManager.glBindVertexArray(vao);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMVertexInput.glBindVertexArray(vao);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
for (final int cap : CLIENT_ARRAY_CAPS) {
GLStateManager.glDisableClientState(cap);
GLSMVertexInput.glDisableClientState(cap);
}
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glDeleteVertexArrays(vaoB);
GLStateManager.glDeleteBuffers(vbo2);
GLStateManager.glDeleteBuffers(ebo);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDeleteVertexArrays(vaoB);
GLSMBuffers.glDeleteBuffers(vbo2);
GLSMBuffers.glDeleteBuffers(ebo);
}
}
@@ -420,150 +420,150 @@ public class GLSM_ClientArrays_GLTest {
void enabledGenericAttributeWinsWithoutAPointer() {
final int position = Usage.POSITION.getAttributeLocation();
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
assertFalse(VAOManager.get(position).genericPointer);
GLStateManager.glEnableVertexAttribArray(position);
GLSMVertexInput.glEnableVertexAttribArray(position);
assertTrue(VAOManager.get(position).genericPointer, "generic 0 supersedes position on its enable bit alone");
GLStateManager.glDisableVertexAttribArray(position);
GLSMVertexInput.glDisableVertexAttribArray(position);
assertFalse(VAOManager.get(position).genericPointer);
assertEquals(3, VAOManager.get(position).size);
} finally {
GLStateManager.glDisableVertexAttribArray(position);
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDisableVertexAttribArray(position);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@Test
void deletedBufferIsDetachedFromTheBoundVertexArray() {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 4L);
GLStateManager.glFogCoordPointer(GL11.GL_FLOAT, 4, 0L);
assertEquals(vbo, GLStateManager.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING));
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 4L);
GLSMVertexInput.glFogCoordPointer(GL11.GL_FLOAT, 4, 0L);
assertEquals(vbo, GLSMQueries.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING));
GLStateManager.glDeleteBuffers(vbo);
assertEquals(0, GLStateManager.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING));
assertEquals(0, GLStateManager.glGetInteger(GL15.GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING));
assertEquals(12, GLStateManager.glGetInteger(GL11.GL_VERTEX_ARRAY_STRIDE), "offset and stride survive the detach");
assertEquals(3, GLStateManager.glGetInteger(GL11.GL_VERTEX_ARRAY_SIZE));
GLSMBuffers.glDeleteBuffers(vbo);
assertEquals(0, GLSMQueries.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING));
assertEquals(0, GLSMQueries.glGetInteger(GL15.GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING));
assertEquals(12, GLSMQueries.glGetInteger(GL11.GL_VERTEX_ARRAY_STRIDE), "offset and stride survive the detach");
assertEquals(3, GLSMQueries.glGetInteger(GL11.GL_VERTEX_ARRAY_SIZE));
}
@Test
void shadowedPointerIsNotRepointedAtAReusedBufferName() {
final int other = GLStateManager.glGenVertexArrays();
final int conventional = GLStateManager.glGenBuffers();
final int generic = GLStateManager.glGenBuffers();
final int other = GLSMVertexInput.glGenVertexArrays();
final int conventional = GLSMBuffers.glGenBuffers();
final int generic = GLSMBuffers.glGenBuffers();
final int position = Usage.POSITION.getAttributeLocation();
int reused = 0;
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, conventional);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, generic);
GLStateManager.glVertexAttribPointer(position, 2, GL11.GL_FLOAT, false, 8, 0L);
GLStateManager.glEnableVertexAttribArray(position);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, conventional);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, generic);
GLSMVertexInput.glVertexAttribPointer(position, 2, GL11.GL_FLOAT, false, 8, 0L);
GLSMVertexInput.glEnableVertexAttribArray(position);
GLStateManager.glBindVertexArray(other);
GLStateManager.glDeleteBuffers(conventional);
reused = GLStateManager.glGenBuffers();
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, reused);
GLSMVertexInput.glBindVertexArray(other);
GLSMBuffers.glDeleteBuffers(conventional);
reused = GLSMBuffers.glGenBuffers();
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, reused);
assumeTrue(reused == conventional, "driver did not reuse the buffer name");
GLStateManager.glBindVertexArray(vao);
GLStateManager.glDisableVertexAttribArray(position);
GLSMVertexInput.glBindVertexArray(vao);
GLSMVertexInput.glDisableVertexAttribArray(position);
assertEquals(generic, driverAttrib(position, GL15.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING), "a pointer set before the delete must not attach to the new buffer");
} finally {
GLStateManager.glBindVertexArray(vao);
GLStateManager.glDisableVertexAttribArray(position);
GLStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glDeleteVertexArrays(other);
GLStateManager.glDeleteBuffers(generic);
if (reused != 0) GLStateManager.glDeleteBuffers(reused);
GLSMVertexInput.glBindVertexArray(vao);
GLSMVertexInput.glDisableVertexAttribArray(position);
GLSMVertexInput.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDeleteVertexArrays(other);
GLSMBuffers.glDeleteBuffers(generic);
if (reused != 0) GLSMBuffers.glDeleteBuffers(reused);
}
}
@Test
void popKeepsCurrentArraysWhenTheSavedArrayBufferWasDeleted() {
final int vbo2 = GLStateManager.glGenBuffers();
final int vbo2 = GLSMBuffers.glGenBuffers();
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo2);
GLStateManager.glVertexPointer(2, GL11.GL_SHORT, 4, 0L);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE1);
GLStateManager.glDeleteBuffers(vbo);
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo2);
GLSMVertexInput.glVertexPointer(2, GL11.GL_SHORT, 4, 0L);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE1);
GLSMBuffers.glDeleteBuffers(vbo);
GLSMAttribStack.glPopClientAttrib();
assertEquals(2, GLStateManager.glGetInteger(GL11.GL_VERTEX_ARRAY_SIZE), "array state is not restored once its array buffer is gone");
assertEquals(vbo2, GLStateManager.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING));
assertEquals(2, GLSMQueries.glGetInteger(GL11.GL_VERTEX_ARRAY_SIZE), "array state is not restored once its array buffer is gone");
assertEquals(vbo2, GLSMQueries.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING));
assertEquals(vbo2, GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING));
assertEquals(GL13.GL_TEXTURE0, GLStateManager.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
assertEquals(GL13.GL_TEXTURE0, GLSMQueries.glGetInteger(GL13.GL_CLIENT_ACTIVE_TEXTURE));
} finally {
drainClientAttribStack();
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLStateManager.glDeleteBuffers(vbo2);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glDeleteBuffers(vbo2);
}
}
@Test
void clientAttribStackIsNotCompiledIntoDisplayLists() {
final int other = GLStateManager.glGenVertexArrays();
final int list = GLStateManager.glGenLists(1);
final int other = GLSMVertexInput.glGenVertexArrays();
final int list = GLSMDraws.glGenLists(1);
try {
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glPopClientAttrib();
GLStateManager.glEndList();
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMAttribStack.glPopClientAttrib();
GLSMDraws.glEndList();
GLStateManager.glBindVertexArray(other);
GLStateManager.glCallList(list);
assertEquals(other, GLStateManager.getBoundVAO(), "replaying the list must not rebind the vertex array that was bound while compiling");
GLSMVertexInput.glBindVertexArray(other);
GLSMDraws.glCallList(list);
assertEquals(other, GLSMVertexInput.getBoundVAO(), "replaying the list must not rebind the vertex array that was bound while compiling");
assertEquals(other, GL11.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING), "driver vertex array unchanged by replay");
} finally {
drainClientAttribStack();
GLStateManager.glDeleteLists(list, 1);
GLStateManager.glDeleteVertexArrays(other);
GLSMDraws.glDeleteLists(list, 1);
GLSMVertexInput.glDeleteVertexArrays(other);
}
}
@Test
void popRestoresDivisorAndStateWithoutAnAttributeLocation() {
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, 4, 0L);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMVertexInput.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, 4, 0L);
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMAttribStack.glPopClientAttrib();
assertEquals(0, driverAttrib(5, GL33.GL_VERTEX_ATTRIB_ARRAY_DIVISOR));
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glVertexAttribDivisor(5, 3);
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMVertexInput.glVertexAttribDivisor(5, 3);
assertEquals(3, driverAttrib(5, GL33.GL_VERTEX_ATTRIB_ARRAY_DIVISOR));
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPopClientAttrib();
assertEquals(0, driverAttrib(5, GL33.GL_VERTEX_ATTRIB_ARRAY_DIVISOR));
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glEnableClientState(GL14.GL_FOG_COORDINATE_ARRAY);
GLStateManager.glPopClientAttrib();
assertFalse(GLStateManager.glIsEnabled(GL14.GL_FOG_COORDINATE_ARRAY));
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMVertexInput.glEnableClientState(GL14.GL_FOG_COORDINATE_ARRAY);
GLSMAttribStack.glPopClientAttrib();
assertFalse(GLSMEnable.glIsEnabled(GL14.GL_FOG_COORDINATE_ARRAY));
GLStateManager.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLStateManager.glEnableVertexAttribArray(5);
GLStateManager.glPopClientAttrib();
GLSMAttribStack.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);
GLSMVertexInput.glEnableVertexAttribArray(5);
GLSMAttribStack.glPopClientAttrib();
assertEquals(GL11.GL_FALSE, driverAttrib(5, GL20.GL_VERTEX_ATTRIB_ARRAY_ENABLED));
} finally {
drainClientAttribStack();
GLStateManager.glDisableVertexAttribArray(5);
GLStateManager.glDisableClientState(GL14.GL_FOG_COORDINATE_ARRAY);
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMVertexInput.glDisableVertexAttribArray(5);
GLSMVertexInput.glDisableClientState(GL14.GL_FOG_COORDINATE_ARRAY);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@@ -572,21 +572,21 @@ public class GLSM_ClientArrays_GLTest {
final FloatBuffer data = BufferUtils.createFloatBuffer(64);
final int position = Usage.POSITION.getAttributeLocation();
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
data.position(2);
GLStateManager.glInterleavedArrays(GL11.GL_C4UB_V3F, 0, data);
GLSMVertexInput.glInterleavedArrays(GL11.GL_C4UB_V3F, 0, data);
final long base = MemoryUtilities.memAddress(data);
assertNotNull(VAOManager.get(position).clientPointer);
assertEquals(base + 4, MemoryUtilities.memAddress(VAOManager.get(position).clientPointer));
assertEquals(base + 4, MemoryUtilities.memAddress(GLStateManager.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4)));
assertEquals(base, MemoryUtilities.memAddress(GLStateManager.glGetPointer(GL11.GL_COLOR_ARRAY_POINTER, 4)));
assertEquals(0, GLStateManager.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING));
assertEquals(16, GLStateManager.glGetInteger(GL11.GL_VERTEX_ARRAY_STRIDE));
assertEquals(base + 4, MemoryUtilities.memAddress(GLSMVertexInput.glGetPointer(GL11.GL_VERTEX_ARRAY_POINTER, 4)));
assertEquals(base, MemoryUtilities.memAddress(GLSMVertexInput.glGetPointer(GL11.GL_COLOR_ARRAY_POINTER, 4)));
assertEquals(0, GLSMQueries.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING));
assertEquals(16, GLSMQueries.glGetInteger(GL11.GL_VERTEX_ARRAY_STRIDE));
assertTrue(GLStateManager.ctx().vaos.hasAnyClientSideEnabledAttrib());
} finally {
for (final int cap : CLIENT_ARRAY_CAPS) {
GLStateManager.glDisableClientState(cap);
GLSMVertexInput.glDisableClientState(cap);
}
}
}
@@ -594,82 +594,82 @@ public class GLSM_ClientArrays_GLTest {
@Test
void enableAndDisableRouteClientArrayCapsToClientState() {
for (final int cap : CLIENT_ARRAY_CAPS) {
GLStateManager.glEnable(cap);
assertTrue(GLStateManager.glIsEnabled(cap), hex(cap));
GLStateManager.glDisable(cap);
assertFalse(GLStateManager.glIsEnabled(cap), hex(cap));
GLSMEnable.glEnable(cap);
assertTrue(GLSMEnable.glIsEnabled(cap), hex(cap));
GLSMEnable.glDisable(cap);
assertFalse(GLSMEnable.glIsEnabled(cap), hex(cap));
}
GLStateManager.glEnable(GL11.GL_VERTEX_ARRAY);
GLSMEnable.glEnable(GL11.GL_VERTEX_ARRAY);
assertTrue(positionArrayEnabled());
GLStateManager.glDisable(GL11.GL_VERTEX_ARRAY);
GLSMEnable.glDisable(GL11.GL_VERTEX_ARRAY);
}
@Test
void illegalPointerArgumentsAreIgnored() {
try {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLStateManager.glNormalPointer(GL11.GL_FLOAT, 12, 0L);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GLSMVertexInput.glVertexPointer(3, GL11.GL_FLOAT, 12, 0L);
GLSMVertexInput.glNormalPointer(GL11.GL_FLOAT, 12, 0L);
GLStateManager.glVertexPointer(1, GL11.GL_FLOAT, 4, 0L);
GLStateManager.glVertexPointer(3, GL11.GL_UNSIGNED_BYTE, 3, 0L);
GLStateManager.glNormalPointer(GL11.GL_UNSIGNED_BYTE, 3, 0L);
GLSMVertexInput.glVertexPointer(1, GL11.GL_FLOAT, 4, 0L);
GLSMVertexInput.glVertexPointer(3, GL11.GL_UNSIGNED_BYTE, 3, 0L);
GLSMVertexInput.glNormalPointer(GL11.GL_UNSIGNED_BYTE, 3, 0L);
assertVertexArray("vertex after illegal calls", 3, GL11.GL_FLOAT, 12, vbo);
assertEquals(GL11.GL_FLOAT, GLStateManager.glGetInteger(GL11.GL_NORMAL_ARRAY_TYPE));
assertEquals(GL11.GL_FLOAT, GLSMQueries.glGetInteger(GL11.GL_NORMAL_ARRAY_TYPE));
GLStateManager.glColorPointer(GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, 4, 0L);
assertEquals(GL12.GL_BGRA, GLStateManager.glGetInteger(GL11.GL_COLOR_ARRAY_SIZE));
GLStateManager.glColorPointer(GL12.GL_BGRA, GL11.GL_FLOAT, 16, 0L);
assertEquals(GL11.GL_UNSIGNED_BYTE, GLStateManager.glGetInteger(GL11.GL_COLOR_ARRAY_TYPE));
GLSMVertexInput.glColorPointer(GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, 4, 0L);
assertEquals(GL12.GL_BGRA, GLSMQueries.glGetInteger(GL11.GL_COLOR_ARRAY_SIZE));
GLSMVertexInput.glColorPointer(GL12.GL_BGRA, GL11.GL_FLOAT, 16, 0L);
assertEquals(GL11.GL_UNSIGNED_BYTE, GLSMQueries.glGetInteger(GL11.GL_COLOR_ARRAY_TYPE));
GLStateManager.glVertexAttribPointer(VAOManager.MAX_ATTRIBS, 3, GL11.GL_FLOAT, false, 0, 0L);
GLStateManager.glEnableVertexAttribArray(VAOManager.MAX_ATTRIBS);
GLStateManager.glDisableVertexAttribArray(VAOManager.MAX_ATTRIBS);
GLStateManager.glVertexAttribPointer(5, 5, GL11.GL_FLOAT, false, 0, 0L);
GLSMVertexInput.glVertexAttribPointer(VAOManager.MAX_ATTRIBS, 3, GL11.GL_FLOAT, false, 0, 0L);
GLSMVertexInput.glEnableVertexAttribArray(VAOManager.MAX_ATTRIBS);
GLSMVertexInput.glDisableVertexAttribArray(VAOManager.MAX_ATTRIBS);
GLSMVertexInput.glVertexAttribPointer(5, 5, GL11.GL_FLOAT, false, 0, 0L);
assertNull(VAOManager.get(5));
} finally {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GLSMBuffers.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
}
@Test
void clientArrayEnablesAreAnsweredFromCache() {
final int vaoB = GLStateManager.glGenVertexArrays();
final int vaoB = GLSMVertexInput.glGenVertexArrays();
try {
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
for (final int cap : CLIENT_ARRAY_CAPS) {
assertFalse(GLStateManager.glIsEnabled(cap), "default isEnabled " + hex(cap));
assertFalse(GLSMEnable.glIsEnabled(cap), "default isEnabled " + hex(cap));
assertEnableRoundTrip(cap, true);
}
GLStateManager.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE1);
assertFalse(GLStateManager.glIsEnabled(GL11.GL_TEXTURE_COORD_ARRAY), "texcoord array enable is per client texture unit");
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
assertTrue(GLStateManager.glIsEnabled(GL11.GL_TEXTURE_COORD_ARRAY));
GLStateManager.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE1);
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_TEXTURE_COORD_ARRAY), "texcoord array enable is per client texture unit");
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_TEXTURE_COORD_ARRAY));
GLSMVertexInput.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GLStateManager.glEnableClientState(GL11.GL_INDEX_ARRAY);
GLStateManager.glBindVertexArray(vaoB);
assertFalse(GLStateManager.glIsEnabled(GL11.GL_INDEX_ARRAY), "array enables are per vertex array object");
GLStateManager.glBindVertexArray(vao);
assertTrue(GLStateManager.glIsEnabled(GL11.GL_INDEX_ARRAY));
GLStateManager.glDisableClientState(GL11.GL_INDEX_ARRAY);
GLSMVertexInput.glEnableClientState(GL11.GL_INDEX_ARRAY);
GLSMVertexInput.glBindVertexArray(vaoB);
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_INDEX_ARRAY), "array enables are per vertex array object");
GLSMVertexInput.glBindVertexArray(vao);
assertTrue(GLSMEnable.glIsEnabled(GL11.GL_INDEX_ARRAY));
GLSMVertexInput.glDisableClientState(GL11.GL_INDEX_ARRAY);
GLStateManager.glBindVertexArray(vaoB);
GLStateManager.glEnableVertexAttribArray(0);
assertFalse(GLStateManager.glIsEnabled(GL11.GL_VERTEX_ARRAY), "an enabled generic attribute 0 is not GL_VERTEX_ARRAY");
GLStateManager.glDisableVertexAttribArray(0);
GLStateManager.glBindVertexArray(vao);
GLSMVertexInput.glBindVertexArray(vaoB);
GLSMVertexInput.glEnableVertexAttribArray(0);
assertFalse(GLSMEnable.glIsEnabled(GL11.GL_VERTEX_ARRAY), "an enabled generic attribute 0 is not GL_VERTEX_ARRAY");
GLSMVertexInput.glDisableVertexAttribArray(0);
GLSMVertexInput.glBindVertexArray(vao);
} finally {
GLStateManager.glBindVertexArray(vaoB);
GLStateManager.glDisableVertexAttribArray(0);
GLStateManager.glBindVertexArray(vao);
GLStateManager.glClientActiveTexture(GL13.GL_TEXTURE0);
GLSMVertexInput.glBindVertexArray(vaoB);
GLSMVertexInput.glDisableVertexAttribArray(0);
GLSMVertexInput.glBindVertexArray(vao);
GLSMTextures.glClientActiveTexture(GL13.GL_TEXTURE0);
for (final int cap : CLIENT_ARRAY_CAPS) {
GLStateManager.glDisableClientState(cap);
GLSMVertexInput.glDisableClientState(cap);
}
GLStateManager.glDeleteVertexArrays(vaoB);
GLSMVertexInput.glDeleteVertexArrays(vaoB);
}
}
}
@@ -52,7 +52,7 @@ public class GLSM_CoreRemovedCaps_GLTest {
private static void assertSecondaryColor(float red, float green, float blue) {
final FloatBuffer params = BufferUtils.createFloatBuffer(4);
GLStateManager.glGetFloat(GL14.GL_CURRENT_SECONDARY_COLOR, params);
GLSMQueries.glGetFloat(GL14.GL_CURRENT_SECONDARY_COLOR, params);
assertEquals(red, params.get(0), "red must round-trip through the cache");
assertEquals(green, params.get(1), "green must round-trip through the cache");
assertEquals(blue, params.get(2), "blue must round-trip through the cache");
@@ -67,15 +67,15 @@ public class GLSM_CoreRemovedCaps_GLTest {
@MethodSource("removedCaps")
void enableDisableIsCacheOnly(String name, int cap) {
try {
GLStateManager.glEnable(cap);
GLSMEnable.glEnable(cap);
assertNoGlError("glEnable(" + name + ")");
assertTrue(GLStateManager.glIsEnabled(cap), name + " must still round-trip through the cache");
assertTrue(GLSMEnable.glIsEnabled(cap), name + " must still round-trip through the cache");
GLStateManager.glDisable(cap);
GLSMEnable.glDisable(cap);
assertNoGlError("glDisable(" + name + ")");
assertFalse(GLStateManager.glIsEnabled(cap));
assertFalse(GLSMEnable.glIsEnabled(cap));
} finally {
GLStateManager.glDisable(cap);
GLSMEnable.glDisable(cap);
}
}
@@ -83,80 +83,80 @@ public class GLSM_CoreRemovedCaps_GLTest {
@MethodSource("removedCaps")
void pushPopAttribIsCacheOnly(String name, int cap) {
try {
GLStateManager.glPushAttrib(GL11.GL_ENABLE_BIT);
GLStateManager.glEnable(cap);
GLStateManager.glPopAttrib();
GLSMAttribStack.glPushAttrib(GL11.GL_ENABLE_BIT);
GLSMEnable.glEnable(cap);
GLSMAttribStack.glPopAttrib();
assertNoGlError("glPushAttrib/glEnable(" + name + ")/glPopAttrib");
assertFalse(GLStateManager.glIsEnabled(cap));
assertFalse(GLSMEnable.glIsEnabled(cap));
} finally {
GLStateManager.glDisable(cap);
GLSMEnable.glDisable(cap);
}
}
@Test
void secondaryColorIsRestoredByPopAttrib() {
try {
GLStateManager.glSecondaryColor3f(0.125F, 0.25F, 0.375F);
GLStateManager.glPushAttrib(GL11.GL_CURRENT_BIT);
GLStateManager.glSecondaryColor3f(1.0F, 1.0F, 1.0F);
GLStateManager.glPopAttrib();
GLSMCurrentAttribs.glSecondaryColor3f(0.125F, 0.25F, 0.375F);
GLSMAttribStack.glPushAttrib(GL11.GL_CURRENT_BIT);
GLSMCurrentAttribs.glSecondaryColor3f(1.0F, 1.0F, 1.0F);
GLSMAttribStack.glPopAttrib();
assertNoGlError("glPushAttrib/glSecondaryColor3f/glPopAttrib");
assertSecondaryColor(0.125F, 0.25F, 0.375F);
} finally {
GLStateManager.glSecondaryColor3f(0.0F, 0.0F, 0.0F);
GLSMCurrentAttribs.glSecondaryColor3f(0.0F, 0.0F, 0.0F);
}
}
@Test
void colorSumIsRestoredByFogBitPopAttrib() {
try {
GLStateManager.glPushAttrib(GL11.GL_FOG_BIT);
GLStateManager.glEnable(GL14.GL_COLOR_SUM);
GLStateManager.glPopAttrib();
GLSMAttribStack.glPushAttrib(GL11.GL_FOG_BIT);
GLSMEnable.glEnable(GL14.GL_COLOR_SUM);
GLSMAttribStack.glPopAttrib();
assertNoGlError("glPushAttrib(GL_FOG_BIT)/glEnable(GL_COLOR_SUM)/glPopAttrib");
assertFalse(GLStateManager.glIsEnabled(GL14.GL_COLOR_SUM));
assertFalse(GLSMEnable.glIsEnabled(GL14.GL_COLOR_SUM));
} finally {
GLStateManager.glDisable(GL14.GL_COLOR_SUM);
GLSMEnable.glDisable(GL14.GL_COLOR_SUM);
}
}
@Test
void secondaryColorReplaysFromDisplayList() {
final int list = GLStateManager.glGenLists(1);
final int list = GLSMDraws.glGenLists(1);
try {
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.glSecondaryColor3f(0.5F, 0.625F, 0.75F);
GLStateManager.glEndList();
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMCurrentAttribs.glSecondaryColor3f(0.5F, 0.625F, 0.75F);
GLSMDraws.glEndList();
assertNoGlError("glSecondaryColor3f display list compile");
GLStateManager.glSecondaryColor3f(0.0F, 0.0F, 0.0F);
GLStateManager.glCallList(list);
GLSMCurrentAttribs.glSecondaryColor3f(0.0F, 0.0F, 0.0F);
GLSMDraws.glCallList(list);
assertNoGlError("glSecondaryColor3f display list replay");
assertSecondaryColor(0.5F, 0.625F, 0.75F);
} finally {
GLStateManager.glDeleteLists(list, 1);
GLStateManager.glSecondaryColor3f(0.0F, 0.0F, 0.0F);
GLSMDraws.glDeleteLists(list, 1);
GLSMCurrentAttribs.glSecondaryColor3f(0.0F, 0.0F, 0.0F);
}
}
@Test
void displayListReplayIsCacheOnly() {
final int list = GLStateManager.glGenLists(1);
final int list = GLSMDraws.glGenLists(1);
try {
GLStateManager.glNewList(list, GL11.GL_COMPILE);
GLStateManager.glEnable(GL11.GL_LINE_STIPPLE);
GLStateManager.glLineStipple(2, (short) 0xF0F0);
GLStateManager.glDisable(GL11.GL_LINE_STIPPLE);
GLStateManager.glEndList();
GLSMDraws.glNewList(list, GL11.GL_COMPILE);
GLSMEnable.glEnable(GL11.GL_LINE_STIPPLE);
GLSMRasterizer.glLineStipple(2, (short) 0xF0F0);
GLSMEnable.glDisable(GL11.GL_LINE_STIPPLE);
GLSMDraws.glEndList();
assertNoGlError("display list compile");
GLStateManager.glCallList(list);
GLSMDraws.glCallList(list);
assertNoGlError("display list replay");
} finally {
GLStateManager.glDeleteLists(list, 1);
GLStateManager.glDisable(GL11.GL_LINE_STIPPLE);
GLSMDraws.glDeleteLists(list, 1);
GLSMEnable.glDisable(GL11.GL_LINE_STIPPLE);
}
}
}
Loaded 100 of 494 files, more files were not shown because too many files have changed in this diff. Show more