mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 00:07:45 +00:00
This commit is contained in:
4 files changed
+72
-10
No files matched your search
@@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
this.addLateDebugPass(framegraphbuilder, vec3, p_407881_);
|
||||
+ net.minecraftforge.client.FramePassManager.insertForgePasses(framegraphbuilder, targets); // Forge: Modded passes are inserted here.
|
||||
+ net.minecraftforge.client.FramePassManager.insertForgePasses(framegraphbuilder, targets, p_342180_); // Forge: Modded passes are inserted here.
|
||||
profilerfiller.popPush("framegraph");
|
||||
framegraphbuilder.execute(p_367325_, new FrameGraphBuilder.Inspector() {
|
||||
@Override
|
||||
|
||||
@@ -7,9 +7,11 @@ package net.minecraftforge.client;
|
||||
|
||||
import com.mojang.blaze3d.framegraph.FrameGraphBuilder;
|
||||
import com.mojang.blaze3d.framegraph.FramePass;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.renderer.LevelTargetBundle;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -27,18 +29,75 @@ public class FramePassManager {
|
||||
|
||||
// Note: Pass order is determined automatically within FrameGraphBuilder. It's unclear what must be done to guarantee ordering.
|
||||
@ApiStatus.Internal
|
||||
public static void insertForgePasses(FrameGraphBuilder graphBuilder, LevelTargetBundle bundle) {
|
||||
public static void insertForgePasses(FrameGraphBuilder graphBuilder, LevelTargetBundle bundle, DeltaTracker tracker) {
|
||||
for (PassInfo info : addedPasses) {
|
||||
FramePass pass = graphBuilder.addPass(info.name);
|
||||
PassDefinition forgePass = info.pass;
|
||||
forgePass.targets(bundle, pass);
|
||||
forgePass.extracts(bundle, pass, tracker);
|
||||
pass.executes(forgePass::executes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// ### A PassDefinition must satisfy 3 things.
|
||||
///
|
||||
/// 1. The rendering order for the purpose of translucency sorting. Read further for specific details.
|
||||
/// 2. A render state definition supplier; "what" will be rendered.
|
||||
/// 3. A render state definition consumer; "how" it will be rendered.
|
||||
///
|
||||
///
|
||||
/// To satisfy #1, all FramePasses (and thus PassDefinitions) must bind against at least one target.
|
||||
/// The list of targets can be found in {@linkplain LevelTargetBundle}.
|
||||
/// HOWEVER!!! Only {@linkplain LevelTargetBundle#main} is used if the graphics mode is not set to Fabulous!
|
||||
/// So at minimum, all passes must guarantee a fallback binding to the main target, like the below.
|
||||
/// ```
|
||||
/// @Override
|
||||
/// void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker deltaTracker) {
|
||||
/// if (bundle.clouds != null) { // Perhaps we want to bind to clouds if Fabulous! is on.
|
||||
/// bundle.clouds = pass.readsAndWrites(bundle.clouds);
|
||||
/// }
|
||||
/// // An else clause could be used, but is not mandatory. It is fine to bind to more than one target.
|
||||
/// bundle.main = pass.readsAndWrites(bundle.main);
|
||||
/// }
|
||||
/// ```
|
||||
/// </pre>
|
||||
///
|
||||
/// It is up to the user to decide how their pass should bind to targets, but it must always bind to at least one.
|
||||
/// Failure to satisfy this requirement will result in {@linkplain FrameGraphBuilder#resolvePassOrder} exploding.
|
||||
/// Custom render targets are possible but not documented, see the implementation of {@linkplain LevelTargetBundle}
|
||||
/// if you want to take a crack at it.
|
||||
///
|
||||
/// Satisfying #2 is simple. Any state information you need to extract
|
||||
/// should be done during {@linkplain PassDefinition#extracts(LevelTargetBundle, FramePass, DeltaTracker)}.
|
||||
/// No actual rendering should be done at this time. This can happen before or after binding to a target.
|
||||
/// The specific implementation of your render state is up to you, it can even be done with some instance variables.
|
||||
///
|
||||
/// Satisfying #3 is also simple, this is the actual rendering that will consume the state created
|
||||
/// during the extracts phase.
|
||||
@NullMarked
|
||||
public interface PassDefinition {
|
||||
void targets(LevelTargetBundle bundle, FramePass pass);
|
||||
void executes();
|
||||
/**
|
||||
* Use to define which targets your pass will bind against, see {@link FramePass#reads} and {@link FramePass#readsAndWrites}
|
||||
* A FramePass must bind to at least ONE target. Otherwise, you get freaky issues with >1 modded passes.
|
||||
* Additionally, this method should be used for extracting render states into instance variables if desired.
|
||||
*/
|
||||
default void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker tracker) {
|
||||
targets(bundle, pass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Prefer {@link PassDefinition#extracts}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.21.10")
|
||||
default void targets(LevelTargetBundle bundle, FramePass pass) {}
|
||||
|
||||
/**
|
||||
* Use to define what your pass does during the render stage
|
||||
* @apiNote In 1.21.10+, LevelRenderState is used. Because that does not exist in 1.21.8, use the client level instead.
|
||||
* This method is informally deprecated due to rendering changes in versions 1.21.10+
|
||||
*/
|
||||
default void executes(){};
|
||||
}
|
||||
|
||||
private record PassInfo(String name, PassDefinition pass){}
|
||||
|
||||
@@ -13,7 +13,7 @@ import net.minecraftforge.eventbus.api.event.RecordEvent;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Fired after all vanilla frame passes are added into the pass list.
|
||||
* Fired during the construction of {@linkplain net.minecraft.client.renderer.LevelRenderer}.
|
||||
*
|
||||
* <p>This event is fired on the {@linkplain net.minecraftforge.common.MinecraftForge#EVENT_BUS main Forge event bus},
|
||||
* only on the {@linkplain net.minecraftforge.fml.LogicalSide#CLIENT logical client}.
|
||||
@@ -24,8 +24,9 @@ public record AddFramePassEvent() implements RecordEvent {
|
||||
/**
|
||||
* Adds a frame pass to pass list.
|
||||
* Create a new {@linkplain FramePassManager.PassDefinition} to handle render targets and render code.
|
||||
* See javadocs for details on what creating a PassDefinition entails.
|
||||
*
|
||||
* @param rl Resource location for frame pass name. Use RLs to avoid duplicate names.
|
||||
* @param rl Identifier for frame pass name. Use RLs to avoid duplicate names.
|
||||
* @param definition see usages of {@linkplain com.mojang.blaze3d.framegraph.FramePass} in {@linkplain net.minecraft.client.renderer.LevelRenderer}
|
||||
* @throws IllegalArgumentException If the name is a duplicate.
|
||||
*/
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
package net.minecraftforge.debug.client;
|
||||
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.renderer.LevelTargetBundle;
|
||||
import net.minecraftforge.client.FramePassManager;
|
||||
import net.minecraftforge.client.event.AddFramePassEvent;
|
||||
import net.minecraftforge.common.extensions.IForgeGameTestHelper;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.gametest.GameTest;
|
||||
@@ -21,6 +21,7 @@ import net.minecraft.client.renderer.ShapeRenderer;
|
||||
import net.minecraft.gametest.framework.GameTestHelper;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.framegraph.FramePass;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
|
||||
@GameTestNamespace("forge")
|
||||
@@ -47,11 +48,12 @@ public class RenderFrameLayerTest extends BaseTestMod {
|
||||
/**
|
||||
* If this is working, two white line box cubes will be rendered at ground level in a superflat world around (0,0)
|
||||
*/
|
||||
@NullMarked
|
||||
public static void renderTest(AddFramePassEvent event) {
|
||||
var mainCamera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||
FramePassManager.PassDefinition def = new FramePassManager.PassDefinition() {
|
||||
@Override
|
||||
public void targets(LevelTargetBundle bundle, FramePass pass) {
|
||||
public void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker deltaTracker) {
|
||||
bundle.main = pass.readsAndWrites(bundle.main);
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ public class RenderFrameLayerTest extends BaseTestMod {
|
||||
event.addPass(rl(MODID), def);
|
||||
FramePassManager.PassDefinition def2 = new FramePassManager.PassDefinition() {
|
||||
@Override
|
||||
public void targets(LevelTargetBundle bundle, FramePass pass) {
|
||||
public void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker deltaTracker) {
|
||||
bundle.main = pass.readsAndWrites(bundle.main);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user