|
|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2024 jMonkeyEngine
|
|
|
+ * Copyright (c) 2025 jMonkeyEngine
|
|
|
* All rights reserved.
|
|
|
*
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
@@ -77,37 +77,30 @@ import java.util.function.Supplier;
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
/**
|
|
|
- * A high-level rendering interface that is
|
|
|
- * above the Renderer implementation. RenderManager takes care
|
|
|
- * of rendering the scene graphs attached to each viewport and
|
|
|
- * handling SceneProcessors.
|
|
|
- *
|
|
|
- * @see SceneProcessor
|
|
|
- * @see ViewPort
|
|
|
- * @see Spatial
|
|
|
+ * The `RenderManager` is a high-level rendering interface that manages
|
|
|
+ * {@link ViewPort}s, {@link SceneProcessor}s, and the overall rendering pipeline.
|
|
|
+ * It is responsible for orchestrating the rendering of scenes into various
|
|
|
+ * viewports.
|
|
|
*/
|
|
|
public class RenderManager {
|
|
|
|
|
|
private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
|
|
|
+
|
|
|
private final Renderer renderer;
|
|
|
private final UniformBindingManager uniformBindingManager = new UniformBindingManager();
|
|
|
private final ArrayList<ViewPort> preViewPorts = new ArrayList<>();
|
|
|
private final ArrayList<ViewPort> viewPorts = new ArrayList<>();
|
|
|
private final ArrayList<ViewPort> postViewPorts = new ArrayList<>();
|
|
|
- private final HashMap<Class, PipelineContext> contexts = new HashMap<>();
|
|
|
- private final ArrayList<PipelineContext> usedContexts = new ArrayList<>();
|
|
|
- private final ArrayList<RenderPipeline> usedPipelines = new ArrayList<>();
|
|
|
- private RenderPipeline defaultPipeline = new ForwardPipeline();
|
|
|
+ private final HashMap<Class<? extends PipelineContext>, PipelineContext> contexts = new HashMap<>();
|
|
|
+ private final LinkedList<PipelineContext> usedContexts = new LinkedList<>();
|
|
|
+ private final LinkedList<RenderPipeline<? extends PipelineContext>> usedPipelines = new LinkedList<>();
|
|
|
+ private RenderPipeline<? extends PipelineContext> defaultPipeline = new ForwardPipeline();
|
|
|
private Camera prevCam = null;
|
|
|
private Material forcedMaterial = null;
|
|
|
private String forcedTechnique = null;
|
|
|
private RenderState forcedRenderState = null;
|
|
|
- private final SafeArrayList<MatParamOverride> forcedOverrides
|
|
|
- = new SafeArrayList<>(MatParamOverride.class);
|
|
|
- private int viewX;
|
|
|
- private int viewY;
|
|
|
- private int viewWidth;
|
|
|
- private int viewHeight;
|
|
|
+ private final SafeArrayList<MatParamOverride> forcedOverrides = new SafeArrayList<>(MatParamOverride.class);
|
|
|
+
|
|
|
private final Matrix4f orthoMatrix = new Matrix4f();
|
|
|
private final LightList filteredLightList = new LightList(null);
|
|
|
private boolean handleTranslucentBucket = true;
|
|
|
@@ -115,7 +108,7 @@ public class RenderManager {
|
|
|
private LightFilter lightFilter = new DefaultLightFilter();
|
|
|
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
|
|
private int singlePassLightBatchSize = 1;
|
|
|
- private MatParamOverride boundDrawBufferId=new MatParamOverride(VarType.Int, "BoundDrawBuffer", 0);
|
|
|
+ private final MatParamOverride boundDrawBufferId = new MatParamOverride(VarType.Int, "BoundDrawBuffer", 0);
|
|
|
private Predicate<Geometry> renderFilter;
|
|
|
|
|
|
|
|
|
@@ -123,7 +116,7 @@ public class RenderManager {
|
|
|
* Creates a high-level rendering interface over the
|
|
|
* low-level rendering interface.
|
|
|
*
|
|
|
- * @param renderer (alias created)
|
|
|
+ * @param renderer The low-level renderer implementation.
|
|
|
*/
|
|
|
public RenderManager(Renderer renderer) {
|
|
|
this.renderer = renderer;
|
|
|
@@ -131,59 +124,61 @@ public class RenderManager {
|
|
|
// register default pipeline context
|
|
|
contexts.put(PipelineContext.class, new DefaultPipelineContext());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Gets the default pipeline used when a ViewPort does not have a
|
|
|
* pipeline already assigned to it.
|
|
|
- *
|
|
|
- * @return
|
|
|
+ *
|
|
|
+ * @return The default {@link RenderPipeline}, which is {@link ForwardPipeline} by default.
|
|
|
*/
|
|
|
- public RenderPipeline getPipeline() {
|
|
|
+ public RenderPipeline<? extends PipelineContext> getPipeline() {
|
|
|
return defaultPipeline;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Sets the default pipeline used when a ViewPort does not have a
|
|
|
* pipeline already assigned to it.
|
|
|
* <p>
|
|
|
* default={@link ForwardPipeline}
|
|
|
- *
|
|
|
- * @param pipeline default pipeline (not null)
|
|
|
+ *
|
|
|
+ * @param pipeline The default rendering pipeline (not null).
|
|
|
*/
|
|
|
- public void setPipeline(RenderPipeline pipeline) {
|
|
|
+ public void setPipeline(RenderPipeline<? extends PipelineContext> pipeline) {
|
|
|
assert pipeline != null;
|
|
|
this.defaultPipeline = pipeline;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Gets the default pipeline context registered under
|
|
|
- * {@link PipelineContext#getClass()}.
|
|
|
- *
|
|
|
- * @return
|
|
|
+ * {@link PipelineContext}.
|
|
|
+ *
|
|
|
+ * @return The default {@link PipelineContext}.
|
|
|
*/
|
|
|
public PipelineContext getDefaultContext() {
|
|
|
return getContext(PipelineContext.class);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Gets the pipeline context registered under the class.
|
|
|
- *
|
|
|
- * @param <T>
|
|
|
- * @param type
|
|
|
- * @return registered context or null
|
|
|
+ * Gets the pipeline context registered under the given class type.
|
|
|
+ *
|
|
|
+ * @param type The class type of the context to retrieve.
|
|
|
+ * @param <T> The type of the {@link PipelineContext}.
|
|
|
+ * @return The registered context instance, or null if not found.
|
|
|
*/
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
public <T extends PipelineContext> T getContext(Class<T> type) {
|
|
|
- return (T)contexts.get(type);
|
|
|
+ return (T) contexts.get(type);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Gets the pipeline context registered under the class or creates
|
|
|
* and registers a new context from the supplier.
|
|
|
- *
|
|
|
- * @param <T>
|
|
|
- * @param type
|
|
|
- * @param supplier interface for creating a new context if necessary
|
|
|
- * @return registered or newly created context
|
|
|
+ *
|
|
|
+ * @param <T> The type of the {@link PipelineContext}.
|
|
|
+ * @param type The class type under which the context is registered.
|
|
|
+ * @param supplier A function interface for creating a new context
|
|
|
+ * if one is not already registered under the given type.
|
|
|
+ * @return The registered or newly created context.
|
|
|
*/
|
|
|
public <T extends PipelineContext> T getOrCreateContext(Class<T> type, Supplier<T> supplier) {
|
|
|
T c = getContext(type);
|
|
|
@@ -193,15 +188,16 @@ public class RenderManager {
|
|
|
}
|
|
|
return c;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Gets the pipeline context registered under the class or creates
|
|
|
* and registers a new context from the function.
|
|
|
- *
|
|
|
- * @param <T>
|
|
|
- * @param type
|
|
|
- * @param function interface for creating a new context if necessary
|
|
|
- * @return registered or newly created context
|
|
|
+ *
|
|
|
+ * @param <T> The type of the {@link PipelineContext}.
|
|
|
+ * @param type The class type under which the context is registered.
|
|
|
+ * @param function A function interface for creating a new context, taking the {@code RenderManager} as an argument,
|
|
|
+ * if one is not already registered under the given type.
|
|
|
+ * @return The registered or newly created context.
|
|
|
*/
|
|
|
public <T extends PipelineContext> T getOrCreateContext(Class<T> type, Function<RenderManager, T> function) {
|
|
|
T c = getContext(type);
|
|
|
@@ -211,16 +207,16 @@ public class RenderManager {
|
|
|
}
|
|
|
return c;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Registers the pipeline context under the class.
|
|
|
+ * Registers a pipeline context under the given class type.
|
|
|
* <p>
|
|
|
* If another context is already registered under the class, that
|
|
|
* context will be replaced by the given context.
|
|
|
- *
|
|
|
- * @param <T>
|
|
|
- * @param type class type to register the context under (not null)
|
|
|
- * @param context context to register (not null)
|
|
|
+ *
|
|
|
+ * @param type The class type under which the context is registered.
|
|
|
+ * @param context The context instance to register.
|
|
|
+ * @param <T> The type of the {@link PipelineContext}.
|
|
|
*/
|
|
|
public <T extends PipelineContext> void registerContext(Class<T> type, T context) {
|
|
|
assert type != null;
|
|
|
@@ -229,11 +225,11 @@ public class RenderManager {
|
|
|
}
|
|
|
contexts.put(type, context);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Gets the application profiler.
|
|
|
- *
|
|
|
- * @return
|
|
|
+ *
|
|
|
+ * @return The {@link AppProfiler} instance, or null if none is set.
|
|
|
*/
|
|
|
public AppProfiler getProfiler() {
|
|
|
return prof;
|
|
|
@@ -522,7 +518,7 @@ public class RenderManager {
|
|
|
for (ViewPort vp : preViewPorts) {
|
|
|
notifyRescale(vp, x, y);
|
|
|
}
|
|
|
- for (ViewPort vp : viewPorts) {
|
|
|
+ for (ViewPort vp : viewPorts) {
|
|
|
notifyRescale(vp, x, y);
|
|
|
}
|
|
|
for (ViewPort vp : postViewPorts) {
|
|
|
@@ -531,22 +527,19 @@ public class RenderManager {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Sets the material to use to render all future objects.
|
|
|
- * This overrides the material set on the geometry and renders
|
|
|
- * with the provided material instead.
|
|
|
- * Use null to clear the material and return renderer to normal
|
|
|
- * functionality.
|
|
|
+ * Sets a material that will be forced on all rendered geometries.
|
|
|
+ * This can be used for debugging (e.g., solid color) or special effects.
|
|
|
*
|
|
|
- * @param mat The forced material to set, or null to return to normal
|
|
|
+ * @param forcedMaterial The material to force, or null to disable forcing.
|
|
|
*/
|
|
|
- public void setForcedMaterial(Material mat) {
|
|
|
- forcedMaterial = mat;
|
|
|
+ public void setForcedMaterial(Material forcedMaterial) {
|
|
|
+ this.forcedMaterial = forcedMaterial;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Gets the forced material.
|
|
|
- *
|
|
|
- * @return
|
|
|
+ * Gets the forced material that overrides materials set on geometries.
|
|
|
+ *
|
|
|
+ * @return The forced {@link Material}, or null if no material is forced.
|
|
|
*/
|
|
|
public Material getForcedMaterial() {
|
|
|
return forcedMaterial;
|
|
|
@@ -597,10 +590,9 @@ public class RenderManager {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns the forced technique name set.
|
|
|
- *
|
|
|
- * @return the forced technique name set.
|
|
|
+ * Returns the name of the forced technique.
|
|
|
*
|
|
|
+ * @return The name of the forced technique, or null if none is forced.
|
|
|
* @see #setForcedTechnique(java.lang.String)
|
|
|
*/
|
|
|
public String getForcedTechnique() {
|
|
|
@@ -616,9 +608,7 @@ public class RenderManager {
|
|
|
* If a forced material is not set and the forced technique name cannot
|
|
|
* be found on the material, the geometry will <em>not</em> be rendered.
|
|
|
*
|
|
|
- * @param forcedTechnique The forced technique name to use, set to null
|
|
|
- * to return to normal functionality.
|
|
|
- *
|
|
|
+ * @param forcedTechnique The technique to force, or null to disable forcing.
|
|
|
* @see #renderGeometry(com.jme3.scene.Geometry)
|
|
|
*/
|
|
|
public void setForcedTechnique(String forcedTechnique) {
|
|
|
@@ -627,13 +617,12 @@ public class RenderManager {
|
|
|
|
|
|
/**
|
|
|
* Adds a forced material parameter to use when rendering geometries.
|
|
|
- *
|
|
|
- * <p>The provided parameter takes precedence over parameters set on the
|
|
|
+ * <p>
|
|
|
+ * The provided parameter takes precedence over parameters set on the
|
|
|
* material or any overrides that exist in the scene graph that have the
|
|
|
* same name.
|
|
|
*
|
|
|
- * @param override The override to add
|
|
|
- * @see MatParamOverride
|
|
|
+ * @param override The material parameter override to add.
|
|
|
* @see #removeForcedMatParam(com.jme3.material.MatParamOverride)
|
|
|
*/
|
|
|
public void addForcedMatParam(MatParamOverride override) {
|
|
|
@@ -641,9 +630,9 @@ public class RenderManager {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Removes a forced material parameter previously added.
|
|
|
+ * Removes a material parameter override.
|
|
|
*
|
|
|
- * @param override The override to remove.
|
|
|
+ * @param override The material parameter override to remove.
|
|
|
* @see #addForcedMatParam(com.jme3.material.MatParamOverride)
|
|
|
*/
|
|
|
public void removeForcedMatParam(MatParamOverride override) {
|
|
|
@@ -757,33 +746,35 @@ public class RenderManager {
|
|
|
* @see com.jme3.material.Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager)
|
|
|
*/
|
|
|
public void renderGeometry(Geometry geom) {
|
|
|
-
|
|
|
+
|
|
|
if (renderFilter != null && !renderFilter.test(geom)) {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
LightList lightList = geom.getWorldLightList();
|
|
|
if (lightFilter != null) {
|
|
|
filteredLightList.clear();
|
|
|
lightFilter.filterLights(geom, filteredLightList);
|
|
|
lightList = filteredLightList;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
renderGeometry(geom, lightList);
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- *
|
|
|
- * @param geom
|
|
|
- * @param lightList
|
|
|
+ * Renders a single {@link Geometry} with a specific list of lights.
|
|
|
+ * This method applies the world transform, handles forced materials and techniques,
|
|
|
+ * and manages the `BoundDrawBuffer` parameter for multi-target frame buffers.
|
|
|
+ *
|
|
|
+ * @param geom The {@link Geometry} to render.
|
|
|
+ * @param lightList The {@link LightList} containing the lights that affect this geometry.
|
|
|
*/
|
|
|
public void renderGeometry(Geometry geom, LightList lightList) {
|
|
|
-
|
|
|
+
|
|
|
if (renderFilter != null && !renderFilter.test(geom)) {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
this.renderer.pushDebugGroup(geom.getName());
|
|
|
if (geom.isIgnoreTransform()) {
|
|
|
setWorldMatrix(Matrix4f.IDENTITY);
|
|
|
@@ -818,8 +809,7 @@ public class RenderManager {
|
|
|
RenderState tmpRs = forcedRenderState;
|
|
|
if (geom.getMaterial().getActiveTechnique().getDef().getForcedRenderState() != null) {
|
|
|
//forcing forced technique renderState
|
|
|
- forcedRenderState
|
|
|
- = geom.getMaterial().getActiveTechnique().getDef().getForcedRenderState();
|
|
|
+ forcedRenderState = geom.getMaterial().getActiveTechnique().getDef().getForcedRenderState();
|
|
|
}
|
|
|
// use geometry's material
|
|
|
material.render(geom, lightList, this);
|
|
|
@@ -902,7 +892,7 @@ public class RenderManager {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Flattens the given scene graph into the ViewPort's RenderQueue,
|
|
|
* checking for culling as the call goes down the graph recursively.
|
|
|
@@ -1079,10 +1069,9 @@ public class RenderManager {
|
|
|
*/
|
|
|
public void setSinglePassLightBatchSize(int singlePassLightBatchSize) {
|
|
|
// Ensure the batch size is no less than 1
|
|
|
- this.singlePassLightBatchSize = singlePassLightBatchSize < 1 ? 1 : singlePassLightBatchSize;
|
|
|
+ this.singlePassLightBatchSize = Math.max(singlePassLightBatchSize, 1);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Renders the given viewport queues.
|
|
|
*
|
|
|
@@ -1126,7 +1115,6 @@ public class RenderManager {
|
|
|
depthRangeChanged = true;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// transparent objects are last because they require blending with the
|
|
|
// rest of the scene's objects. Consequently, they are sorted
|
|
|
// back-to-front.
|
|
|
@@ -1184,12 +1172,12 @@ public class RenderManager {
|
|
|
private void setViewPort(Camera cam) {
|
|
|
// this will make sure to clearReservations viewport only if needed
|
|
|
if (cam != prevCam || cam.isViewportChanged()) {
|
|
|
- viewX = (int) (cam.getViewPortLeft() * cam.getWidth());
|
|
|
- viewY = (int) (cam.getViewPortBottom() * cam.getHeight());
|
|
|
+ int viewX = (int) (cam.getViewPortLeft() * cam.getWidth());
|
|
|
+ int viewY = (int) (cam.getViewPortBottom() * cam.getHeight());
|
|
|
int viewX2 = (int) (cam.getViewPortRight() * cam.getWidth());
|
|
|
int viewY2 = (int) (cam.getViewPortTop() * cam.getHeight());
|
|
|
- viewWidth = viewX2 - viewX;
|
|
|
- viewHeight = viewY2 - viewY;
|
|
|
+ int viewWidth = viewX2 - viewX;
|
|
|
+ int viewHeight = viewY2 - viewY;
|
|
|
uniformBindingManager.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
|
|
renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
|
|
renderer.setClipRect(viewX, viewY, viewWidth, viewHeight);
|
|
|
@@ -1266,8 +1254,8 @@ public class RenderManager {
|
|
|
/**
|
|
|
* Applies the ViewPort's Camera and FrameBuffer in preparation
|
|
|
* for rendering.
|
|
|
- *
|
|
|
- * @param vp
|
|
|
+ *
|
|
|
+ * @param vp The ViewPort to apply.
|
|
|
*/
|
|
|
public void applyViewPort(ViewPort vp) {
|
|
|
renderer.setFrameBuffer(vp.getOutputFrameBuffer());
|
|
|
@@ -1279,7 +1267,7 @@ public class RenderManager {
|
|
|
renderer.clearBuffers(vp.isClearColor(), vp.isClearDepth(), vp.isClearStencil());
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Renders the {@link ViewPort} using the ViewPort's {@link RenderPipeline}.
|
|
|
* <p>
|
|
|
@@ -1294,11 +1282,12 @@ public class RenderManager {
|
|
|
public void renderViewPort(ViewPort vp, float tpf) {
|
|
|
if (!vp.isEnabled()) {
|
|
|
return;
|
|
|
- }
|
|
|
+ }
|
|
|
RenderPipeline pipeline = vp.getPipeline();
|
|
|
if (pipeline == null) {
|
|
|
pipeline = defaultPipeline;
|
|
|
}
|
|
|
+
|
|
|
PipelineContext context = pipeline.fetchPipelineContext(this);
|
|
|
if (context == null) {
|
|
|
throw new NullPointerException("Failed to fetch pipeline context.");
|
|
|
@@ -1310,6 +1299,7 @@ public class RenderManager {
|
|
|
usedPipelines.add(pipeline);
|
|
|
pipeline.startRenderFrame(this);
|
|
|
}
|
|
|
+
|
|
|
pipeline.pipelineRender(this, context, vp, tpf);
|
|
|
context.endViewPortRender(this, vp);
|
|
|
}
|
|
|
@@ -1333,7 +1323,7 @@ public class RenderManager {
|
|
|
if (renderer instanceof NullRenderer) {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
uniformBindingManager.newFrame();
|
|
|
|
|
|
if (prof != null) {
|
|
|
@@ -1365,17 +1355,16 @@ public class RenderManager {
|
|
|
renderViewPort(vp, tpf);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// cleanup for used render pipelines and pipeline contexts only
|
|
|
for (int i = 0; i < usedContexts.size(); i++) {
|
|
|
usedContexts.get(i).endContextRenderFrame(this);
|
|
|
}
|
|
|
- for (int i = 0; i < usedPipelines.size(); i++) {
|
|
|
- usedPipelines.get(i).endRenderFrame(this);
|
|
|
+ for (RenderPipeline<?> p : usedPipelines) {
|
|
|
+ p.endRenderFrame(this);
|
|
|
}
|
|
|
usedContexts.clear();
|
|
|
usedPipelines.clear();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1384,41 +1373,42 @@ public class RenderManager {
|
|
|
* @return True if the draw buffer target id is passed to the shaders.
|
|
|
*/
|
|
|
public boolean getPassDrawBufferTargetIdToShaders() {
|
|
|
- return this.forcedOverrides.contains(boundDrawBufferId);
|
|
|
+ return forcedOverrides.contains(boundDrawBufferId);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Enable or disable passing the draw buffer target id to the shaders. This
|
|
|
* is needed to handle FrameBuffer.setTargetIndex correctly in some
|
|
|
- * backends.
|
|
|
+ * backends. When enabled, a material parameter named "BoundDrawBuffer" of
|
|
|
+ * type Int will be added to forced material parameters.
|
|
|
*
|
|
|
- * @param v
|
|
|
- * True to enable, false to disable (default is true)
|
|
|
+ * @param enable True to enable, false to disable (default is true)
|
|
|
*/
|
|
|
- public void setPassDrawBufferTargetIdToShaders(boolean v) {
|
|
|
- if (v) {
|
|
|
- if (!this.forcedOverrides.contains(boundDrawBufferId)) {
|
|
|
- this.forcedOverrides.add(boundDrawBufferId);
|
|
|
+ public void setPassDrawBufferTargetIdToShaders(boolean enable) {
|
|
|
+ if (enable) {
|
|
|
+ if (!forcedOverrides.contains(boundDrawBufferId)) {
|
|
|
+ forcedOverrides.add(boundDrawBufferId);
|
|
|
}
|
|
|
} else {
|
|
|
- this.forcedOverrides.remove(boundDrawBufferId);
|
|
|
+ forcedOverrides.remove(boundDrawBufferId);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Set a render filter. Every geometry will be tested against this filter
|
|
|
* before rendering and will only be rendered if the filter returns true.
|
|
|
- *
|
|
|
- * @param filter the render filter
|
|
|
+ * This allows for custom culling or selective rendering based on geometry properties.
|
|
|
+ *
|
|
|
+ * @param filter The render filter to apply, or null to remove any existing filter.
|
|
|
*/
|
|
|
public void setRenderFilter(Predicate<Geometry> filter) {
|
|
|
renderFilter = filter;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns the render filter that the RenderManager is currently using
|
|
|
- *
|
|
|
- * @return the render filter
|
|
|
+ * Returns the render filter that the RenderManager is currently using.
|
|
|
+ *
|
|
|
+ * @return The currently active render filter, or null if no filter is set.
|
|
|
*/
|
|
|
public Predicate<Geometry> getRenderFilter() {
|
|
|
return renderFilter;
|