Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a ConfigureMainRenderTargetEvent for enabling stenciling #1715

Open
wants to merge 11 commits into
base: 1.21.x
Choose a base branch
from
49 changes: 49 additions & 0 deletions patches/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--- a/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java
+++ b/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java
@@ -173,6 +_,11 @@
public T get() {
return this.resource;
}
+
+ @Override
+ public ResourceDescriptor<T> getDescriptor() {
+ return null;
+ }
}

@OnlyIn(Dist.CLIENT)
@@ -211,6 +_,10 @@
public String toString() {
return this.createdBy != null ? this.holder + "#" + this.version + " (from " + this.createdBy + ")" : this.holder + "#" + this.version;
}
+
+ public ResourceDescriptor<T> getDescriptor() {
+ return this.holder.getDescriptor();
+ }
}

@OnlyIn(Dist.CLIENT)
@@ -265,6 +_,11 @@
this.physicalResource = null;
}
}
+
+ @Override
+ public ResourceDescriptor<T> getDescriptor() {
+ return descriptor;
+ }
}

@OnlyIn(Dist.CLIENT)
@@ -363,6 +_,11 @@
@Override
public String toString() {
return this.name;
+ }
+
+ @Nullable
+ public ResourceDescriptor<T> getDescriptor() {
+ return null;
}
}
}
87 changes: 87 additions & 0 deletions patches/com/mojang/blaze3d/pipeline/MainTarget.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
--- a/com/mojang/blaze3d/pipeline/MainTarget.java
+++ b/com/mojang/blaze3d/pipeline/MainTarget.java
@@ -16,8 +_,12 @@
static final MainTarget.Dimension DEFAULT_DIMENSIONS = new MainTarget.Dimension(854, 480);

public MainTarget(int p_166137_, int p_166138_) {
- super(true);
- this.createFrameBuffer(p_166137_, p_166138_);
+ this(p_166137_, p_166138_, true, false);
+ }
+
+ public MainTarget(int width, int height, boolean useDepth, boolean useStencil) {
+ super(useDepth, useStencil);
+ this.createFrameBuffer(width, height);
}

private void createFrameBuffer(int p_166142_, int p_166143_) {
@@ -37,6 +_,10 @@
GlStateManager._texParameter(3553, 10242, 33071);
GlStateManager._texParameter(3553, 10243, 33071);
GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, this.depthBufferId, 0);
+ if (this.useStencil) {
+ GlStateManager._bindTexture(this.stencilBufferId);
+ GlStateManager._glFramebufferTexture2D(36160, org.lwjgl.opengl.GL32.GL_STENCIL_ATTACHMENT, 3553, this.stencilBufferId, 0);
+ }
GlStateManager._bindTexture(0);
this.viewWidth = maintarget$dimension.width;
this.viewHeight = maintarget$dimension.height;
@@ -50,7 +_,14 @@
RenderSystem.assertOnRenderThreadOrInit();
this.colorTextureId = TextureUtil.generateTextureId();
this.depthBufferId = TextureUtil.generateTextureId();
+ if (this.useStencil) {
+ this.stencilBufferId = this.depthBufferId;
+ }
MainTarget.AttachmentState maintarget$attachmentstate = MainTarget.AttachmentState.NONE;
+ MainTarget.AttachmentState targetState = MainTarget.AttachmentState.COLOR_DEPTH;
+ if (this.useStencil) {
+ targetState = targetState.with(MainTarget.AttachmentState.STENCIL);
+ }

for (MainTarget.Dimension maintarget$dimension : MainTarget.Dimension.listWithFallback(p_166147_, p_166148_)) {
maintarget$attachmentstate = MainTarget.AttachmentState.NONE;
@@ -58,11 +_,15 @@
maintarget$attachmentstate = maintarget$attachmentstate.with(MainTarget.AttachmentState.COLOR);
}

- if (this.allocateDepthAttachment(maintarget$dimension)) {
+ if (this.useStencil && this.allocateDepthStencilAttachment(maintarget$dimension)) {
+ maintarget$attachmentstate = maintarget$attachmentstate.with(MainTarget.AttachmentState.DEPTH_STENCIL);
+ }
+
+ else if (this.allocateDepthAttachment(maintarget$dimension)) {
maintarget$attachmentstate = maintarget$attachmentstate.with(MainTarget.AttachmentState.DEPTH);
}

- if (maintarget$attachmentstate == MainTarget.AttachmentState.COLOR_DEPTH) {
+ if (maintarget$attachmentstate == targetState) {
return maintarget$dimension;
}
}
@@ -86,12 +_,24 @@
return GlStateManager._getError() != 1285;
}

+ private boolean allocateDepthStencilAttachment(MainTarget.Dimension p_166145_) {
+ RenderSystem.assertOnRenderThreadOrInit();
+ GlStateManager._getError();
+ GlStateManager._bindTexture(this.depthBufferId);
+ GlStateManager._texImage2D(3553, 0, 6402, p_166145_.width, p_166145_.height, 0, org.lwjgl.opengl.GL32.GL_DEPTH_STENCIL, org.lwjgl.opengl.GL32.GL_UNSIGNED_INT_24_8, null);
+ return GlStateManager._getError() != 1285;
+ }
+
@OnlyIn(Dist.CLIENT)
static enum AttachmentState {
NONE,
COLOR,
DEPTH,
- COLOR_DEPTH;
+ COLOR_DEPTH,
+ STENCIL,
+ COLOR_STENCIL,
+ DEPTH_STENCIL,
+ COLOR_DEPTH_STENCIL;

private static final MainTarget.AttachmentState[] VALUES = values();

137 changes: 137 additions & 0 deletions patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
--- a/com/mojang/blaze3d/pipeline/RenderTarget.java
+++ b/com/mojang/blaze3d/pipeline/RenderTarget.java
@@ -25,17 +_,34 @@
public int viewWidth;
public int viewHeight;
public final boolean useDepth;
+ public final boolean useStencil;
public int frameBufferId;
protected int colorTextureId;
protected int depthBufferId;
+ protected int stencilBufferId;
private final float[] clearChannels = Util.make(() -> new float[]{1.0F, 1.0F, 1.0F, 0.0F});
public int filterMode;

+ // If this is true, we can use stencil texture formats rather than combined depth-stencil textures.
+ private final boolean stencilTextureSupported;
+
public RenderTarget(boolean p_166199_) {
- this.useDepth = p_166199_;
+ this(p_166199_, false);
+ }
+
+ public RenderTarget(boolean useDepth, boolean useStencil) {
+ this.useDepth = useDepth;
+ this.useStencil = useStencil;
this.frameBufferId = -1;
this.colorTextureId = -1;
this.depthBufferId = -1;
+
+ if (!useDepth && useStencil) {
+ var capabilities = org.lwjgl.opengl.GL.getCapabilities();
+ stencilTextureSupported = capabilities.GL_ARB_texture_stencil8 || capabilities.OpenGL44;
+ } else {
+ stencilTextureSupported = false;
+ }
}

public void resize(int p_83942_, int p_83943_) {
@@ -53,6 +_,11 @@
RenderSystem.assertOnRenderThreadOrInit();
this.unbindRead();
this.unbindWrite();
+ if (this.stencilBufferId > -1 && this.stencilBufferId != this.depthBufferId) {
+ TextureUtil.releaseTextureId(this.stencilBufferId);
+ this.stencilBufferId = -1;
+ }
+
if (this.depthBufferId > -1) {
TextureUtil.releaseTextureId(this.depthBufferId);
this.depthBufferId = -1;
@@ -96,9 +_,50 @@
GlStateManager._texParameter(3553, 34892, 0);
GlStateManager._texParameter(3553, 10242, 33071);
GlStateManager._texParameter(3553, 10243, 33071);
+ if (!this.useStencil) // If stenciling is enabled, we will fill this later
GlStateManager._texImage2D(3553, 0, 6402, this.width, this.height, 0, 6402, 5126, null);
}

+ if (this.useStencil) {
+ if (this.useDepth) {
+ // If depth and stencil buffers are both enabled, we must combine them
+ this.stencilBufferId = this.depthBufferId;
+ } else {
+ // Otherwise, we can generate a new texture in its place.
+ this.stencilBufferId = TextureUtil.generateTextureId();
+ GlStateManager._bindTexture(this.stencilBufferId);
+ GlStateManager._texParameter(3553, 10241, 9728);
+ GlStateManager._texParameter(3553, 10240, 9728);
+ GlStateManager._texParameter(3553, 34892, 0);
+ GlStateManager._texParameter(3553, 10242, 33071);
+ GlStateManager._texParameter(3553, 10243, 33071);
+ }
+
+ if (this.useDepth || !stencilTextureSupported) {
+ // Use a combined format for both depth and stencil.
+ GlStateManager._texImage2D(
+ org.lwjgl.opengl.GL32.GL_TEXTURE_2D,
+ 0,
+ org.lwjgl.opengl.GL32.GL_DEPTH24_STENCIL8,
+ this.width, this.height,
+ 0,
+ org.lwjgl.opengl.GL32.GL_DEPTH_STENCIL,
+ org.lwjgl.opengl.GL32.GL_UNSIGNED_INT_24_8,
+ null);
+ } else {
+ // Otherwise, we can use a separate format.
+ GlStateManager._texImage2D(
+ org.lwjgl.opengl.GL32.GL_TEXTURE_2D,
+ 0,
+ org.lwjgl.opengl.GL32.GL_STENCIL_INDEX8,
+ this.width, this.height,
+ 0,
+ org.lwjgl.opengl.GL32.GL_STENCIL_INDEX,
+ org.lwjgl.opengl.GL32.GL_BYTE,
+ null);
+ }
+ }
+
this.setFilterMode(9728, true);
GlStateManager._bindTexture(this.colorTextureId);
GlStateManager._texParameter(3553, 10242, 33071);
@@ -109,6 +_,14 @@
if (this.useDepth) {
GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, this.depthBufferId, 0);
}
+ if (this.useStencil) {
+ GlStateManager._glFramebufferTexture2D(
+ org.lwjgl.opengl.GL32.GL_FRAMEBUFFER,
+ org.lwjgl.opengl.GL32.GL_STENCIL_ATTACHMENT,
+ org.lwjgl.opengl.GL32.GL_TEXTURE_2D,
+ this.stencilBufferId,
+ 0);
+ }

this.checkStatus();
this.clear();
@@ -218,6 +_,10 @@
GlStateManager._clearDepth(1.0);
i |= 256;
}
+ if (this.useStencil) {
+ GlStateManager._clearStencil(0);
+ i |= org.lwjgl.opengl.GL32.GL_STENCIL_BUFFER_BIT;
+ }

GlStateManager._clear(i);
this.unbindWrite();
@@ -229,5 +_,9 @@

public int getDepthTextureId() {
return this.depthBufferId;
+ }
+
+ public int getStencilTextureId() {
+ return this.stencilBufferId;
}
}
14 changes: 14 additions & 0 deletions patches/com/mojang/blaze3d/pipeline/TextureTarget.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--- a/com/mojang/blaze3d/pipeline/TextureTarget.java
+++ b/com/mojang/blaze3d/pipeline/TextureTarget.java
@@ -7,7 +_,10 @@
@OnlyIn(Dist.CLIENT)
public class TextureTarget extends RenderTarget {
public TextureTarget(int p_166213_, int p_166214_, boolean p_166215_) {
- super(p_166215_);
+ this(p_166213_, p_166214_, p_166215_, false);
+ }
+ public TextureTarget(int p_166213_, int p_166214_, boolean p_166215_, boolean useStencil) {
+ super(p_166215_, useStencil);
RenderSystem.assertOnRenderThreadOrInit();
this.resize(p_166213_, p_166214_);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--- a/com/mojang/blaze3d/resource/RenderTargetDescriptor.java
+++ b/com/mojang/blaze3d/resource/RenderTargetDescriptor.java
@@ -6,9 +_,13 @@
import net.neoforged.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
-public record RenderTargetDescriptor(int width, int height, boolean useDepth) implements ResourceDescriptor<RenderTarget> {
+public record RenderTargetDescriptor(int width, int height, boolean useDepth, boolean useStencil) implements ResourceDescriptor<RenderTarget> {
+ public RenderTargetDescriptor(int width, int height, boolean useDepth) {
+ this(width, height, useDepth, false);
+ }
+
public RenderTarget allocate() {
- return new TextureTarget(this.width, this.height, this.useDepth);
+ return new TextureTarget(this.width, this.height, this.useDepth, this.useStencil);
}

public void free(RenderTarget p_363223_) {
11 changes: 7 additions & 4 deletions patches/net/minecraft/client/Minecraft.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
this.demo = p_91084_.game.demo;
this.allowsMultiplayer = !p_91084_.game.disableMultiplayer;
this.allowsChat = !p_91084_.game.disableChat;
@@ -483,15 +_,17 @@
@@ -483,15 +_,18 @@
LOGGER.error("Couldn't set icon", (Throwable)ioexception);
}

Expand All @@ -18,11 +18,13 @@
this.keyboardHandler = new KeyboardHandler(this);
- this.keyboardHandler.setup(this.window.getWindow());
RenderSystem.initRenderer(this.options.glDebugVerbosity, false);
this.mainRenderTarget = new MainTarget(this.window.getWidth(), this.window.getHeight());
- this.mainRenderTarget = new MainTarget(this.window.getWidth(), this.window.getHeight());
+ net.neoforged.neoforge.client.loading.ClientModLoader.begin(this);
+ this.mainRenderTarget = net.neoforged.neoforge.client.ClientHooks.createMainRenderTarget(this.window.getWidth(), this.window.getHeight());
this.mainRenderTarget.setClearColor(0.0F, 0.0F, 0.0F, 0.0F);
this.mainRenderTarget.clear();
this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
+ net.neoforged.neoforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager);
+ net.neoforged.neoforge.client.loading.ClientModLoader.finish(this.resourcePackRepository, this.resourceManager);
+ //Move client bootstrap to after mod loading so that events can be fired for it.
+ ClientBootstrap.bootstrap();
this.resourcePackRepository.reload();
Expand Down Expand Up @@ -177,14 +179,15 @@
this.deltaTracker.updatePauseState(this.pause);
this.deltaTracker.updateFrozenState(!this.isLevelRunningNormally());
long l = Util.getNanos();
@@ -1351,10 +_,12 @@
@@ -1351,10 +_,13 @@
this.window.setGuiScale((double)i);
if (this.screen != null) {
this.screen.resize(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
+ net.neoforged.neoforge.client.ClientHooks.resizeGuiLayers(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
}

RenderTarget rendertarget = this.getMainRenderTarget();
+ if (rendertarget != null)
rendertarget.resize(this.window.getWidth(), this.window.getHeight());
+ if (this.gameRenderer != null)
this.gameRenderer.resize(this.window.getWidth(), this.window.getHeight());
Expand Down
10 changes: 10 additions & 0 deletions patches/net/minecraft/client/renderer/LevelRenderer.java.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
--- a/net/minecraft/client/renderer/LevelRenderer.java
+++ b/net/minecraft/client/renderer/LevelRenderer.java
@@ -459,7 +_,8 @@
this.targets.main = framegraphbuilder.importExternal("main", this.minecraft.getMainRenderTarget());
int i = this.minecraft.getMainRenderTarget().width;
int j = this.minecraft.getMainRenderTarget().height;
- RenderTargetDescriptor rendertargetdescriptor = new RenderTargetDescriptor(i, j, true);
+ boolean useStencil = this.minecraft.getMainRenderTarget().useStencil;
+ RenderTargetDescriptor rendertargetdescriptor = new RenderTargetDescriptor(i, j, true, useStencil);
PostChain postchain = this.getTransparencyChain();
if (postchain != null) {
this.targets.translucent = framegraphbuilder.createInternal("translucent", rendertargetdescriptor);
@@ -473,6 +_,9 @@
this.targets.entityOutline = framegraphbuilder.importExternal("entity_outline", this.entityOutlineTarget);
}
Expand Down
Loading
Loading