|
|
@ -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--) { |
|
|
|
List<Integer> injectIndices = node.getDependencyInjectIndices(); |
|
|
|
// Must insert them backwards ..
|
|
|
|
for (int i = resolvedShaderNodes.size() - 1; i >= 0; i--) { |
|
|
|
sb.insert(injectIndices.get(i), resolvedShaderNodes.get(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; |
|
|
|
} |
|
|
|
} |
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|