Skip to content

Commit

Permalink
Implement scissors
Browse files Browse the repository at this point in the history
  • Loading branch information
SmylerMC committed Jul 21, 2024
1 parent 4428193 commit 68fc733
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import net.smyler.smylib.Color;
import net.smyler.smylib.Identifier;
import net.smyler.smylib.gui.gl.Blaze3dGlContext;
import net.smyler.smylib.gui.gl.Gl20Scissor;
import net.smyler.smylib.gui.gl.GlContext;
import net.smyler.smylib.gui.gl.Scissor;
import net.smyler.smylib.gui.gl.WrappedGuiGraphicsScissor;
import net.smyler.smylib.gui.sprites.Sprite;
import org.joml.Matrix4f;

Expand All @@ -25,7 +25,7 @@
public class WrappedGuiGraphics implements UiDrawContext {

public final GuiGraphics vanillaGraphics;
private final Scissor scissor = new WrappedGuiGraphicsScissor();
private final Scissor scissor = new Gl20Scissor();
private final GlContext glState = new Blaze3dGlContext();
private final TextureManager textureManager;
private int dynamicTextureLocationCounter = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package net.smyler.smylib.gui.gl;

import net.smyler.smylib.game.GameClient;
import org.lwjgl.opengl.GL20;

import java.util.LinkedList;
import java.util.List;

import static java.lang.Math.*;
import static net.smyler.smylib.SmyLib.getGameClient;

/**
* A wrapper around OpenGL 2.0's scissor feature.
* For now, it's easier to rely on this rather than rendering to different frame buffers.
*
* @author Smyler
*/
public class Gl20Scissor implements Scissor {

private boolean isScissorEnabled = GL20.glIsEnabled(GL20.GL_SCISSOR_TEST);
private float x, y, width, height; // This is in the Minecraft screen coordinate space

private final List<ScissorStackFrame> scissorPosStack = new LinkedList<>();

@Override
public void setEnabled(boolean yesNo) {
if(yesNo && !this.isScissorEnabled) {
GL20.glEnable(GL20.GL_SCISSOR_TEST);
} else if(!yesNo && this.isScissorEnabled) {
GL20.glDisable(GL20.GL_SCISSOR_TEST);
}
this.isScissorEnabled = yesNo;
}

@Override
public boolean isEnabled() {
return this.isScissorEnabled;
}

@Override
public void cropScreen(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
doScissor();
}

@Override
public void cropSection(float x, float y, float width, float height) {
float intersectX = max(x, this.x);
float intersectY = max(y, this.y);
float intersectWidth = min(width + x, this.width + this.x) - intersectX;
float intersectHeight = min(height + y, this.height + this.y) - intersectY;
this.cropScreen(intersectX, intersectY, intersectWidth, intersectHeight);
}

@Override
public void push() {
this.scissorPosStack.add(new ScissorStackFrame(isEnabled(), x, y, width, height));
}

@Override
public void pop() {
this.restore(this.scissorPosStack.removeLast());
this.doScissor();
}

private void doScissor() {
GameClient game = getGameClient();
float screenWidth = game.windowWidth();
float screenHeight = game.windowHeight();
double scale = game.scaleFactor();
float leftX = clamp(this.x, 0f, screenWidth);
float topY = clamp(screenHeight - this.y - this.height, 0f, screenHeight);
float rightX = clamp(this.x + this.width, 0f, screenWidth);
float bottomY = clamp(screenHeight - this.y, 0f, screenHeight);
float width = rightX - leftX;
float height = bottomY - topY;
GL20.glScissor((int) round(leftX * scale), (int) round(topY * scale), (int) round(width * scale), (int) round(height * scale));
}

private void restore(ScissorStackFrame frame) {
this.setEnabled(frame.enabled);
this.x = frame.x;
this.y = frame.y;
this.width = frame.width;
this.height = frame.height;
}

private record ScissorStackFrame(boolean enabled, float x, float y, float width, float height) {
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void render(GuiGraphics guiGraphics, int x, int y, float partialTicks) {

this.screen.onUpdate(mouseX, mouseY, null);
this.drawBackground(guiGraphics);
uiDrawContext.scissor().cropScreen(-1f, -1f, this.width + 1f, height + 1f);
super.render(guiGraphics, x, y, partialTicks);
this.screen.draw(uiDrawContext, 0, 0, mouseX, mouseY, true, true, null);
}
Expand Down

0 comments on commit 68fc733

Please sign in to comment.