De duplicate imports when generating a shader from shader nodes
This commit is contained in:
parent
eb6ce4d4b4
commit
171007693b
@ -31,14 +31,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.shader;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.asset.AssetKey;
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.ShaderGenerationInfo;
|
import com.jme3.material.ShaderGenerationInfo;
|
||||||
import com.jme3.material.Technique;
|
|
||||||
import com.jme3.material.TechniqueDef;
|
import com.jme3.material.TechniqueDef;
|
||||||
import com.jme3.shader.Shader.ShaderType;
|
import com.jme3.shader.Shader.ShaderType;
|
||||||
import java.util.List;
|
import com.jme3.shader.plugins.ShaderAssetKey;
|
||||||
import java.util.regex.*;
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the base for a shader generator using the ShaderNodes system,
|
* This class is the base for a shader generator using the ShaderNodes system,
|
||||||
@ -66,6 +67,8 @@ public abstract class ShaderGenerator {
|
|||||||
*/
|
*/
|
||||||
Pattern extensions = Pattern.compile("(#extension.*\\s+)");
|
Pattern extensions = Pattern.compile("(#extension.*\\s+)");
|
||||||
|
|
||||||
|
private Map<String, String> imports = new LinkedHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a shaderGenerator
|
* Build a shaderGenerator
|
||||||
*
|
*
|
||||||
@ -127,6 +130,8 @@ public abstract class ShaderGenerator {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imports.clear();
|
||||||
|
|
||||||
indent = 0;
|
indent = 0;
|
||||||
|
|
||||||
StringBuilder sourceDeclaration = new StringBuilder();
|
StringBuilder sourceDeclaration = new StringBuilder();
|
||||||
@ -145,6 +150,12 @@ public abstract class ShaderGenerator {
|
|||||||
|
|
||||||
generateEndOfMainSection(source, info, type);
|
generateEndOfMainSection(source, info, type);
|
||||||
|
|
||||||
|
//insert imports backward
|
||||||
|
int insertIndex = sourceDeclaration.length();
|
||||||
|
for (String importSource : imports.values()) {
|
||||||
|
sourceDeclaration.insert(insertIndex, importSource);
|
||||||
|
}
|
||||||
|
|
||||||
sourceDeclaration.append(source);
|
sourceDeclaration.append(source);
|
||||||
|
|
||||||
return moveExtensionsUp(sourceDeclaration);
|
return moveExtensionsUp(sourceDeclaration);
|
||||||
@ -186,7 +197,13 @@ public abstract class ShaderGenerator {
|
|||||||
if (shaderNode.getDefinition().getType() == type) {
|
if (shaderNode.getDefinition().getType() == type) {
|
||||||
int index = findShaderIndexFromVersion(shaderNode, type);
|
int index = findShaderIndexFromVersion(shaderNode, type);
|
||||||
String shaderPath = shaderNode.getDefinition().getShadersPath().get(index);
|
String shaderPath = shaderNode.getDefinition().getShadersPath().get(index);
|
||||||
String loadedSource = (String) assetManager.loadAsset(new AssetKey(shaderPath));
|
Map<String, String> sources = (Map<String, String>) assetManager.loadAsset(new ShaderAssetKey(shaderPath, false));
|
||||||
|
String loadedSource = sources.get("[main]");
|
||||||
|
for (String name : sources.keySet()) {
|
||||||
|
if (!name.equals("[main]")) {
|
||||||
|
imports.put(name, sources.get(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
appendNodeDeclarationAndMain(loadedSource, sourceDeclaration, source, shaderNode, info, shaderPath);
|
appendNodeDeclarationAndMain(loadedSource, sourceDeclaration, source, shaderNode, info, shaderPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,7 @@ package com.jme3.shader.plugins;
|
|||||||
import com.jme3.asset.*;
|
import com.jme3.asset.*;
|
||||||
import com.jme3.asset.cache.AssetCache;
|
import com.jme3.asset.cache.AssetCache;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,7 +145,7 @@ public class GLSLLoader implements AssetLoader {
|
|||||||
throw new IOException("Circular dependency.");
|
throw new IOException("Circular dependency.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveDependencies(ShaderDependencyNode node, Set<ShaderDependencyNode> alreadyInjectedSet, StringBuilder extensions) {
|
private String resolveDependencies(ShaderDependencyNode node, Set<ShaderDependencyNode> alreadyInjectedSet, StringBuilder extensions, boolean injectDependencies) {
|
||||||
if (alreadyInjectedSet.contains(node)) {
|
if (alreadyInjectedSet.contains(node)) {
|
||||||
return "// " + node.getName() + " was already injected at the top.\n";
|
return "// " + node.getName() + " was already injected at the top.\n";
|
||||||
} else {
|
} else {
|
||||||
@ -160,18 +157,27 @@ public class GLSLLoader implements AssetLoader {
|
|||||||
if (node.getDependencies().isEmpty()) {
|
if (node.getDependencies().isEmpty()) {
|
||||||
return node.getSource();
|
return node.getSource();
|
||||||
} else {
|
} else {
|
||||||
StringBuilder sb = new StringBuilder(node.getSource());
|
if (injectDependencies) {
|
||||||
List<String> resolvedShaderNodes = new ArrayList<>();
|
StringBuilder sb = new StringBuilder(node.getSource());
|
||||||
|
List<String> resolvedShaderNodes = new ArrayList<>();
|
||||||
|
|
||||||
for (ShaderDependencyNode dependencyNode : node.getDependencies()) {
|
for (ShaderDependencyNode dependencyNode : node.getDependencies()) {
|
||||||
resolvedShaderNodes.add(resolveDependencies(dependencyNode, alreadyInjectedSet, extensions));
|
resolvedShaderNodes.add(resolveDependencies(dependencyNode, alreadyInjectedSet, extensions, injectDependencies));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> injectIndices = node.getDependencyInjectIndices();
|
||||||
|
for (int i = resolvedShaderNodes.size() - 1; i >= 0; i--) {
|
||||||
|
// Must insert them backwards ..
|
||||||
|
sb.insert(injectIndices.get(i), resolvedShaderNodes.get(i));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
} else {
|
||||||
|
for (ShaderDependencyNode dependencyNode : node.getDependencies()) {
|
||||||
|
resolveDependencies(dependencyNode, alreadyInjectedSet, extensions, injectDependencies);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
List<Integer> injectIndices = node.getDependencyInjectIndices();
|
|
||||||
for (int i = resolvedShaderNodes.size() - 1; i >= 0; i--) {
|
|
||||||
// Must insert them backwards ..
|
|
||||||
sb.insert(injectIndices.get(i), resolvedShaderNodes.get(i));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +187,10 @@ public class GLSLLoader implements AssetLoader {
|
|||||||
// to retrieve the fragment shader, use the content manager
|
// to retrieve the fragment shader, use the content manager
|
||||||
this.assetManager = info.getManager();
|
this.assetManager = info.getManager();
|
||||||
Reader reader = new InputStreamReader(info.openStream());
|
Reader reader = new InputStreamReader(info.openStream());
|
||||||
|
boolean injectDependencies = true;
|
||||||
|
if (info.getKey() instanceof ShaderAssetKey) {
|
||||||
|
injectDependencies = ((ShaderAssetKey) info.getKey()).isInjectDependencies();
|
||||||
|
}
|
||||||
if (info.getKey().getExtension().equals("glsllib")) {
|
if (info.getKey().getExtension().equals("glsllib")) {
|
||||||
// NOTE: Loopback, GLSLLIB is loaded by this loader
|
// NOTE: Loopback, GLSLLIB is loaded by this loader
|
||||||
// and needs data as InputStream
|
// and needs data as InputStream
|
||||||
@ -188,10 +198,25 @@ public class GLSLLoader implements AssetLoader {
|
|||||||
} else {
|
} else {
|
||||||
ShaderDependencyNode rootNode = loadNode(reader, "[main]");
|
ShaderDependencyNode rootNode = loadNode(reader, "[main]");
|
||||||
StringBuilder extensions = new StringBuilder();
|
StringBuilder extensions = new StringBuilder();
|
||||||
String code = resolveDependencies(rootNode, new HashSet<ShaderDependencyNode>(), extensions);
|
if (injectDependencies) {
|
||||||
extensions.append(code);
|
String code = resolveDependencies(rootNode, new HashSet<ShaderDependencyNode>(), extensions, injectDependencies);
|
||||||
dependCache.clear();
|
extensions.append(code);
|
||||||
return extensions.toString();
|
dependCache.clear();
|
||||||
|
return extensions.toString();
|
||||||
|
} else {
|
||||||
|
Map<String, String> files = new LinkedHashMap<>();
|
||||||
|
HashSet<ShaderDependencyNode> dependencies = new HashSet<>();
|
||||||
|
String code = resolveDependencies(rootNode, dependencies, extensions, injectDependencies);
|
||||||
|
extensions.append(code);
|
||||||
|
files.put("[main]", extensions.toString());
|
||||||
|
|
||||||
|
for (ShaderDependencyNode dependency : dependencies) {
|
||||||
|
files.put(dependency.getName(), dependency.getSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
dependCache.clear();
|
||||||
|
return files;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.jme3.shader.plugins;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Nehon on 28/10/2017.
|
||||||
|
*/
|
||||||
|
public class ShaderAssetKey extends AssetKey {
|
||||||
|
|
||||||
|
private boolean injectDependencies = false;
|
||||||
|
|
||||||
|
public ShaderAssetKey(String name, boolean injectDependencies) {
|
||||||
|
super(name);
|
||||||
|
this.injectDependencies = injectDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInjectDependencies() {
|
||||||
|
return injectDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInjectDependencies(boolean injectDependencies) {
|
||||||
|
this.injectDependencies = injectDependencies;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user