ShaderNodes : generated shaders are now cached by the assetManager to avoid generating a new shader for already loaded materials. This saves memory and avoids a lot of shader switches at render time.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10575 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
77a3cba69e
commit
4f3319f049
@ -448,6 +448,8 @@ public class J3MLoader implements AssetLoader {
|
||||
|
||||
if(isUseNodes){
|
||||
nodesLoaderDelegate.computeConditions();
|
||||
//used for caching later, the shader here is not a file.
|
||||
technique.setShaderFile(technique.hashCode() + "", technique.hashCode() + "", "GLSL100", "GLSL100");
|
||||
}
|
||||
|
||||
if (vertName != null && fragName != null){
|
||||
|
@ -398,16 +398,23 @@ public class DesktopAssetManager implements AssetManager {
|
||||
AssetCache cache = handler.getCache(SimpleAssetCache.class);
|
||||
Shader shader = (Shader) cache.getFromCache(key);
|
||||
if (shader == null){
|
||||
String vertName = key.getVertName();
|
||||
String fragName = key.getFragName();
|
||||
if (key.isUsesShaderNodes()) {
|
||||
if(shaderGenerator == null){
|
||||
throw new UnsupportedOperationException("ShaderGenerator was not initialized, make sure assetManager.getGenerator(caps) has been called");
|
||||
}
|
||||
shader = shaderGenerator.generateShader();
|
||||
} else {
|
||||
String vertName = key.getVertName();
|
||||
String fragName = key.getFragName();
|
||||
|
||||
String vertSource = (String) loadAsset(new AssetKey(vertName));
|
||||
String fragSource = (String) loadAsset(new AssetKey(fragName));
|
||||
String vertSource = (String) loadAsset(new AssetKey(vertName));
|
||||
String fragSource = (String) loadAsset(new AssetKey(fragName));
|
||||
|
||||
shader = new Shader();
|
||||
shader.initialize();
|
||||
shader.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled(), key.getVertexShaderLanguage());
|
||||
shader.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled(), key.getFragmentShaderLanguage());
|
||||
shader = new Shader();
|
||||
shader.initialize();
|
||||
shader.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled(), key.getVertexShaderLanguage());
|
||||
shader.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled(), key.getFragmentShaderLanguage());
|
||||
}
|
||||
|
||||
cache.addToCache(key, shader);
|
||||
}
|
||||
|
@ -204,17 +204,18 @@ public class Technique /* implements Savable */ {
|
||||
|
||||
private void loadShader(AssetManager manager,EnumSet<Caps> rendererCaps) {
|
||||
|
||||
if (getDef().isUsingShaderNodes()) {
|
||||
shader = manager.getShaderGenerator(rendererCaps).generateShader(this);
|
||||
} else {
|
||||
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
|
||||
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
|
||||
def.getFragmentShaderName(),
|
||||
getAllDefines(),
|
||||
def.getVertexShaderLanguage(),
|
||||
def.getFragmentShaderLanguage());
|
||||
shader = manager.loadShader(key);
|
||||
|
||||
}
|
||||
if (getDef().isUsingShaderNodes()) {
|
||||
manager.getShaderGenerator(rendererCaps).initialize(this);
|
||||
key.setUsesShaderNodes(true);
|
||||
}
|
||||
shader = manager.loadShader(key);
|
||||
|
||||
// register the world bound uniforms
|
||||
worldBindUniforms.clear();
|
||||
if (def.getWorldBindings() != null) {
|
||||
|
@ -52,6 +52,8 @@ public abstract class ShaderGenerator {
|
||||
protected AssetManager assetManager;
|
||||
//indentation value for generation
|
||||
protected int indent;
|
||||
//the technique to use for the shader generation
|
||||
protected Technique technique = null;
|
||||
|
||||
/**
|
||||
* Build a shaderGenerator
|
||||
@ -59,16 +61,23 @@ public abstract class ShaderGenerator {
|
||||
* @param assetManager
|
||||
*/
|
||||
protected ShaderGenerator(AssetManager assetManager) {
|
||||
this.assetManager = assetManager;
|
||||
this.assetManager = assetManager;
|
||||
}
|
||||
|
||||
|
||||
public void initialize(Technique technique){
|
||||
this.technique = technique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate vertex and fragment shaders for the given technique
|
||||
*
|
||||
* @param technique the technique to use to generate the shaders
|
||||
* @return a Shader program
|
||||
*/
|
||||
public Shader generateShader(Technique technique) {
|
||||
public Shader generateShader() {
|
||||
if(technique == null){
|
||||
throw new UnsupportedOperationException("The shaderGenerator was not properly initialized, call initialize(Technique) before any generation");
|
||||
}
|
||||
|
||||
DefineList defines = technique.getAllDefines();
|
||||
TechniqueDef def = technique.getDef();
|
||||
@ -81,7 +90,8 @@ public abstract class ShaderGenerator {
|
||||
shader.initialize();
|
||||
shader.addSource(Shader.ShaderType.Vertex, technique.getDef().getName() + ".vert", vertexSource, defines.getCompiled(), getLanguageAndVersion(ShaderType.Vertex));
|
||||
shader.addSource(Shader.ShaderType.Fragment, technique.getDef().getName() + ".frag", fragmentSource, defines.getCompiled(), getLanguageAndVersion(ShaderType.Fragment));
|
||||
|
||||
|
||||
technique = null;
|
||||
return shader;
|
||||
}
|
||||
|
||||
@ -286,5 +296,5 @@ public abstract class ShaderGenerator {
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
protected String vertLanguage;
|
||||
protected String fragLanguage;
|
||||
protected int cachedHashedCode = 0;
|
||||
protected boolean usesShaderNodes = false;
|
||||
|
||||
public ShaderKey(){
|
||||
}
|
||||
@ -56,7 +57,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
this.vertLanguage = vertLanguage;
|
||||
this.fragLanguage = fragLanguage;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ShaderKey clone() {
|
||||
ShaderKey clone = (ShaderKey) super.clone();
|
||||
@ -125,6 +126,14 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
return fragLanguage;
|
||||
}
|
||||
|
||||
public boolean isUsesShaderNodes() {
|
||||
return usesShaderNodes;
|
||||
}
|
||||
|
||||
public void setUsesShaderNodes(boolean usesShaderNodes) {
|
||||
this.usesShaderNodes = usesShaderNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException{
|
||||
super.write(ex);
|
||||
|
Loading…
x
Reference in New Issue
Block a user