mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
Add DeltaTracker (partialTick) context to PassDefinitions (#10848)
This commit is contained in:
4 files changed
+73
-14
No files matched your search
@@ -7,10 +7,14 @@ 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.client.renderer.state.level.LevelRenderState;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,25 +31,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, LevelRenderState state) {
|
||||
public static void insertForgePasses(FrameGraphBuilder graphBuilder, LevelTargetBundle bundle, LevelRenderState state, DeltaTracker deltaTracker) {
|
||||
for (PassInfo info : addedPasses) {
|
||||
FramePass pass = graphBuilder.addPass(info.name);
|
||||
PassDefinition forgePass = info.pass;
|
||||
forgePass.extracts(bundle, pass);
|
||||
forgePass.extracts(bundle, pass, deltaTracker);
|
||||
pass.executes(() -> forgePass.executes(state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// ### 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 {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void extracts(LevelTargetBundle bundle, FramePass pass);
|
||||
|
||||
/**
|
||||
* Use to define what your pass does during the render stage.
|
||||
* @deprecated Prefer {@linkplain PassDefinition#extracts(LevelTargetBundle, FramePass, DeltaTracker)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since="26.2")
|
||||
default void extracts(LevelTargetBundle bundle, FramePass pass) {};
|
||||
|
||||
/**
|
||||
* This method exists to do render state extraction. Your instance of a PassDefinition should have
|
||||
* locals or some filled record instance that represents the render state created.
|
||||
* The resulting render state should be consumed by {@linkplain PassDefinition#executes(LevelRenderState)}
|
||||
* You must also use this to define which targets your pass will bind against. See PassDefinition javadocs for details.
|
||||
*/
|
||||
|
||||
default void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker deltaTracker) {
|
||||
extracts(bundle, pass);
|
||||
};
|
||||
|
||||
/**
|
||||
* Use to define what your pass does during the render stage. This should consume the render state created
|
||||
* during the extracts phase.
|
||||
*/
|
||||
void executes(LevelRenderState state);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user