Opens the Renderer's API, switch to using guava's Graph facilities.
commit
7c7edd128d
|
@ -16,6 +16,8 @@
|
|||
package org.terasology.rendering.dag;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Set;
|
||||
import org.junit.Test;
|
||||
import org.terasology.engine.SimpleUri;
|
||||
|
||||
|
@ -30,25 +32,22 @@ public class RenderTaskListGeneratorTest {
|
|||
|
||||
RenderTaskListGenerator renderTaskListGenerator = new RenderTaskListGenerator();
|
||||
List<Node> orderedNodes = Lists.newArrayList();
|
||||
Node alphaNode = new AlphaNode();
|
||||
alphaNode.setUri(new SimpleUri("engine:alphaNode"));
|
||||
Node alphaNode = new AlphaNode("alphaNode");
|
||||
orderedNodes.add(alphaNode);
|
||||
Node bravoNode = new BravoNode();
|
||||
bravoNode.setUri(new SimpleUri("engine:bravoNode"));
|
||||
Node bravoNode = new BravoNode("bravoNode");
|
||||
orderedNodes.add(bravoNode);
|
||||
Node charlieNode = new CharlieNode();
|
||||
charlieNode.setUri(new SimpleUri("engine:charlieNode"));
|
||||
Node charlieNode = new CharlieNode("charlieNode");
|
||||
orderedNodes.add(charlieNode);
|
||||
|
||||
List<RenderPipelineTask> taskList = renderTaskListGenerator.generateFrom(orderedNodes);
|
||||
|
||||
assertEquals("----- engine:alphaNode (AlphaNode)", taskList.get(0).toString().trim()); // Strictly speaking we don't need
|
||||
assertEquals("----- test:alphaNode (AlphaNode)", taskList.get(0).toString().trim()); // Strictly speaking we don't need
|
||||
assertEquals("SetName: foo", taskList.get(1).toString().trim()); // trimming MarkerTask.toString(),
|
||||
assertEquals("engine:alphaNode (AlphaNode)", taskList.get(2).toString().trim()); // resulting in "----- <NodeName>"
|
||||
assertEquals("----- engine:bravoNode (BravoNode)", taskList.get(3).toString().trim()); // We just do it to avoid attracting
|
||||
assertEquals("engine:bravoNode (BravoNode)", taskList.get(4).toString().trim()); // too much attention to it.
|
||||
assertEquals("----- engine:charlieNode (CharlieNode)", taskList.get(5).toString().trim());
|
||||
assertEquals("engine:charlieNode (CharlieNode)", taskList.get(6).toString().trim());
|
||||
assertEquals("test:alphaNode (AlphaNode)", taskList.get(2).toString().trim()); // resulting in "----- <NodeName>"
|
||||
assertEquals("----- test:bravoNode (BravoNode)", taskList.get(3).toString().trim()); // We just do it to avoid attracting
|
||||
assertEquals("test:bravoNode (BravoNode)", taskList.get(4).toString().trim()); // too much attention to it.
|
||||
assertEquals("----- test:charlieNode (CharlieNode)", taskList.get(5).toString().trim());
|
||||
assertEquals("test:charlieNode (CharlieNode)", taskList.get(6).toString().trim());
|
||||
assertEquals("SetName: bar", taskList.get(7).toString().trim());
|
||||
}
|
||||
|
||||
|
@ -56,31 +55,27 @@ public class RenderTaskListGeneratorTest {
|
|||
public void testReducePersistingStateChanges() {
|
||||
RenderTaskListGenerator renderTaskListGenerator = new RenderTaskListGenerator();
|
||||
List<Node> orderedNodes = Lists.newArrayList();
|
||||
Node alphaNode = new AlphaNode();
|
||||
alphaNode.setUri(new SimpleUri("engine:alphaNode"));
|
||||
Node alphaNode = new AlphaNode("alphaNode");
|
||||
orderedNodes.add(alphaNode);
|
||||
Node bravoNode = new BravoNode();
|
||||
bravoNode.setUri(new SimpleUri("engine:bravoNode"));
|
||||
Node bravoNode = new BravoNode("bravoNode");
|
||||
orderedNodes.add(bravoNode);
|
||||
Node charlieNode = new CharlieNode();
|
||||
charlieNode.setUri(new SimpleUri("engine:charlieNode"));
|
||||
Node charlieNode = new CharlieNode("charlieNode");
|
||||
orderedNodes.add(charlieNode);
|
||||
Node deltaNode = new DeltaNode();
|
||||
deltaNode.setUri(new SimpleUri("engine:deltaNode"));
|
||||
Node deltaNode = new DeltaNode("deltaNode");
|
||||
orderedNodes.add(deltaNode);
|
||||
|
||||
List<RenderPipelineTask> taskList = renderTaskListGenerator.generateFrom(orderedNodes);
|
||||
|
||||
assertEquals("----- engine:alphaNode (AlphaNode)", taskList.get(0).toString().trim());
|
||||
assertEquals("----- test:alphaNode (AlphaNode)", taskList.get(0).toString().trim());
|
||||
assertEquals("SetName: foo", taskList.get(1).toString().trim());
|
||||
assertEquals("engine:alphaNode (AlphaNode)", taskList.get(2).toString().trim());
|
||||
assertEquals("----- engine:bravoNode (BravoNode)", taskList.get(3).toString().trim());
|
||||
assertEquals("engine:bravoNode (BravoNode)", taskList.get(4).toString().trim());
|
||||
assertEquals("----- engine:charlieNode (CharlieNode)", taskList.get(5).toString().trim());
|
||||
assertEquals("engine:charlieNode (CharlieNode)", taskList.get(6).toString().trim());
|
||||
assertEquals("----- engine:deltaNode (DeltaNode)", taskList.get(7).toString().trim());
|
||||
assertEquals("SetName: delta", taskList.get(8).toString().trim());
|
||||
assertEquals("engine:deltaNode (DeltaNode)", taskList.get(9).toString().trim());
|
||||
assertEquals("test:alphaNode (AlphaNode)", taskList.get(2).toString().trim());
|
||||
assertEquals("----- test:bravoNode (BravoNode)", taskList.get(3).toString().trim());
|
||||
assertEquals("test:bravoNode (BravoNode)", taskList.get(4).toString().trim());
|
||||
assertEquals("----- test:charlieNode (CharlieNode)", taskList.get(5).toString().trim());
|
||||
assertEquals("test:charlieNode (CharlieNode)", taskList.get(6).toString().trim());
|
||||
assertEquals("----- test:deltaNode (DeltaNode)", taskList.get(7).toString().trim());
|
||||
assertEquals("SetName: bar", taskList.get(8).toString().trim());
|
||||
assertEquals("test:deltaNode (DeltaNode)", taskList.get(9).toString().trim());
|
||||
assertEquals("SetName: bar", taskList.get(10).toString().trim());
|
||||
}
|
||||
|
||||
|
@ -88,44 +83,85 @@ public class RenderTaskListGeneratorTest {
|
|||
public void testReducePersistingStateChangesEcho() {
|
||||
RenderTaskListGenerator renderTaskListGenerator = new RenderTaskListGenerator();
|
||||
List<Node> orderedNodes = Lists.newArrayList();
|
||||
Node alphaNode = new AlphaNode();
|
||||
alphaNode.setUri(new SimpleUri("engine:alphaNode"));
|
||||
Node alphaNode = new AlphaNode("alphaNode");
|
||||
orderedNodes.add(alphaNode);
|
||||
Node bravoNode = new BravoNode();
|
||||
bravoNode.setUri(new SimpleUri("engine:bravoNode"));
|
||||
Node bravoNode = new BravoNode("bravoNode");
|
||||
orderedNodes.add(bravoNode);
|
||||
Node echoNode = new EchoNode();
|
||||
echoNode.setUri(new SimpleUri("engine:echoNode"));
|
||||
Node echoNode = new EchoNode("echoNode");
|
||||
orderedNodes.add(echoNode);
|
||||
Node charlieNode = new CharlieNode();
|
||||
charlieNode.setUri(new SimpleUri("engine:charlieNode"));
|
||||
Node charlieNode = new CharlieNode("charlieNode");
|
||||
orderedNodes.add(charlieNode);
|
||||
Node deltaNode = new DeltaNode();
|
||||
deltaNode.setUri(new SimpleUri("engine:deltaNode"));
|
||||
Node deltaNode = new DeltaNode("deltaNode");
|
||||
orderedNodes.add(deltaNode);
|
||||
|
||||
List<RenderPipelineTask> taskList = renderTaskListGenerator.generateFrom(orderedNodes);
|
||||
|
||||
assertEquals("----- engine:alphaNode (AlphaNode)", taskList.get(0).toString().trim());
|
||||
assertEquals("----- test:alphaNode (AlphaNode)", taskList.get(0).toString().trim());
|
||||
assertEquals("SetName: foo", taskList.get(1).toString().trim());
|
||||
assertEquals("engine:alphaNode (AlphaNode)", taskList.get(2).toString().trim());
|
||||
assertEquals("----- engine:bravoNode (BravoNode)", taskList.get(3).toString().trim());
|
||||
assertEquals("engine:bravoNode (BravoNode)", taskList.get(4).toString().trim());
|
||||
assertEquals("----- engine:echoNode (EchoNode)", taskList.get(5).toString().trim());
|
||||
assertEquals("test:alphaNode (AlphaNode)", taskList.get(2).toString().trim());
|
||||
assertEquals("----- test:bravoNode (BravoNode)", taskList.get(3).toString().trim());
|
||||
assertEquals("test:bravoNode (BravoNode)", taskList.get(4).toString().trim());
|
||||
assertEquals("----- test:echoNode (EchoNode)", taskList.get(5).toString().trim());
|
||||
assertEquals("SetName: bar", taskList.get(6).toString().trim());
|
||||
assertEquals("engine:echoNode (EchoNode)", taskList.get(7).toString().trim());
|
||||
assertEquals("----- engine:charlieNode (CharlieNode)", taskList.get(8).toString().trim());
|
||||
assertEquals("test:echoNode (EchoNode)", taskList.get(7).toString().trim());
|
||||
assertEquals("----- test:charlieNode (CharlieNode)", taskList.get(8).toString().trim());
|
||||
assertEquals("SetName: foo", taskList.get(9).toString().trim());
|
||||
assertEquals("engine:charlieNode (CharlieNode)", taskList.get(10).toString().trim());
|
||||
assertEquals("----- engine:deltaNode (DeltaNode)", taskList.get(11).toString().trim());
|
||||
assertEquals("SetName: delta", taskList.get(12).toString().trim());
|
||||
assertEquals("engine:deltaNode (DeltaNode)", taskList.get(13).toString().trim());
|
||||
assertEquals("test:charlieNode (CharlieNode)", taskList.get(10).toString().trim());
|
||||
assertEquals("----- test:deltaNode (DeltaNode)", taskList.get(11).toString().trim());
|
||||
assertEquals("SetName: bar", taskList.get(12).toString().trim());
|
||||
assertEquals("test:deltaNode (DeltaNode)", taskList.get(13).toString().trim());
|
||||
assertEquals("SetName: bar", taskList.get(14).toString().trim());
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access") // actual node classes are not meant to be static
|
||||
private class AlphaNode extends AbstractNode {
|
||||
AlphaNode() {
|
||||
private abstract class DummyNode implements Node {
|
||||
private SimpleUri nodeUri;
|
||||
private Set<StateChange> desiredStateChanges = Sets.newLinkedHashSet();
|
||||
private boolean enabled;
|
||||
|
||||
DummyNode(String nodeUri) {
|
||||
this.nodeUri = new SimpleUri("test:" + nodeUri);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleUri getUri() {
|
||||
return nodeUri;
|
||||
}
|
||||
|
||||
void addDesiredStateChange(StateChange stateChange) {
|
||||
desiredStateChanges.add(stateChange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<StateChange> getDesiredStateChanges() {
|
||||
return desiredStateChanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(String command, String... arguments) { }
|
||||
|
||||
@Override
|
||||
public void dispose() { }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s (%s)", getUri(), this.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private class AlphaNode extends DummyNode {
|
||||
AlphaNode(String nodeUri) {
|
||||
super(nodeUri);
|
||||
addDesiredStateChange(new SetName("foo"));
|
||||
}
|
||||
|
||||
|
@ -133,9 +169,9 @@ public class RenderTaskListGeneratorTest {
|
|||
public void process() { }
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access") // actual node classes are not meant to be static
|
||||
private class BravoNode extends AbstractNode {
|
||||
BravoNode() {
|
||||
private class BravoNode extends DummyNode {
|
||||
BravoNode(String nodeUri) {
|
||||
super(nodeUri);
|
||||
addDesiredStateChange(new SetName("foo"));
|
||||
}
|
||||
|
||||
|
@ -143,9 +179,9 @@ public class RenderTaskListGeneratorTest {
|
|||
public void process() { }
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access") // actual node classes are not meant to be static
|
||||
private class CharlieNode extends AbstractNode {
|
||||
CharlieNode() {
|
||||
private class CharlieNode extends DummyNode {
|
||||
CharlieNode(String nodeUri) {
|
||||
super(nodeUri);
|
||||
addDesiredStateChange(new SetName("foo"));
|
||||
}
|
||||
|
||||
|
@ -153,19 +189,20 @@ public class RenderTaskListGeneratorTest {
|
|||
public void process() { }
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access") // actual node classes are not meant to be static
|
||||
private class DeltaNode extends AbstractNode {
|
||||
DeltaNode() {
|
||||
addDesiredStateChange(new SetName("delta"));
|
||||
private class DeltaNode extends DummyNode {
|
||||
DeltaNode(String nodeUri) {
|
||||
super(nodeUri);
|
||||
addDesiredStateChange(new SetName("bar"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() { }
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access") // actual node classes are not meant to be static
|
||||
private class EchoNode extends AbstractNode {
|
||||
EchoNode() { }
|
||||
private class EchoNode extends DummyNode {
|
||||
EchoNode(String nodeUri) {
|
||||
super(nodeUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() { }
|
||||
|
|
|
@ -92,7 +92,7 @@ dependencies {
|
|||
|
||||
|
||||
// Storage and networking
|
||||
compile group: 'com.google.guava', name: 'guava', version: '19.0'
|
||||
compile group: 'com.google.guava', name: 'guava', version: '23.0'
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.6.2'
|
||||
compile group: 'com.google.protobuf', name: 'protobuf-java', version: '2.6.1'
|
||||
compile group: 'net.sf.trove4j', name: 'trove4j', version: '3.0.3'
|
||||
|
@ -127,7 +127,7 @@ dependencies {
|
|||
// Small-time 3rd party libs we've stored in our Artifactory for access
|
||||
compile group: 'ec.util', name: 'MersenneTwister', version: '20'
|
||||
compile group: 'org.eaxy', name: 'eaxy', version: '0.1'
|
||||
|
||||
|
||||
// telemetry
|
||||
compile (group: 'com.snowplowanalytics', name: 'snowplow-java-tracker', version :'0.8.0'){
|
||||
exclude group:'org.slf4j',module:'slf4j-simple'
|
||||
|
@ -185,7 +185,7 @@ task cacheReflections {
|
|||
description = 'Caches reflection output to make regular startup faster. May go stale and need cleanup at times.'
|
||||
inputs.files project.classes.outputs.files
|
||||
dependsOn classes
|
||||
|
||||
|
||||
doLast {
|
||||
// Without the .mkdirs() we might hit a scenario where the classes dir doesn't exist yet
|
||||
file(sourceSets.main.output.classesDir.toString()).mkdirs()
|
||||
|
@ -194,7 +194,7 @@ task cacheReflections {
|
|||
.setScanners(new TypeAnnotationsScanner(), new SubTypesScanner()))
|
||||
reflections.save(sourceSets.main.output.classesDir.toString() + "/reflections.cache")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
task cleanReflections(type: Delete) {
|
||||
|
|
|
@ -79,6 +79,10 @@ public final class ExternalApiWhitelist {
|
|||
.add("sun.reflect")
|
||||
.add("com.snowplowanalytics.snowplow.tracker.events")
|
||||
.add("com.snowplowanalytics.snowplow.tracker.payload")
|
||||
.add("org.lwjgl.opengl")
|
||||
.add("org.lwjgl.opengl.GL11")
|
||||
.add("org.lwjgl.opengl.GL12")
|
||||
.add("org.lwjgl.opengl.GL13")
|
||||
.build();
|
||||
|
||||
public static final Set<Class<?>> CLASSES = new ImmutableSet.Builder<Class<?>>()
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.terasology.monitoring.PerformanceMonitor;
|
|||
import org.terasology.rendering.assets.material.Material;
|
||||
import org.terasology.rendering.cameras.Camera;
|
||||
import org.terasology.rendering.cameras.SubmersibleCamera;
|
||||
import org.terasology.rendering.dag.RenderGraph;
|
||||
import org.terasology.rendering.world.viewDistance.ViewDistance;
|
||||
import org.terasology.rendering.world.WorldRenderer;
|
||||
import org.terasology.world.WorldProvider;
|
||||
|
@ -192,6 +193,11 @@ public class HeadlessWorldRenderer implements WorldRenderer {
|
|||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderGraph getRenderGraph() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of chunks around the player.
|
||||
*
|
||||
|
|
|
@ -20,7 +20,12 @@ import com.google.common.collect.Sets;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.terasology.assets.ResourceUrn;
|
||||
import org.terasology.context.Context;
|
||||
import org.terasology.engine.SimpleUri;
|
||||
import org.terasology.engine.module.ModuleManager;
|
||||
import org.terasology.module.sandbox.API;
|
||||
import org.terasology.naming.Name;
|
||||
import org.terasology.registry.CoreRegistry;
|
||||
import org.terasology.rendering.assets.material.Material;
|
||||
import org.terasology.rendering.opengl.BaseFBOsManager;
|
||||
import org.terasology.rendering.opengl.FBO;
|
||||
|
@ -39,7 +44,14 @@ public abstract class AbstractNode implements Node {
|
|||
private Set<StateChange> desiredStateChanges = Sets.newLinkedHashSet();
|
||||
private Map<SimpleUri, BaseFBOsManager> fboUsages = Maps.newHashMap();
|
||||
protected boolean enabled = true;
|
||||
private SimpleUri nodeUri = null;
|
||||
private final SimpleUri nodeUri;
|
||||
|
||||
protected AbstractNode(String nodeUri, Context context) {
|
||||
ModuleManager moduleManager = context.get(ModuleManager.class);
|
||||
Name providingModule = moduleManager.getEnvironment().getModuleProviding(this.getClass());
|
||||
|
||||
this.nodeUri = new SimpleUri(providingModule.toString() + ":" + nodeUri);
|
||||
}
|
||||
|
||||
protected FBO requiresFBO(FBOConfig fboConfig, BaseFBOsManager fboManager) {
|
||||
SimpleUri fboName = fboConfig.getName();
|
||||
|
@ -99,15 +111,6 @@ public abstract class AbstractNode implements Node {
|
|||
@Override
|
||||
public void handleCommand(String command, String... arguments) { }
|
||||
|
||||
@Override
|
||||
public void setUri(SimpleUri nodeUri) {
|
||||
if (this.nodeUri == null) {
|
||||
this.nodeUri = nodeUri;
|
||||
} else {
|
||||
throw new RuntimeException("Cannot set a Node's URI more than once!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleUri getUri() {
|
||||
return nodeUri;
|
||||
|
|
|
@ -32,7 +32,9 @@ public abstract class ConditionDependentNode extends AbstractNode implements Pro
|
|||
|
||||
protected WorldRenderer worldRenderer;
|
||||
|
||||
protected ConditionDependentNode(Context context) {
|
||||
protected ConditionDependentNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,8 @@ package org.terasology.rendering.dag;
|
|||
|
||||
//TODO: consider removing the word "Node" from the name of all Node implementations now that they are in the dag.nodes package.
|
||||
|
||||
import org.terasology.engine.SimpleUri;
|
||||
|
||||
import java.util.Set;
|
||||
import org.terasology.engine.SimpleUri;
|
||||
|
||||
/**
|
||||
* TODO: Add javadocs
|
||||
|
@ -36,7 +35,5 @@ public interface Node extends RenderPipelineTask {
|
|||
|
||||
void handleCommand(String command, String... arguments);
|
||||
|
||||
void setUri(SimpleUri nodeUri);
|
||||
|
||||
SimpleUri getUri();
|
||||
}
|
||||
|
|
|
@ -16,58 +16,56 @@
|
|||
package org.terasology.rendering.dag;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.graph.GraphBuilder;
|
||||
import com.google.common.graph.MutableGraph;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.terasology.engine.SimpleUri;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* TODO: Add javadocs
|
||||
*/
|
||||
public class RenderGraph {
|
||||
private static final Logger logger = LoggerFactory.getLogger(RenderGraph.class);
|
||||
|
||||
private Map<SimpleUri, Node> nodeMap = Maps.newHashMap();
|
||||
// TODO: Convert to biMap
|
||||
private Multimap<Node, Node> edgeMap = HashMultimap.create();
|
||||
private Multimap<Node, Node> reverseEdgeMap = HashMultimap.create();
|
||||
private Map<SimpleUri, Node> nodeMap;
|
||||
private MutableGraph<Node> graph;
|
||||
|
||||
public SimpleUri addNode(Node node, String suggestedUri) {
|
||||
public RenderGraph() {
|
||||
nodeMap = Maps.newHashMap();
|
||||
graph = GraphBuilder.directed().build();
|
||||
}
|
||||
|
||||
public void addNode(Node node) {
|
||||
Preconditions.checkNotNull(node, "node cannot be null!");
|
||||
Preconditions.checkNotNull(suggestedUri, "suggestedUri cannot be null!");
|
||||
|
||||
SimpleUri nodeUri = new SimpleUri("engine:" + suggestedUri);
|
||||
|
||||
SimpleUri nodeUri = node.getUri();
|
||||
if (nodeMap.containsKey(nodeUri)) {
|
||||
int i = 2;
|
||||
while (nodeMap.containsKey(new SimpleUri(nodeUri.toString() + i))) {
|
||||
i++;
|
||||
}
|
||||
nodeUri = new SimpleUri(nodeUri.toString() + i);
|
||||
throw new RuntimeException("A node with uri " + nodeUri + " already exists!");
|
||||
}
|
||||
|
||||
node.setUri(nodeUri);
|
||||
nodeMap.put(nodeUri, node);
|
||||
|
||||
return nodeUri;
|
||||
graph.addNode(node);
|
||||
}
|
||||
|
||||
public Node removeNode(SimpleUri nodeUri) {
|
||||
Preconditions.checkNotNull(nodeUri, "nodeUri cannot be null!");
|
||||
|
||||
if (edgeMap.containsKey(nodeUri)) {
|
||||
throw new RuntimeException("The node you are trying to remove is still connected to other nodes in the graph!");
|
||||
Node node = findNode(nodeUri);
|
||||
if (node == null) {
|
||||
throw new RuntimeException("Node removal failure: there is no '" + nodeUri + "' in the render graph!");
|
||||
}
|
||||
|
||||
if (graph.adjacentNodes(node).size() != 0) {
|
||||
throw new RuntimeException("Node removal failure: node '" + nodeUri + "' is still connected to other nodes in the render graph!");
|
||||
}
|
||||
|
||||
nodeMap.remove(nodeUri);
|
||||
return nodeMap.remove(nodeUri);
|
||||
}
|
||||
|
||||
|
@ -81,10 +79,8 @@ public class RenderGraph {
|
|||
return findNode(new SimpleUri(simpleUri));
|
||||
}
|
||||
|
||||
public boolean connect(Node ... nodeList) {
|
||||
boolean returnValue = true;
|
||||
|
||||
assert(nodeList.length > 1);
|
||||
public void connect(Node ... nodeList) {
|
||||
Preconditions.checkArgument(nodeList.length > 1, "Expected at least 2 nodes as arguments to connect() - found " + nodeList.length);
|
||||
|
||||
Node fromNode = null;
|
||||
|
||||
|
@ -92,28 +88,26 @@ public class RenderGraph {
|
|||
Preconditions.checkNotNull(toNode, "toNode cannot be null!");
|
||||
|
||||
if (fromNode != null) {
|
||||
boolean success = edgeMap.put(fromNode, toNode);
|
||||
if (success) {
|
||||
reverseEdgeMap.put(toNode, fromNode);
|
||||
if (!graph.hasEdgeConnecting(fromNode, toNode)) {
|
||||
graph.putEdge(fromNode, toNode);
|
||||
} else {
|
||||
logger.warn("Trying to connect two already connected nodes, " + fromNode.getClass() + " and " + toNode.getClass());
|
||||
logger.warn("Trying to connect two already connected nodes, " + fromNode.getUri() + " and " + toNode.getUri());
|
||||
}
|
||||
|
||||
returnValue = returnValue && success;
|
||||
}
|
||||
|
||||
fromNode = toNode;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public boolean disconnect(Node fromNode, Node toNode) {
|
||||
public void disconnect(Node fromNode, Node toNode) {
|
||||
Preconditions.checkNotNull(fromNode, "fromNode cannot be null!");
|
||||
Preconditions.checkNotNull(toNode, "toNode cannot be null!");
|
||||
|
||||
reverseEdgeMap.remove(toNode, fromNode);
|
||||
return edgeMap.remove(fromNode, toNode);
|
||||
if (!graph.hasEdgeConnecting(fromNode, toNode)) {
|
||||
logger.warn("Trying to disconnect two nodes that aren't connected, " + fromNode.getUri() + " and " + toNode.getUri());
|
||||
}
|
||||
|
||||
graph.removeEdge(fromNode, toNode);
|
||||
}
|
||||
|
||||
// TODO: Add `boolean isFullyFunctional(Node node)`
|
||||
|
@ -131,15 +125,12 @@ public class RenderGraph {
|
|||
List<Node> nodesToExamine = Lists.newArrayList();
|
||||
int visitedNodes = 0;
|
||||
|
||||
// Calculate the in-degree for each node.
|
||||
for (Entry<Node, Collection<Node>> nodeEdgeList : reverseEdgeMap.asMap().entrySet()) {
|
||||
inDegreeMap.put(nodeEdgeList.getKey(), nodeEdgeList.getValue().size());
|
||||
}
|
||||
// Calculate the in-degree for each node, and mark all nodes with no incoming edges for examination.
|
||||
for (Node node : graph.nodes()) {
|
||||
int inDegree = graph.inDegree(node);
|
||||
inDegreeMap.put(node, inDegree);
|
||||
|
||||
// Add the missing nodes that did not have any edges, and mark them for examination
|
||||
for (Node node : nodeMap.values()) {
|
||||
if (!inDegreeMap.containsKey(node)) {
|
||||
inDegreeMap.put(node, 0);
|
||||
if (inDegree == 0) {
|
||||
nodesToExamine.add(node);
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +138,7 @@ public class RenderGraph {
|
|||
while (!nodesToExamine.isEmpty()) {
|
||||
Node currentNode = nodesToExamine.remove(0);
|
||||
|
||||
for (Node adjacentNode : edgeMap.get(currentNode)) {
|
||||
for (Node adjacentNode : graph.successors(currentNode)) {
|
||||
int updatedInDegree = inDegreeMap.get(adjacentNode) - 1;
|
||||
inDegreeMap.put(adjacentNode, updatedInDegree);
|
||||
|
||||
|
@ -169,8 +160,10 @@ public class RenderGraph {
|
|||
}
|
||||
|
||||
public void dispose() {
|
||||
for (Node node : nodeMap.values()) {
|
||||
graph.removeNode(node);
|
||||
node.dispose();
|
||||
}
|
||||
nodeMap.clear();
|
||||
edgeMap.clear();
|
||||
reverseEdgeMap.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,9 @@ public class AlphaRejectBlocksNode extends AbstractNode implements WireframeCapa
|
|||
@Range(min = 0.0f, max = 0.50f)
|
||||
private float parallaxScale = 0.05f;
|
||||
|
||||
public AlphaRejectBlocksNode(Context context) {
|
||||
public AlphaRejectBlocksNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
renderQueues = context.get(RenderQueuesHelper.class);
|
||||
worldProvider = context.get(WorldProvider.class);
|
||||
|
||||
|
|
|
@ -96,8 +96,8 @@ public class AmbientOcclusionNode extends ConditionDependentNode {
|
|||
|
||||
private FloatBuffer ssaoSamples;
|
||||
|
||||
public AmbientOcclusionNode(Context context) {
|
||||
super(context);
|
||||
public AmbientOcclusionNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
activeCamera = worldRenderer.getActiveCamera();
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ import static org.terasology.rendering.opengl.OpenGLUtils.renderFullscreenQuad;
|
|||
public class ApplyDeferredLightingNode extends AbstractNode {
|
||||
private static final ResourceUrn DEFERRED_LIGHTING_MATERIAL_URN = new ResourceUrn("engine:prog.lightBufferPass");
|
||||
|
||||
public ApplyDeferredLightingNode(Context context) {
|
||||
public ApplyDeferredLightingNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
DisplayResolutionDependentFBOs displayResolutionDependentFBOs = context.get(DisplayResolutionDependentFBOs.class);
|
||||
SwappableFBO gBufferPair = displayResolutionDependentFBOs.getGBufferPair();
|
||||
|
||||
|
|
|
@ -91,7 +91,9 @@ public class BackdropNode extends AbstractNode implements WireframeCapable {
|
|||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private float turbidity;
|
||||
|
||||
public BackdropNode(Context context) {
|
||||
public BackdropNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
|
|
|
@ -97,7 +97,9 @@ public class BackdropReflectionNode extends AbstractNode {
|
|||
*
|
||||
* This method also requests the material using the "sky" shaders (vertex, fragment) to be enabled.
|
||||
*/
|
||||
public BackdropReflectionNode(Context context) {
|
||||
public BackdropReflectionNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
|
||||
SubmersibleCamera activeCamera = context.get(WorldRenderer.class).getActiveCamera();
|
||||
|
|
|
@ -43,8 +43,8 @@ public class BloomBlurNode extends BlurNode {
|
|||
* @param inputFbo The input fbo, containing the image to be blurred.
|
||||
* @param outputFbo The output fbo, to store the blurred image.
|
||||
*/
|
||||
public BloomBlurNode(Context context, FBO inputFbo, FBO outputFbo) {
|
||||
super(context, inputFbo, outputFbo, BLUR_RADIUS);
|
||||
public BloomBlurNode(String nodeUri, Context context, FBO inputFbo, FBO outputFbo) {
|
||||
super(nodeUri, context, inputFbo, outputFbo, BLUR_RADIUS);
|
||||
|
||||
RenderingConfig renderingConfig = context.get(Config.class).getRendering();
|
||||
requiresCondition(renderingConfig::isBloom);
|
||||
|
|
|
@ -48,8 +48,8 @@ public class BlurNode extends ConditionDependentNode {
|
|||
* @param outputFbo The output fbo, to store the blurred image.
|
||||
* @param blurRadius the blur radius: higher values cause higher blur. The shader's default is 16.0f.
|
||||
*/
|
||||
public BlurNode(Context context, FBO inputFbo, FBO outputFbo, float blurRadius) {
|
||||
super(context);
|
||||
public BlurNode(String nodeUri, Context context, FBO inputFbo, FBO outputFbo, float blurRadius) {
|
||||
super(nodeUri, context);
|
||||
|
||||
this.blurRadius = blurRadius;
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ public class BlurredAmbientOcclusionNode extends ConditionDependentNode {
|
|||
|
||||
private FBO ssaoBlurredFbo;
|
||||
|
||||
public BlurredAmbientOcclusionNode(Context context) {
|
||||
super(context);
|
||||
public BlurredAmbientOcclusionNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
RenderingConfig renderingConfig = context.get(Config.class).getRendering();
|
||||
renderingConfig.subscribe(RenderingConfig.SSAO, this);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.terasology.rendering.dag.nodes;
|
||||
|
||||
import org.terasology.context.Context;
|
||||
import org.terasology.rendering.dag.AbstractNode;
|
||||
import org.terasology.rendering.dag.stateChanges.BindFbo;
|
||||
import org.terasology.rendering.opengl.BaseFBOsManager;
|
||||
|
@ -45,7 +46,8 @@ public class BufferClearingNode extends AbstractNode {
|
|||
* Non GL_*_BIT values will be accepted but might eventually generate an opengl error.
|
||||
* @throws IllegalArgumentException if fboConfig, fboManager are null and if clearingMask is zero.
|
||||
*/
|
||||
public BufferClearingNode(FBOConfig fboConfig, BaseFBOsManager fboManager, int clearingMask) {
|
||||
public BufferClearingNode(String nodeUri, Context context, FBOConfig fboConfig, BaseFBOsManager fboManager, int clearingMask) {
|
||||
super(nodeUri, context);
|
||||
|
||||
boolean argumentsAreValid = validateArguments(fboConfig, fboManager, clearingMask);
|
||||
|
||||
|
@ -58,7 +60,9 @@ public class BufferClearingNode extends AbstractNode {
|
|||
}
|
||||
}
|
||||
|
||||
public BufferClearingNode(FBO fbo, int clearingMask) {
|
||||
public BufferClearingNode(String nodeUri, Context context, FBO fbo, int clearingMask) {
|
||||
super(nodeUri, context);
|
||||
|
||||
boolean argumentsAreValid = validateArguments(fbo, clearingMask);
|
||||
|
||||
if (argumentsAreValid) {
|
||||
|
|
|
@ -83,7 +83,9 @@ public class DeferredMainLightNode extends AbstractNode {
|
|||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private Vector3f mainLightInViewSpace = new Vector3f();
|
||||
|
||||
public DeferredMainLightNode(Context context) {
|
||||
public DeferredMainLightNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
renderingConfig = context.get(Config.class).getRendering();
|
||||
worldProvider = context.get(WorldProvider.class);
|
||||
|
|
|
@ -83,7 +83,9 @@ public class DeferredPointLightsNode extends AbstractNode {
|
|||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private Vector3f activeCameraToLightSpace = new Vector3f();
|
||||
|
||||
public DeferredPointLightsNode(Context context) {
|
||||
public DeferredPointLightsNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
renderingConfig = context.get(Config.class).getRendering();
|
||||
worldProvider = context.get(WorldProvider.class);
|
||||
entityManager = context.get(EntityManager.class);
|
||||
|
|
|
@ -40,9 +40,10 @@ public class DownSamplerForExposureNode extends DownSamplerNode {
|
|||
public static final FBOConfig FBO_2X2_CONFIG = new FBOConfig(new SimpleUri("engine:fbo.2x2px"), 2, 2, FBO.Type.DEFAULT);
|
||||
public static final FBOConfig FBO_1X1_CONFIG = new FBOConfig(new SimpleUri("engine:fbo.1x1px"), 1, 1, FBO.Type.DEFAULT);
|
||||
|
||||
public DownSamplerForExposureNode(Context context, FBOConfig inputFboConfig, BaseFBOsManager inputFboManager,
|
||||
public DownSamplerForExposureNode(String nodeUri, Context context,
|
||||
FBOConfig inputFboConfig, BaseFBOsManager inputFboManager,
|
||||
FBOConfig outputFboConfig, BaseFBOsManager outputFboManager) {
|
||||
super(context, inputFboConfig, inputFboManager, outputFboConfig, outputFboManager);
|
||||
super(nodeUri, context, inputFboConfig, inputFboManager, outputFboConfig, outputFboManager);
|
||||
|
||||
RenderingConfig renderingConfig = context.get(Config.class).getRendering();
|
||||
requiresCondition(renderingConfig::isEyeAdaptation);
|
||||
|
|
|
@ -50,9 +50,10 @@ public class DownSamplerNode extends ConditionDependentNode {
|
|||
* @param outputFboConfig an FBOConfig instance describing the output FBO, to be retrieved from the FBO manager
|
||||
* @param outputFboManager the FBO manager from which to retrieve the output FBO
|
||||
*/
|
||||
public DownSamplerNode(Context context, FBOConfig inputFboConfig, BaseFBOsManager inputFboManager,
|
||||
public DownSamplerNode(String nodeUri, Context context,
|
||||
FBOConfig inputFboConfig, BaseFBOsManager inputFboManager,
|
||||
FBOConfig outputFboConfig, BaseFBOsManager outputFboManager) {
|
||||
super(context);
|
||||
super(nodeUri, context);
|
||||
|
||||
FBO inputFbo = requiresFBO(inputFboConfig, inputFboManager);
|
||||
outputFbo = requiresFBO(outputFboConfig, outputFboManager);
|
||||
|
|
|
@ -87,7 +87,9 @@ public class FinalPostProcessingNode extends AbstractNode implements PropertyCha
|
|||
|
||||
private final int noiseTextureSize = 1024;
|
||||
|
||||
public FinalPostProcessingNode(Context context) {
|
||||
public FinalPostProcessingNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
activeCamera = worldRenderer.getActiveCamera();
|
||||
screenGrabber = context.get(ScreenGrabber.class);
|
||||
|
|
|
@ -45,8 +45,8 @@ public class HazeNode extends BlurNode {
|
|||
* @param inputFbo The input fbo, containing the image to be blurred.
|
||||
* @param outputFbo The output fbo, to store the blurred image.
|
||||
*/
|
||||
public HazeNode(Context context, FBO inputFbo, FBO outputFbo) {
|
||||
super(context, inputFbo, outputFbo, BLUR_RADIUS);
|
||||
public HazeNode(String nodeUri, Context context, FBO inputFbo, FBO outputFbo) {
|
||||
super(nodeUri, context, inputFbo, outputFbo, BLUR_RADIUS);
|
||||
|
||||
renderingConfig = context.get(Config.class).getRendering();
|
||||
requiresCondition(renderingConfig::isInscattering);
|
||||
|
|
|
@ -51,8 +51,8 @@ public class HighPassNode extends ConditionDependentNode {
|
|||
|
||||
private Material highPass;
|
||||
|
||||
public HighPassNode(Context context) {
|
||||
super(context);
|
||||
public HighPassNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
RenderingConfig renderingConfig = context.get(Config.class).getRendering();
|
||||
renderingConfig.subscribe(RenderingConfig.BLOOM, this);
|
||||
|
|
|
@ -78,7 +78,9 @@ public class InitialPostProcessingNode extends AbstractNode implements PropertyC
|
|||
@Range(min = 0.0f, max = 1.0f)
|
||||
private float bloomFactor = 0.5f;
|
||||
|
||||
public InitialPostProcessingNode(Context context) {
|
||||
public InitialPostProcessingNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
worldProvider = context.get(WorldProvider.class);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
|
|
|
@ -52,8 +52,8 @@ public class LateBlurNode extends BlurNode implements PropertyChangeListener {
|
|||
* @param inputFbo The input fbo, containing the image to be blurred.
|
||||
* @param outputFbo The output fbo, to store the blurred image.
|
||||
*/
|
||||
public LateBlurNode(Context context, FBO inputFbo, FBO outputFbo) {
|
||||
super(context, inputFbo, outputFbo, 0); // note: blurRadius is 0.0 at this stage.
|
||||
public LateBlurNode(String nodeUri, Context context, FBO inputFbo, FBO outputFbo) {
|
||||
super(nodeUri, context, inputFbo, outputFbo, 0); // note: blurRadius is 0.0 at this stage.
|
||||
|
||||
renderingConfig = context.get(Config.class).getRendering();
|
||||
requiresCondition(() -> renderingConfig.getBlurIntensity() != 0); // getBlurIntensity > 0 implies blur is enabled.
|
||||
|
|
|
@ -81,8 +81,8 @@ public class LightShaftsNode extends ConditionDependentNode {
|
|||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private Vector4f sunPositionScreenSpace = new Vector4f();
|
||||
|
||||
public LightShaftsNode(Context context) {
|
||||
super(context);
|
||||
public LightShaftsNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
activeCamera = context.get(WorldRenderer.class).getActiveCamera();
|
||||
|
|
|
@ -83,7 +83,9 @@ public class OpaqueBlocksNode extends AbstractNode implements WireframeCapable,
|
|||
@Range(min = 0.0f, max = 0.50f)
|
||||
private float parallaxScale = 0.05f;
|
||||
|
||||
public OpaqueBlocksNode(Context context) {
|
||||
public OpaqueBlocksNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
renderQueues = context.get(RenderQueuesHelper.class);
|
||||
worldProvider = context.get(WorldProvider.class);
|
||||
|
||||
|
|
|
@ -46,7 +46,9 @@ public class OpaqueObjectsNode extends AbstractNode implements WireframeCapable
|
|||
private SetWireframe wireframeStateChange;
|
||||
private EnableFaceCulling faceCullingStateChange;
|
||||
|
||||
public OpaqueObjectsNode(Context context) {
|
||||
public OpaqueObjectsNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
componentSystemManager = context.get(ComponentSystemManager.class);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
|
|
|
@ -63,8 +63,8 @@ public class OutlineNode extends ConditionDependentNode {
|
|||
@Range(min = 0.0f, max = 16.0f)
|
||||
private float pixelOffsetY = 1.0f;
|
||||
|
||||
public OutlineNode(Context context) {
|
||||
super(context);
|
||||
public OutlineNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
activeCamera = worldRenderer.getActiveCamera();
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ public class OutputToHMDNode extends ConditionDependentNode {
|
|||
* Constructs an instance of this node. Specifically, initialize the vrProvider and pass the frame buffer
|
||||
* information for the vrProvider to use.
|
||||
*/
|
||||
public OutputToHMDNode(Context context) {
|
||||
super(context);
|
||||
public OutputToHMDNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
vrProvider = context.get(OpenVRProvider.class);
|
||||
requiresCondition(() -> (context.get(Config.class).getRendering().isVrSupport() && vrProvider.isInitialized()));
|
||||
|
|
|
@ -45,8 +45,8 @@ public class OutputToScreenNode extends ConditionDependentNode {
|
|||
|
||||
private StateChange bindFbo;
|
||||
|
||||
public OutputToScreenNode(Context context) {
|
||||
super(context);
|
||||
public OutputToScreenNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
displayResolutionDependentFBOs = context.get(DisplayResolutionDependentFBOs.class);
|
||||
|
||||
|
|
|
@ -47,7 +47,9 @@ public class OverlaysNode extends AbstractNode implements WireframeCapable {
|
|||
|
||||
private SetWireframe wireframeStateChange;
|
||||
|
||||
public OverlaysNode(Context context) {
|
||||
public OverlaysNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
componentSystemManager = context.get(ComponentSystemManager.class);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
|
|
|
@ -104,7 +104,9 @@ public class PrePostCompositeNode extends AbstractNode implements PropertyChange
|
|||
@Range(min = -0.1f, max = 0.1f)
|
||||
private float volumetricFogHeightFalloff = -0.01f;
|
||||
|
||||
public PrePostCompositeNode(Context context) {
|
||||
public PrePostCompositeNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
worldRenderer = context.get(WorldRenderer.class);
|
||||
activeCamera = worldRenderer.getActiveCamera();
|
||||
|
||||
|
|
|
@ -148,7 +148,9 @@ public class RefractiveReflectiveBlocksNode extends AbstractNode implements Prop
|
|||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private Vector3f sunDirection;
|
||||
|
||||
public RefractiveReflectiveBlocksNode(Context context) {
|
||||
public RefractiveReflectiveBlocksNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
renderQueues = context.get(RenderQueuesHelper.class);
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
worldProvider = context.get(WorldProvider.class);
|
||||
|
|
|
@ -73,8 +73,8 @@ public class ShadowMapNode extends ConditionDependentNode implements PropertyCha
|
|||
private SubmersibleCamera activeCamera;
|
||||
private float texelSize;
|
||||
|
||||
public ShadowMapNode(Context context) {
|
||||
super(context);
|
||||
public ShadowMapNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
renderQueues = context.get(RenderQueuesHelper.class);
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
|
|
|
@ -50,7 +50,9 @@ import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
|
|||
public class SimpleBlendMaterialsNode extends AbstractNode {
|
||||
private ComponentSystemManager componentSystemManager;
|
||||
|
||||
public SimpleBlendMaterialsNode(Context context) {
|
||||
public SimpleBlendMaterialsNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
componentSystemManager = context.get(ComponentSystemManager.class);
|
||||
|
||||
Camera playerCamera = context.get(WorldRenderer.class).getActiveCamera();
|
||||
|
|
|
@ -60,7 +60,9 @@ public class ToneMappingNode extends AbstractNode {
|
|||
@Range(min = 0.0f, max = 100.0f)
|
||||
private float whitePoint = 9f;
|
||||
|
||||
public ToneMappingNode(Context context) {
|
||||
public ToneMappingNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
screenGrabber = context.get(ScreenGrabber.class);
|
||||
|
||||
DisplayResolutionDependentFBOs displayResolutionDependentFBOs = context.get(DisplayResolutionDependentFBOs.class);
|
||||
|
|
|
@ -74,7 +74,9 @@ public class UpdateExposureNode extends AbstractNode {
|
|||
private PBO writeOnlyPbo; // PBOs are 1x1 pixels buffers used to read GPU data back into the CPU.
|
||||
// This data is then used in the context of eye adaptation.
|
||||
|
||||
public UpdateExposureNode(Context context) {
|
||||
public UpdateExposureNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
screenGrabber = context.get(ScreenGrabber.class);
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ public class WorldReflectionNode extends ConditionDependentNode {
|
|||
*
|
||||
* This method also requests the material using the "chunk" shaders (vertex, fragment) to be enabled.
|
||||
*/
|
||||
public WorldReflectionNode(Context context) {
|
||||
super(context);
|
||||
public WorldReflectionNode(String nodeUri, Context context) {
|
||||
super(nodeUri, context);
|
||||
|
||||
renderQueues = context.get(RenderQueuesHelper.class);
|
||||
backdropProvider = context.get(BackdropProvider.class);
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2018 MovingBlocks
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@API
|
||||
package org.terasology.rendering.dag.nodes;
|
||||
|
||||
import org.terasology.module.sandbox.API;
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2018 MovingBlocks
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@API
|
||||
package org.terasology.rendering.dag;
|
||||
|
||||
import org.terasology.module.sandbox.API;
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2018 MovingBlocks
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@API
|
||||
package org.terasology.rendering.dag.stateChanges;
|
||||
|
||||
import org.terasology.module.sandbox.API;
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2018 MovingBlocks
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@API
|
||||
package org.terasology.rendering.opengl.fbms;
|
||||
|
||||
import org.terasology.module.sandbox.API;
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2018 MovingBlocks
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@API
|
||||
package org.terasology.rendering.opengl;
|
||||
|
||||
import org.terasology.module.sandbox.API;
|
|
@ -17,9 +17,11 @@ package org.terasology.rendering.world;
|
|||
|
||||
import org.terasology.math.geom.Vector3f;
|
||||
import org.terasology.math.geom.Vector3i;
|
||||
import org.terasology.module.sandbox.API;
|
||||
import org.terasology.rendering.assets.material.Material;
|
||||
import org.terasology.rendering.cameras.Camera;
|
||||
import org.terasology.rendering.cameras.SubmersibleCamera;
|
||||
import org.terasology.rendering.dag.RenderGraph;
|
||||
import org.terasology.rendering.world.viewDistance.ViewDistance;
|
||||
|
||||
/**
|
||||
|
@ -33,6 +35,7 @@ import org.terasology.rendering.world.viewDistance.ViewDistance;
|
|||
* If this is the first time you look into this interface, you might want to start with
|
||||
* the update and render methods as they are central to a rendering implementation.
|
||||
*/
|
||||
@API
|
||||
public interface WorldRenderer {
|
||||
float BLOCK_LIGHT_POW = 0.96f;
|
||||
float BLOCK_LIGHT_SUN_POW = 0.96f;
|
||||
|
@ -218,4 +221,18 @@ public interface WorldRenderer {
|
|||
*/
|
||||
// TODO: transform this to return an object or a map. Consumers would then take care of formatting.
|
||||
String getMetrics();
|
||||
|
||||
/***
|
||||
* Returns the RenderGraph.
|
||||
*
|
||||
* This object is used by Engine and Modules to add/remove Nodes to/from the rendering process.
|
||||
*
|
||||
* Nodes encapsulate the rendering functionality of the renderer. A node might provide a basic rendering
|
||||
* of the landscape, another might add deferred lighting to it while another might add tone mapping
|
||||
* to the resulting 2d image. Arbitrary features and effects can be added or removed by adding or removing
|
||||
* nodes to the graph and connecting them appropriately with other nodes.
|
||||
*
|
||||
* @return the RenderGraph containing the nodes used by the rendering process.
|
||||
*/
|
||||
RenderGraph getRenderGraph();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.terasology.rendering.world;
|
||||
|
||||
import java.util.List;
|
||||
import org.terasology.config.Config;
|
||||
import org.terasology.config.RenderingConfig;
|
||||
import org.terasology.context.Context;
|
||||
|
@ -22,7 +23,6 @@ import org.terasology.engine.SimpleUri;
|
|||
import org.terasology.engine.subsystem.DisplayDevice;
|
||||
import org.terasology.engine.subsystem.lwjgl.GLBufferPool;
|
||||
import org.terasology.engine.subsystem.lwjgl.LwjglGraphics;
|
||||
import org.terasology.entitySystem.systems.RegisterSystem;
|
||||
import org.terasology.logic.console.Console;
|
||||
import org.terasology.logic.console.commandSystem.MethodCommand;
|
||||
import org.terasology.logic.console.commandSystem.annotations.Command;
|
||||
|
@ -86,9 +86,6 @@ import org.terasology.rendering.world.viewDistance.ViewDistance;
|
|||
import org.terasology.utilities.Assets;
|
||||
import org.terasology.world.WorldProvider;
|
||||
import org.terasology.world.chunks.ChunkProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
|
@ -119,14 +116,13 @@ import static org.terasology.rendering.opengl.ScalingFactors.QUARTER_SCALE;
|
|||
* TODO: update this section to include new, relevant objects
|
||||
* - a RenderableWorld instance, providing acceleration structures caching blocks requiring different rendering treatments<br/>
|
||||
*/
|
||||
@RegisterSystem
|
||||
public final class WorldRendererImpl implements WorldRenderer {
|
||||
/*
|
||||
* Presumably, the eye height should be context.get(Config.class).getPlayer().getEyeHeight() above the ground plane.
|
||||
* It's not, so for now, we use this factor to adjust for the disparity.
|
||||
*/
|
||||
private static final float GROUND_PLANE_HEIGHT_DISPARITY = -0.7f;
|
||||
private static RenderGraph renderGraph = new RenderGraph(); // TODO: Try making this non-static
|
||||
private RenderGraph renderGraph = new RenderGraph();
|
||||
|
||||
private boolean isFirstRenderingStageForCurrentFrame;
|
||||
private final RenderQueuesHelper renderQueues;
|
||||
|
@ -267,35 +263,34 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
addOutputNodes(renderGraph);
|
||||
|
||||
renderTaskListGenerator = new RenderTaskListGenerator();
|
||||
List<Node> orderedNodes = renderGraph.getNodesInTopologicalOrder();
|
||||
renderPipelineTaskList = renderTaskListGenerator.generateFrom(orderedNodes);
|
||||
requestTaskListRefresh();
|
||||
}
|
||||
|
||||
private void addGBufferClearingNodes(RenderGraph renderGraph) {
|
||||
SwappableFBO gBufferPair = displayResolutionDependentFBOs.getGBufferPair();
|
||||
|
||||
BufferClearingNode lastUpdatedGBufferClearingNode = new BufferClearingNode(gBufferPair.getLastUpdatedFbo(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
renderGraph.addNode(lastUpdatedGBufferClearingNode, "lastUpdatedGBufferClearingNode");
|
||||
BufferClearingNode lastUpdatedGBufferClearingNode = new BufferClearingNode("lastUpdatedGBufferClearingNode", context, gBufferPair.getLastUpdatedFbo(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
renderGraph.addNode(lastUpdatedGBufferClearingNode);
|
||||
|
||||
BufferClearingNode staleGBufferClearingNode = new BufferClearingNode(gBufferPair.getStaleFbo(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
renderGraph.addNode(staleGBufferClearingNode, "staleGBufferClearingNode");
|
||||
BufferClearingNode staleGBufferClearingNode = new BufferClearingNode("staleGBufferClearingNode", context, gBufferPair.getStaleFbo(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
renderGraph.addNode(staleGBufferClearingNode);
|
||||
}
|
||||
|
||||
private void addSkyNodes(RenderGraph renderGraph) {
|
||||
Node backdropNode = new BackdropNode(context);
|
||||
renderGraph.addNode(backdropNode, "backdropNode");
|
||||
Node backdropNode = new BackdropNode("backdropNode", context);
|
||||
renderGraph.addNode(backdropNode);
|
||||
|
||||
FBOConfig intermediateHazeConfig = new FBOConfig(HazeNode.INTERMEDIATE_HAZE_FBO_URI, ONE_16TH_SCALE, FBO.Type.DEFAULT);
|
||||
FBO intermediateHazeFbo = displayResolutionDependentFBOs.request(intermediateHazeConfig);
|
||||
|
||||
HazeNode intermediateHazeNode = new HazeNode(context, displayResolutionDependentFBOs.getGBufferPair().getLastUpdatedFbo(), intermediateHazeFbo);
|
||||
renderGraph.addNode(intermediateHazeNode, "intermediateHazeNode");
|
||||
HazeNode intermediateHazeNode = new HazeNode("intermediateHazeNode", context, displayResolutionDependentFBOs.getGBufferPair().getLastUpdatedFbo(), intermediateHazeFbo);
|
||||
renderGraph.addNode(intermediateHazeNode);
|
||||
|
||||
FBOConfig finalHazeConfig = new FBOConfig(HazeNode.FINAL_HAZE_FBO_URI, ONE_32TH_SCALE, FBO.Type.DEFAULT);
|
||||
FBO finalHazeFbo = displayResolutionDependentFBOs.request(finalHazeConfig);
|
||||
|
||||
HazeNode finalHazeNode = new HazeNode(context, intermediateHazeFbo, finalHazeFbo);
|
||||
renderGraph.addNode(finalHazeNode, "finalHazeNode");
|
||||
HazeNode finalHazeNode = new HazeNode("finalHazeNode", context, intermediateHazeFbo, finalHazeFbo);
|
||||
renderGraph.addNode(finalHazeNode);
|
||||
|
||||
Node lastUpdatedGBufferClearingNode = renderGraph.findNode("engine:lastUpdatedGBufferClearingNode");
|
||||
renderGraph.connect(lastUpdatedGBufferClearingNode, backdropNode, intermediateHazeNode, finalHazeNode);
|
||||
|
@ -313,20 +308,20 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
the haze-related nodes together. */
|
||||
Node finalHazeNode = renderGraph.findNode("engine:finalHazeNode");
|
||||
|
||||
Node opaqueObjectsNode = new OpaqueObjectsNode(context);
|
||||
renderGraph.addNode(opaqueObjectsNode, "opaqueObjectsNode");
|
||||
Node opaqueObjectsNode = new OpaqueObjectsNode("opaqueObjectsNode", context);
|
||||
renderGraph.addNode(opaqueObjectsNode);
|
||||
renderGraph.connect(finalHazeNode, opaqueObjectsNode);
|
||||
|
||||
Node opaqueBlocksNode = new OpaqueBlocksNode(context);
|
||||
renderGraph.addNode(opaqueBlocksNode, "opaqueBlocksNode");
|
||||
Node opaqueBlocksNode = new OpaqueBlocksNode("opaqueBlocksNode", context);
|
||||
renderGraph.addNode(opaqueBlocksNode);
|
||||
renderGraph.connect(finalHazeNode, opaqueBlocksNode);
|
||||
|
||||
Node alphaRejectBlocksNode = new AlphaRejectBlocksNode(context);
|
||||
renderGraph.addNode(alphaRejectBlocksNode, "alphaRejectBlocksNode");
|
||||
Node alphaRejectBlocksNode = new AlphaRejectBlocksNode("alphaRejectBlocksNode", context);
|
||||
renderGraph.addNode(alphaRejectBlocksNode);
|
||||
renderGraph.connect(finalHazeNode, alphaRejectBlocksNode);
|
||||
|
||||
Node overlaysNode = new OverlaysNode(context);
|
||||
renderGraph.addNode(overlaysNode, "overlaysNode");
|
||||
Node overlaysNode = new OverlaysNode("overlaysNode", context);
|
||||
renderGraph.addNode(overlaysNode);
|
||||
renderGraph.connect(finalHazeNode, overlaysNode);
|
||||
}
|
||||
|
||||
|
@ -338,29 +333,29 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
Node staleGBufferClearingNode = renderGraph.findNode("engine:staleGBufferClearingNode");
|
||||
|
||||
FBOConfig shadowMapConfig = new FBOConfig(ShadowMapNode.SHADOW_MAP_FBO_URI, FBO.Type.NO_COLOR).useDepthBuffer();
|
||||
BufferClearingNode shadowMapClearingNode = new BufferClearingNode(shadowMapConfig, shadowMapResolutionDependentFBOs, GL_DEPTH_BUFFER_BIT);
|
||||
renderGraph.addNode(shadowMapClearingNode, "shadowMapClearingNode");
|
||||
BufferClearingNode shadowMapClearingNode = new BufferClearingNode("shadowMapClearingNode", context, shadowMapConfig, shadowMapResolutionDependentFBOs, GL_DEPTH_BUFFER_BIT);
|
||||
renderGraph.addNode(shadowMapClearingNode);
|
||||
|
||||
shadowMapNode = new ShadowMapNode(context);
|
||||
renderGraph.addNode(shadowMapNode, "shadowMapNode");
|
||||
shadowMapNode = new ShadowMapNode("shadowMapNode", context);
|
||||
renderGraph.addNode(shadowMapNode);
|
||||
renderGraph.connect(shadowMapClearingNode, shadowMapNode);
|
||||
|
||||
Node deferredPointLightsNode = new DeferredPointLightsNode(context);
|
||||
renderGraph.addNode(deferredPointLightsNode, "deferredPointLightsNode");
|
||||
Node deferredPointLightsNode = new DeferredPointLightsNode("deferredPointLightsNode", context);
|
||||
renderGraph.addNode(deferredPointLightsNode);
|
||||
renderGraph.connect(opaqueObjectsNode, deferredPointLightsNode);
|
||||
renderGraph.connect(opaqueBlocksNode, deferredPointLightsNode);
|
||||
renderGraph.connect(alphaRejectBlocksNode, deferredPointLightsNode);
|
||||
|
||||
Node deferredMainLightNode = new DeferredMainLightNode(context);
|
||||
renderGraph.addNode(deferredMainLightNode, "deferredMainLightNode");
|
||||
Node deferredMainLightNode = new DeferredMainLightNode("deferredMainLightNode", context);
|
||||
renderGraph.addNode(deferredMainLightNode);
|
||||
renderGraph.connect(shadowMapNode, deferredMainLightNode);
|
||||
renderGraph.connect(opaqueObjectsNode, deferredMainLightNode);
|
||||
renderGraph.connect(opaqueBlocksNode, deferredMainLightNode);
|
||||
renderGraph.connect(alphaRejectBlocksNode, deferredMainLightNode);
|
||||
renderGraph.connect(deferredPointLightsNode, deferredMainLightNode);
|
||||
|
||||
Node applyDeferredLightingNode = new ApplyDeferredLightingNode(context);
|
||||
renderGraph.addNode(applyDeferredLightingNode, "applyDeferredLightingNode");
|
||||
Node applyDeferredLightingNode = new ApplyDeferredLightingNode("applyDeferredLightingNode", context);
|
||||
renderGraph.addNode(applyDeferredLightingNode);
|
||||
renderGraph.connect(deferredMainLightNode, applyDeferredLightingNode);
|
||||
renderGraph.connect(deferredPointLightsNode, applyDeferredLightingNode);
|
||||
renderGraph.connect(lastUpdatedGBufferClearingNode, applyDeferredLightingNode);
|
||||
|
@ -373,44 +368,44 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
Node alphaRejectBlocksNode = renderGraph.findNode("engine:alphaRejectBlocksNode");
|
||||
Node applyDeferredLightingNode = renderGraph.findNode("engine:applyDeferredLightingNode");
|
||||
|
||||
Node outlineNode = new OutlineNode(context);
|
||||
renderGraph.addNode(outlineNode, "outlineNode");
|
||||
Node outlineNode = new OutlineNode("outlineNode", context);
|
||||
renderGraph.addNode(outlineNode);
|
||||
renderGraph.connect(opaqueObjectsNode, outlineNode);
|
||||
renderGraph.connect(opaqueBlocksNode, outlineNode);
|
||||
renderGraph.connect(alphaRejectBlocksNode, outlineNode);
|
||||
|
||||
Node ambientOcclusionNode = new AmbientOcclusionNode(context);
|
||||
renderGraph.addNode(ambientOcclusionNode, "ambientOcclusionNode");
|
||||
Node ambientOcclusionNode = new AmbientOcclusionNode("ambientOcclusionNode", context);
|
||||
renderGraph.addNode(ambientOcclusionNode);
|
||||
renderGraph.connect(opaqueObjectsNode, ambientOcclusionNode);
|
||||
renderGraph.connect(opaqueBlocksNode, ambientOcclusionNode);
|
||||
renderGraph.connect(alphaRejectBlocksNode, ambientOcclusionNode);
|
||||
// TODO: At this stage, it is unclear -why- this connection is required, we just know that it's required. Investigate.
|
||||
renderGraph.connect(applyDeferredLightingNode, ambientOcclusionNode);
|
||||
|
||||
Node blurredAmbientOcclusionNode = new BlurredAmbientOcclusionNode(context);
|
||||
renderGraph.addNode(blurredAmbientOcclusionNode, "blurredAmbientOcclusionNode");
|
||||
Node blurredAmbientOcclusionNode = new BlurredAmbientOcclusionNode("blurredAmbientOcclusionNode", context);
|
||||
renderGraph.addNode(blurredAmbientOcclusionNode);
|
||||
renderGraph.connect(ambientOcclusionNode, blurredAmbientOcclusionNode);
|
||||
}
|
||||
|
||||
private void addReflectionAndRefractionNodes(RenderGraph renderGraph) {
|
||||
FBOConfig reflectedBufferConfig = new FBOConfig(BackdropReflectionNode.REFLECTED_FBO_URI, HALF_SCALE, FBO.Type.DEFAULT).useDepthBuffer();
|
||||
BufferClearingNode reflectedBufferClearingNode = new BufferClearingNode(reflectedBufferConfig, displayResolutionDependentFBOs, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
renderGraph.addNode(reflectedBufferClearingNode, "reflectedBufferClearingNode");
|
||||
BufferClearingNode reflectedBufferClearingNode = new BufferClearingNode("reflectedBufferClearingNode", context, reflectedBufferConfig, displayResolutionDependentFBOs, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
renderGraph.addNode(reflectedBufferClearingNode);
|
||||
|
||||
Node reflectedBackdropNode = new BackdropReflectionNode(context);
|
||||
renderGraph.addNode(reflectedBackdropNode, "reflectedBackdropNode");
|
||||
Node reflectedBackdropNode = new BackdropReflectionNode("reflectedBackdropNode", context);
|
||||
renderGraph.addNode(reflectedBackdropNode);
|
||||
|
||||
Node worldReflectionNode = new WorldReflectionNode(context);
|
||||
renderGraph.addNode(worldReflectionNode, "worldReflectionNode");
|
||||
Node worldReflectionNode = new WorldReflectionNode("worldReflectionNode", context);
|
||||
renderGraph.addNode(worldReflectionNode);
|
||||
|
||||
renderGraph.connect(reflectedBufferClearingNode, reflectedBackdropNode, worldReflectionNode);
|
||||
|
||||
FBOConfig reflectedRefractedBufferConfig = new FBOConfig(RefractiveReflectiveBlocksNode.REFRACTIVE_REFLECTIVE_FBO_URI, FULL_SCALE, FBO.Type.HDR).useNormalBuffer();
|
||||
BufferClearingNode reflectedRefractedBufferClearingNode = new BufferClearingNode(reflectedRefractedBufferConfig, displayResolutionDependentFBOs, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
renderGraph.addNode(reflectedRefractedBufferClearingNode, "reflectedRefractedBufferClearingNode");
|
||||
BufferClearingNode reflectedRefractedBufferClearingNode = new BufferClearingNode("reflectedRefractedBufferClearingNode", context, reflectedRefractedBufferConfig, displayResolutionDependentFBOs, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
renderGraph.addNode(reflectedRefractedBufferClearingNode);
|
||||
|
||||
Node chunksRefractiveReflectiveNode = new RefractiveReflectiveBlocksNode(context);
|
||||
renderGraph.addNode(chunksRefractiveReflectiveNode, "chunksRefractiveReflectiveNode");
|
||||
Node chunksRefractiveReflectiveNode = new RefractiveReflectiveBlocksNode("chunksRefractiveReflectiveNode", context);
|
||||
renderGraph.addNode(chunksRefractiveReflectiveNode);
|
||||
|
||||
Node applyDeferredLightingNode = renderGraph.findNode("engine:applyDeferredLightingNode");
|
||||
renderGraph.connect(reflectedRefractedBufferClearingNode, chunksRefractiveReflectiveNode);
|
||||
|
@ -431,8 +426,8 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
Node outlineNode = renderGraph.findNode("engine:outlineNode");
|
||||
Node blurredAmbientOcclusionNode = renderGraph.findNode("engine:blurredAmbientOcclusionNode");
|
||||
|
||||
Node prePostCompositeNode = new PrePostCompositeNode(context);
|
||||
renderGraph.addNode(prePostCompositeNode, "prePostCompositeNode");
|
||||
Node prePostCompositeNode = new PrePostCompositeNode("prePostCompositeNode", context);
|
||||
renderGraph.addNode(prePostCompositeNode);
|
||||
renderGraph.connect(overlaysNode, prePostCompositeNode);
|
||||
renderGraph.connect(finalHazeNode, prePostCompositeNode);
|
||||
renderGraph.connect(chunksRefractiveReflectiveNode, prePostCompositeNode);
|
||||
|
@ -440,34 +435,34 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
renderGraph.connect(outlineNode, prePostCompositeNode);
|
||||
renderGraph.connect(blurredAmbientOcclusionNode, prePostCompositeNode);
|
||||
|
||||
Node simpleBlendMaterialsNode = new SimpleBlendMaterialsNode(context);
|
||||
renderGraph.addNode(simpleBlendMaterialsNode, "simpleBlendMaterialsNode");
|
||||
Node simpleBlendMaterialsNode = new SimpleBlendMaterialsNode("simpleBlendMaterialsNode", context);
|
||||
renderGraph.addNode(simpleBlendMaterialsNode);
|
||||
renderGraph.connect(prePostCompositeNode, simpleBlendMaterialsNode);
|
||||
}
|
||||
|
||||
private void addBloomNodes(RenderGraph renderGraph) {
|
||||
// Bloom Effect: one high-pass filter and three blur passes
|
||||
|
||||
Node highPassNode = new HighPassNode(context);
|
||||
renderGraph.addNode(highPassNode, "highPassNode");
|
||||
Node highPassNode = new HighPassNode("highPassNode", context);
|
||||
renderGraph.addNode(highPassNode);
|
||||
|
||||
FBOConfig halfScaleBloomConfig = new FBOConfig(BloomBlurNode.HALF_SCALE_FBO_URI, HALF_SCALE, FBO.Type.DEFAULT);
|
||||
FBO halfScaleBloomFbo = displayResolutionDependentFBOs.request(halfScaleBloomConfig);
|
||||
|
||||
BloomBlurNode halfScaleBlurredBloomNode = new BloomBlurNode(context, displayResolutionDependentFBOs.get(HighPassNode.HIGH_PASS_FBO_URI), halfScaleBloomFbo);
|
||||
renderGraph.addNode(halfScaleBlurredBloomNode, "halfScaleBlurredBloomNode");
|
||||
BloomBlurNode halfScaleBlurredBloomNode = new BloomBlurNode("halfScaleBlurredBloomNode", context, displayResolutionDependentFBOs.get(HighPassNode.HIGH_PASS_FBO_URI), halfScaleBloomFbo);
|
||||
renderGraph.addNode(halfScaleBlurredBloomNode);
|
||||
|
||||
FBOConfig quarterScaleBloomConfig = new FBOConfig(BloomBlurNode.QUARTER_SCALE_FBO_URI, QUARTER_SCALE, FBO.Type.DEFAULT);
|
||||
FBO quarterScaleBloomFbo = displayResolutionDependentFBOs.request(quarterScaleBloomConfig);
|
||||
|
||||
BloomBlurNode quarterScaleBlurredBloomNode = new BloomBlurNode(context, halfScaleBloomFbo, quarterScaleBloomFbo);
|
||||
renderGraph.addNode(quarterScaleBlurredBloomNode, "quarterScaleBlurredBloomNode");
|
||||
BloomBlurNode quarterScaleBlurredBloomNode = new BloomBlurNode("quarterScaleBlurredBloomNode", context, halfScaleBloomFbo, quarterScaleBloomFbo);
|
||||
renderGraph.addNode(quarterScaleBlurredBloomNode);
|
||||
|
||||
FBOConfig one8thScaleBloomConfig = new FBOConfig(BloomBlurNode.ONE_8TH_SCALE_FBO_URI, ONE_8TH_SCALE, FBO.Type.DEFAULT);
|
||||
FBO one8thScaleBloomFbo = displayResolutionDependentFBOs.request(one8thScaleBloomConfig);
|
||||
|
||||
BloomBlurNode one8thScaleBlurredBloomNode = new BloomBlurNode(context, quarterScaleBloomFbo, one8thScaleBloomFbo);
|
||||
renderGraph.addNode(one8thScaleBlurredBloomNode, "one8thScaleBlurredBloomNode");
|
||||
BloomBlurNode one8thScaleBlurredBloomNode = new BloomBlurNode("one8thScaleBlurredBloomNode", context, quarterScaleBloomFbo, one8thScaleBloomFbo);
|
||||
renderGraph.addNode(one8thScaleBlurredBloomNode);
|
||||
|
||||
Node simpleBlendMaterialsNode = renderGraph.findNode("engine:simpleBlendMaterialsNode");
|
||||
renderGraph.connect(simpleBlendMaterialsNode, highPassNode, halfScaleBlurredBloomNode,
|
||||
|
@ -476,23 +471,23 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
|
||||
private void addExposureNodes(RenderGraph renderGraph) {
|
||||
FBOConfig gBuffer2Config = displayResolutionDependentFBOs.getFboConfig(new SimpleUri("engine:fbo.gBuffer2")); // TODO: Remove the hard coded value here
|
||||
DownSamplerForExposureNode exposureDownSamplerTo16pixels = new DownSamplerForExposureNode(context, gBuffer2Config, displayResolutionDependentFBOs, FBO_16X16_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo16pixels, "exposureDownSamplerTo16pixels");
|
||||
DownSamplerForExposureNode exposureDownSamplerTo16pixels = new DownSamplerForExposureNode("exposureDownSamplerTo16pixels", context, gBuffer2Config, displayResolutionDependentFBOs, FBO_16X16_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo16pixels);
|
||||
|
||||
DownSamplerForExposureNode exposureDownSamplerTo8pixels = new DownSamplerForExposureNode(context, FBO_16X16_CONFIG, immutableFBOs, FBO_8X8_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo8pixels, "exposureDownSamplerTo8pixels");
|
||||
DownSamplerForExposureNode exposureDownSamplerTo8pixels = new DownSamplerForExposureNode("exposureDownSamplerTo8pixels", context, FBO_16X16_CONFIG, immutableFBOs, FBO_8X8_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo8pixels);
|
||||
|
||||
DownSamplerForExposureNode exposureDownSamplerTo4pixels = new DownSamplerForExposureNode(context, FBO_8X8_CONFIG, immutableFBOs, FBO_4X4_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo4pixels, "exposureDownSamplerTo4pixels");
|
||||
DownSamplerForExposureNode exposureDownSamplerTo4pixels = new DownSamplerForExposureNode("exposureDownSamplerTo4pixels", context, FBO_8X8_CONFIG, immutableFBOs, FBO_4X4_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo4pixels);
|
||||
|
||||
DownSamplerForExposureNode exposureDownSamplerTo2pixels = new DownSamplerForExposureNode(context, FBO_4X4_CONFIG, immutableFBOs, FBO_2X2_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo2pixels, "exposureDownSamplerTo2pixels");
|
||||
DownSamplerForExposureNode exposureDownSamplerTo2pixels = new DownSamplerForExposureNode("exposureDownSamplerTo2pixels", context, FBO_4X4_CONFIG, immutableFBOs, FBO_2X2_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo2pixels);
|
||||
|
||||
DownSamplerForExposureNode exposureDownSamplerTo1pixel = new DownSamplerForExposureNode(context, FBO_2X2_CONFIG, immutableFBOs, FBO_1X1_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo1pixel, "exposureDownSamplerTo1pixel");
|
||||
DownSamplerForExposureNode exposureDownSamplerTo1pixel = new DownSamplerForExposureNode("exposureDownSamplerTo1pixel", context, FBO_2X2_CONFIG, immutableFBOs, FBO_1X1_CONFIG, immutableFBOs);
|
||||
renderGraph.addNode(exposureDownSamplerTo1pixel);
|
||||
|
||||
Node updateExposureNode = new UpdateExposureNode(context);
|
||||
renderGraph.addNode(updateExposureNode, "updateExposureNode");
|
||||
Node updateExposureNode = new UpdateExposureNode("updateExposureNode", context);
|
||||
renderGraph.addNode(updateExposureNode);
|
||||
|
||||
Node simpleBlendMaterialsNode = renderGraph.findNode("engine:simpleBlendMaterialsNode");
|
||||
renderGraph.connect(simpleBlendMaterialsNode, exposureDownSamplerTo16pixels, exposureDownSamplerTo8pixels,
|
||||
|
@ -505,13 +500,13 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
Node one8thScaleBlurredBloomNode = renderGraph.findNode("engine:one8thScaleBlurredBloomNode");
|
||||
|
||||
// Light shafts
|
||||
Node lightShaftsNode = new LightShaftsNode(context);
|
||||
renderGraph.addNode(lightShaftsNode, "lightShaftsNode");
|
||||
Node lightShaftsNode = new LightShaftsNode("lightShaftsNode", context);
|
||||
renderGraph.addNode(lightShaftsNode);
|
||||
renderGraph.connect(simpleBlendMaterialsNode, lightShaftsNode);
|
||||
|
||||
// Adding the bloom and light shafts to the gBuffer
|
||||
Node initialPostProcessingNode = new InitialPostProcessingNode(context);
|
||||
renderGraph.addNode(initialPostProcessingNode, "initialPostProcessingNode");
|
||||
Node initialPostProcessingNode = new InitialPostProcessingNode("initialPostProcessingNode", context);
|
||||
renderGraph.addNode(initialPostProcessingNode);
|
||||
renderGraph.connect(lightShaftsNode, initialPostProcessingNode);
|
||||
renderGraph.connect(one8thScaleBlurredBloomNode, initialPostProcessingNode);
|
||||
}
|
||||
|
@ -520,8 +515,8 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
Node initialPostProcessingNode = renderGraph.findNode("engine:initialPostProcessingNode");
|
||||
Node updateExposureNode = renderGraph.findNode("engine:updateExposureNode");
|
||||
|
||||
Node toneMappingNode = new ToneMappingNode(context);
|
||||
renderGraph.addNode(toneMappingNode, "toneMappingNode");
|
||||
Node toneMappingNode = new ToneMappingNode("toneMappingNode", context);
|
||||
renderGraph.addNode(toneMappingNode);
|
||||
renderGraph.connect(updateExposureNode, toneMappingNode);
|
||||
renderGraph.connect(initialPostProcessingNode, toneMappingNode);
|
||||
|
||||
|
@ -529,17 +524,17 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
FBOConfig firstLateBlurConfig = new FBOConfig(FIRST_LATE_BLUR_FBO_URI, HALF_SCALE, FBO.Type.DEFAULT);
|
||||
FBO firstLateBlurFbo = displayResolutionDependentFBOs.request(firstLateBlurConfig);
|
||||
|
||||
LateBlurNode firstLateBlurNode = new LateBlurNode(context, displayResolutionDependentFBOs.get(ToneMappingNode.TONE_MAPPING_FBO_URI), firstLateBlurFbo);
|
||||
renderGraph.addNode(firstLateBlurNode, "firstLateBlurNode");
|
||||
LateBlurNode firstLateBlurNode = new LateBlurNode("firstLateBlurNode", context, displayResolutionDependentFBOs.get(ToneMappingNode.TONE_MAPPING_FBO_URI), firstLateBlurFbo);
|
||||
renderGraph.addNode(firstLateBlurNode);
|
||||
|
||||
FBOConfig secondLateBlurConfig = new FBOConfig(SECOND_LATE_BLUR_FBO_URI, HALF_SCALE, FBO.Type.DEFAULT);
|
||||
FBO secondLateBlurFbo = displayResolutionDependentFBOs.request(secondLateBlurConfig);
|
||||
|
||||
LateBlurNode secondLateBlurNode = new LateBlurNode(context, firstLateBlurFbo, secondLateBlurFbo);
|
||||
renderGraph.addNode(secondLateBlurNode, "secondLateBlurNode");
|
||||
LateBlurNode secondLateBlurNode = new LateBlurNode("secondLateBlurNode", context, firstLateBlurFbo, secondLateBlurFbo);
|
||||
renderGraph.addNode(secondLateBlurNode);
|
||||
|
||||
Node finalPostProcessingNode = new FinalPostProcessingNode(context);
|
||||
renderGraph.addNode(finalPostProcessingNode, "finalPostProcessingNode");
|
||||
Node finalPostProcessingNode = new FinalPostProcessingNode("finalPostProcessingNode", context);
|
||||
renderGraph.addNode(finalPostProcessingNode);
|
||||
|
||||
renderGraph.connect(toneMappingNode, firstLateBlurNode, secondLateBlurNode, finalPostProcessingNode);
|
||||
}
|
||||
|
@ -547,12 +542,12 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
private void addOutputNodes(RenderGraph renderGraph) {
|
||||
Node finalPostProcessingNode = renderGraph.findNode("engine:finalPostProcessingNode");
|
||||
|
||||
Node outputToVRFrameBufferNode = new OutputToHMDNode(context);
|
||||
renderGraph.addNode(outputToVRFrameBufferNode, "outputToVRFrameBufferNode");
|
||||
Node outputToVRFrameBufferNode = new OutputToHMDNode("outputToVRFrameBufferNode", context);
|
||||
renderGraph.addNode(outputToVRFrameBufferNode);
|
||||
renderGraph.connect(finalPostProcessingNode, outputToVRFrameBufferNode);
|
||||
|
||||
Node outputToScreenNode = new OutputToScreenNode(context);
|
||||
renderGraph.addNode(outputToScreenNode, "outputToScreenNode");
|
||||
Node outputToScreenNode = new OutputToScreenNode("outputToScreenNode", context);
|
||||
renderGraph.addNode(outputToScreenNode);
|
||||
renderGraph.connect(finalPostProcessingNode, outputToScreenNode);
|
||||
}
|
||||
|
||||
|
@ -638,7 +633,8 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
renderableWorld.queueVisibleChunks(isFirstRenderingStageForCurrentFrame);
|
||||
|
||||
if (requestedTaskListRefresh) {
|
||||
renderTaskListGenerator.refresh();
|
||||
List<Node> orderedNodes = renderGraph.getNodesInTopologicalOrder();
|
||||
renderPipelineTaskList = renderTaskListGenerator.generateFrom(orderedNodes);
|
||||
requestedTaskListRefresh = false;
|
||||
}
|
||||
}
|
||||
|
@ -777,6 +773,11 @@ public final class WorldRendererImpl implements WorldRenderer {
|
|||
return currentRenderingStage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderGraph getRenderGraph() {
|
||||
return renderGraph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a recompilation of all shaders. This command, backed by Gestalt's monitoring feature,
|
||||
* allows developers to hot-swap shaders for easy development.
|
||||
|
|
Loading…
Reference in New Issue