Refactoring of the shader system to allow addition of new shaderstages

experimental
michael 10 years ago
parent ab4d665b3e
commit 0d3292c83a
  1. 1
      jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java
  2. 6
      jme3-core/src/main/java/com/jme3/material/Technique.java
  3. 123
      jme3-core/src/main/java/com/jme3/material/TechniqueDef.java
  4. 65
      jme3-core/src/main/java/com/jme3/shader/ShaderKey.java
  5. 136
      jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java
  6. 7
      jme3-core/src/tools/java/jme3tools/shadercheck/ShaderCheck.java

@ -402,6 +402,7 @@ public class DesktopAssetManager implements AssetManager {
}
shader = shaderGenerator.generateShader();
} else {
String vertName = key.getVertName();
String fragName = key.getFragName();

@ -190,11 +190,7 @@ public class Technique /* implements Savable */ {
private void loadShader(AssetManager manager,EnumSet<Caps> rendererCaps) {
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
def.getFragmentShaderName(),
getAllDefines(),
def.getVertexShaderLanguage(),
def.getFragmentShaderLanguage());
ShaderKey key = new ShaderKey(getAllDefines(),def.getShaderProgramLanguages(),def.getShaderProgramNames());
if (getDef().isUsingShaderNodes()) {
manager.getShaderGenerator(rendererCaps).initialize(this);

@ -34,15 +34,10 @@ package com.jme3.material;
import com.jme3.export.*;
import com.jme3.renderer.Caps;
import com.jme3.renderer.Renderer;
import com.jme3.shader.DefineList;
import com.jme3.shader.ShaderNode;
import com.jme3.shader.UniformBinding;
import com.jme3.shader.VarType;
import com.jme3.shader.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.*;
/**
* Describes a technique definition.
@ -55,7 +50,9 @@ public class TechniqueDef implements Savable {
* Version #1: Separate shader language for each shader source.
*/
public static final int SAVABLE_VERSION = 1;
/**
* Describes light rendering mode.
*/
@ -100,10 +97,8 @@ public class TechniqueDef implements Savable {
private EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class);
private String name;
private String vertName;
private String fragName;
private String vertLanguage;
private String fragLanguage;
private EnumMap<Shader.ShaderType,String> shaderLanguage;
private EnumMap<Shader.ShaderType,String> shaderName;
private DefineList presetDefines;
private boolean usesShaders;
@ -129,6 +124,7 @@ public class TechniqueDef implements Savable {
* for default techniques.
*/
public TechniqueDef(String name){
this();
this.name = name == null ? "Default" : name;
}
@ -136,6 +132,8 @@ public class TechniqueDef implements Savable {
* Serialization only. Do not use.
*/
public TechniqueDef(){
shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
}
/**
@ -244,11 +242,10 @@ public class TechniqueDef implements Savable {
* @param fragLanguage The fragment shader language
*/
public void setShaderFile(String vertexShader, String fragmentShader, String vertLanguage, String fragLanguage){
this.vertName = vertexShader;
this.fragName = fragmentShader;
this.vertLanguage = vertLanguage;
this.fragLanguage = fragLanguage;
this.shaderLanguage.put(Shader.ShaderType.Vertex,shaderLanguage.get(vertLanguage));
this.shaderName.put(Shader.ShaderType.Vertex,shaderName.get(vertexShader));
this.shaderLanguage.put(Shader.ShaderType.Fragment,shaderLanguage.get(fragLanguage));
this.shaderName.put(Shader.ShaderType.Fragment,shaderName.get(fragmentShader));
Caps vertCap = Caps.valueOf(vertLanguage);
requiredCaps.add(vertCap);
Caps fragCap = Caps.valueOf(fragLanguage);
@ -257,6 +254,26 @@ public class TechniqueDef implements Savable {
usesShaders = true;
}
/**
* Sets the shaders that this technique definition will use.
*
* @param shaderName EnumMap containing all shader names for this stage
* @param shaderLanguage EnumMap containing all shader languages for this stage
*/
public void setShaderFile(EnumMap<Shader.ShaderType, String> shaderName, EnumMap<Shader.ShaderType, String> shaderLanguage) {
for (Shader.ShaderType shaderType : shaderName.keySet()) {
this.shaderLanguage.put(shaderType,shaderLanguage.get(shaderType));
this.shaderName.put(shaderType,shaderName.get(shaderType));
if(shaderType.equals(Shader.ShaderType.Geometry)){
requiredCaps.add(Caps.GeometryShader);
}else if(shaderType.equals(Shader.ShaderType.TesselationControl)){
requiredCaps.add(Caps.TesselationShader);
}
}
usesShaders=true;
}
/**
* Returns the define name which the given material parameter influences.
*
@ -329,7 +346,7 @@ public class TechniqueDef implements Savable {
* @return the name of the fragment shader to be used.
*/
public String getFragmentShaderName() {
return fragName;
return shaderName.get(Shader.ShaderType.Fragment);
}
@ -340,7 +357,7 @@ public class TechniqueDef implements Savable {
* @return the name of the vertex shader to be used.
*/
public String getVertexShaderName() {
return vertName;
return shaderName.get(Shader.ShaderType.Vertex);
}
/**
@ -348,21 +365,34 @@ public class TechniqueDef implements Savable {
*/
@Deprecated
public String getShaderLanguage() {
return vertLanguage;
return shaderLanguage.get(Shader.ShaderType.Vertex);
}
/**
* Returns the language of the fragment shader used in this technique.
*/
public String getFragmentShaderLanguage() {
return fragLanguage;
return shaderLanguage.get(Shader.ShaderType.Fragment);
}
/**
* Returns the language of the vertex shader used in this technique.
*/
public String getVertexShaderLanguage() {
return vertLanguage;
return shaderLanguage.get(Shader.ShaderType.Vertex);
}
/**Returns the language for each shader program
* @param shaderType
*/
public String getShaderProgramLanguage(Shader.ShaderType shaderType){
return shaderLanguage.get(shaderType);
}
/**Returns the name for each shader program
* @param shaderType
*/
public String getShaderProgramName(Shader.ShaderType shaderType){
return shaderName.get(shaderType);
}
/**
@ -406,10 +436,18 @@ public class TechniqueDef implements Savable {
public void write(JmeExporter ex) throws IOException{
OutputCapsule oc = ex.getCapsule(this);
oc.write(name, "name", null);
oc.write(vertName, "vertName", null);
oc.write(fragName, "fragName", null);
oc.write(vertLanguage, "vertLanguage", null);
oc.write(vertLanguage, "fragLanguage", null);
oc.write(shaderName.get(Shader.ShaderType.Vertex), "vertName", null);
oc.write(shaderName.get(Shader.ShaderType.Fragment), "fragName", null);
oc.write(shaderName.get(Shader.ShaderType.Geometry), "geomName", null);
oc.write(shaderName.get(Shader.ShaderType.TesselationControl), "tsctrlName", null);
oc.write(shaderName.get(Shader.ShaderType.TesselationEvaluation), "tsevalName", null);
oc.write(shaderLanguage.get(Shader.ShaderType.Vertex), "vertLanguage", null);
oc.write(shaderLanguage.get(Shader.ShaderType.Fragment), "fragLanguage", null);
oc.write(shaderLanguage.get(Shader.ShaderType.Geometry), "geomLanguage", null);
oc.write(shaderLanguage.get(Shader.ShaderType.TesselationControl), "tsctrlLanguage", null);
oc.write(shaderLanguage.get(Shader.ShaderType.TesselationEvaluation), "tsevalLanguage", null);
oc.write(presetDefines, "presetDefines", null);
oc.write(lightMode, "lightMode", LightMode.Disable);
oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
@ -428,8 +466,11 @@ public class TechniqueDef implements Savable {
public void read(JmeImporter im) throws IOException{
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", null);
vertName = ic.readString("vertName", null);
fragName = ic.readString("fragName", null);
shaderName.put(Shader.ShaderType.Vertex,ic.readString("vertName", null));
shaderName.put(Shader.ShaderType.Fragment,ic.readString("fragName", null));
shaderName.put(Shader.ShaderType.Geometry,ic.readString("geomName", null));
shaderName.put(Shader.ShaderType.TesselationControl,ic.readString("tsctrlName", null));
shaderName.put(Shader.ShaderType.TesselationEvaluation,ic.readString("tsevalName", null));
presetDefines = (DefineList) ic.readSavable("presetDefines", null);
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
@ -438,12 +479,15 @@ public class TechniqueDef implements Savable {
if (ic.getSavableVersion(TechniqueDef.class) == 0) {
// Old version
vertLanguage = ic.readString("shaderLang", null);
fragLanguage = vertLanguage;
shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null));
shaderLanguage.put(Shader.ShaderType.Fragment,shaderLanguage.get(Shader.ShaderType.Vertex));
} else {
// New version
vertLanguage = ic.readString("vertLanguage", null);
fragLanguage = ic.readString("fragLanguage", null);;
shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("vertLanguage", null));
shaderLanguage.put(Shader.ShaderType.Fragment,ic.readString("fragLanguage", null));
shaderLanguage.put(Shader.ShaderType.Geometry,ic.readString("geomLanguage", null));
shaderLanguage.put(Shader.ShaderType.TesselationControl,ic.readString("tsctrlLanguage", null));
shaderLanguage.put(Shader.ShaderType.TesselationEvaluation,ic.readString("tsevalLanguage", null));
}
usesNodes = ic.readBoolean("usesNodes", false);
@ -461,6 +505,16 @@ public class TechniqueDef implements Savable {
usesShaders = true;
}
//todo: add javadoc
public EnumMap<Shader.ShaderType, String> getShaderProgramNames() {
return shaderName;
}
//todo: add javadoc
public EnumMap<Shader.ShaderType, String> getShaderProgramLanguages() {
return shaderLanguage;
}
public ShaderGenerationInfo getShaderGenerationInfo() {
return shaderGenerationInfo;
}
@ -469,8 +523,9 @@ public class TechniqueDef implements Savable {
this.shaderGenerationInfo = shaderGenerationInfo;
}
//todo: make toString return something usefull
@Override
public String toString() {
return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name + ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage + ", presetDefines=" + presetDefines + ", usesShaders=" + usesShaders + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}';
return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name /*+ ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage */+ ", presetDefines=" + presetDefines + ", usesShaders=" + usesShaders + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}';
}
}

@ -37,25 +37,30 @@ import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import java.io.IOException;
import java.util.EnumMap;
public class ShaderKey extends AssetKey<Shader> {
protected String fragName;
protected EnumMap<Shader.ShaderType,String> shaderLanguage;
protected EnumMap<Shader.ShaderType,String> shaderName;
protected DefineList defines;
protected String vertLanguage;
protected String fragLanguage;
protected int cachedHashedCode = 0;
protected boolean usesShaderNodes = false;
public ShaderKey(){
shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
}
public ShaderKey(String vertName, String fragName, DefineList defines, String vertLanguage, String fragLanguage){
super(vertName);
this.fragName = fragName;
public ShaderKey(DefineList defines, EnumMap<Shader.ShaderType,String> shaderLanguage,EnumMap<Shader.ShaderType,String> shaderName){
super(shaderName.get(Shader.ShaderType.Vertex));
this.shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
this.shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
this.defines = defines;
this.vertLanguage = vertLanguage;
this.fragLanguage = fragLanguage;
for (Shader.ShaderType shaderType : shaderName.keySet()) {
this.shaderName.put(shaderType,shaderName.get(shaderType));
this.shaderLanguage.put(shaderType,shaderLanguage.get(shaderType));
}
}
@Override
@ -68,13 +73,15 @@ public class ShaderKey extends AssetKey<Shader> {
@Override
public String toString(){
return "V="+name + " F=" + fragName + (defines != null ? defines : "");
//todo:
return "V="+name+";";
}
//todo: make equals and hashCode work
@Override
public boolean equals(Object obj) {
final ShaderKey other = (ShaderKey) obj;
if (name.equals(other.name) && fragName.equals(other.fragName)){
if (name.equals(other.name) && shaderName.get(Shader.ShaderType.Fragment).equals(other.shaderName.get(Shader.ShaderType.Fragment))){
if (defines != null && other.defines != null) {
return defines.equals(other.defines);
} else if (defines != null || other.defines != null) {
@ -91,7 +98,7 @@ public class ShaderKey extends AssetKey<Shader> {
if (cachedHashedCode == 0) {
int hash = 7;
hash = 41 * hash + name.hashCode();
hash = 41 * hash + fragName.hashCode();
hash = 41 * hash + shaderName.get(Shader.ShaderType.Fragment).hashCode();
hash = 41 * hash + (defines != null ? defines.hashCode() : 0);
cachedHashedCode = hash;
}
@ -103,11 +110,11 @@ public class ShaderKey extends AssetKey<Shader> {
}
public String getVertName(){
return name;
return shaderName.get(Shader.ShaderType.Vertex);
}
public String getFragName() {
return fragName;
return shaderName.get(Shader.ShaderType.Fragment);
}
/**
@ -115,15 +122,15 @@ public class ShaderKey extends AssetKey<Shader> {
*/
@Deprecated
public String getLanguage() {
return vertLanguage;
return shaderLanguage.get(Shader.ShaderType.Vertex);
}
public String getVertexShaderLanguage() {
return vertLanguage;
return shaderLanguage.get(Shader.ShaderType.Vertex);
}
public String getFragmentShaderLanguage() {
return fragLanguage;
return shaderLanguage.get(Shader.ShaderType.Vertex);
}
public boolean isUsesShaderNodes() {
@ -138,18 +145,32 @@ public class ShaderKey extends AssetKey<Shader> {
public void write(JmeExporter ex) throws IOException{
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(fragName, "fragment_name", null);
oc.write(vertLanguage, "language", null);
oc.write(fragLanguage, "frag_language", null);
oc.write(shaderName.get(Shader.ShaderType.Fragment), "fragment_name", null);
oc.write(shaderName.get(Shader.ShaderType.Geometry), "geometry_name", null);
oc.write(shaderName.get(Shader.ShaderType.TesselationControl), "tessControl_name", null);
oc.write(shaderName.get(Shader.ShaderType.TesselationEvaluation), "tessEval_name", null);
oc.write(shaderLanguage.get(Shader.ShaderType.Vertex), "language", null);
oc.write(shaderLanguage.get(Shader.ShaderType.Fragment), "frag_language", null);
oc.write(shaderLanguage.get(Shader.ShaderType.Geometry), "geom_language", null);
oc.write(shaderLanguage.get(Shader.ShaderType.TesselationControl), "tsctrl_language", null);
oc.write(shaderLanguage.get(Shader.ShaderType.TesselationEvaluation), "tseval_language", null);
}
@Override
public void read(JmeImporter im) throws IOException{
super.read(im);
InputCapsule ic = im.getCapsule(this);
fragName = ic.readString("fragment_name", null);
vertLanguage = ic.readString("language", null);
fragLanguage = ic.readString("frag_language", null);
shaderName.put(Shader.ShaderType.Vertex,name);
shaderName.put(Shader.ShaderType.Fragment,ic.readString("fragment_name", null));
shaderName.put(Shader.ShaderType.Geometry,ic.readString("geometry_name", null));
shaderName.put(Shader.ShaderType.TesselationControl,ic.readString("tessControl_name", null));
shaderName.put(Shader.ShaderType.TesselationEvaluation,ic.readString("tessEval_name", null));
shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("language", null));
shaderLanguage.put(Shader.ShaderType.Fragment,ic.readString("frag_language", null));
shaderLanguage.put(Shader.ShaderType.Geometry,ic.readString("geom_language", null));
shaderLanguage.put(Shader.ShaderType.TesselationControl,ic.readString("tsctrl_language", null));
shaderLanguage.put(Shader.ShaderType.TesselationEvaluation,ic.readString("tseval_language", null));
}
}

@ -40,6 +40,7 @@ import com.jme3.material.TechniqueDef.ShadowMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.shader.Shader;
import com.jme3.shader.VarType;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
@ -50,6 +51,7 @@ import com.jme3.util.blockparser.BlockLanguageParser;
import com.jme3.util.blockparser.Statement;
import java.io.IOException;
import java.io.InputStream;
import java.util.EnumMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -60,7 +62,7 @@ public class J3MLoader implements AssetLoader {
// private ErrorLogger errors;
private ShaderNodeLoaderDelegate nodesLoaderDelegate;
boolean isUseNodes = false;
private AssetManager assetManager;
private AssetKey key;
@ -68,16 +70,15 @@ public class J3MLoader implements AssetLoader {
private Material material;
private TechniqueDef technique;
private RenderState renderState;
private String vertLanguage;
private String fragLanguage;
private String vertName;
private String fragName;
private EnumMap<Shader.ShaderType,String> shaderLanguage;
private EnumMap<Shader.ShaderType,String> shaderName;
private static final String whitespacePattern = "\\p{javaWhitespace}+";
public J3MLoader(){
shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
}
@ -91,16 +92,19 @@ public class J3MLoader implements AssetLoader {
if (typeAndLang.length != 2) {
throw new IOException("Shader statement syntax incorrect: " + statement);
}
if (typeAndLang[0].equals("VertexShader")) {
vertName = split[1].trim();
vertLanguage = typeAndLang[1];
} else if (typeAndLang[0].equals("FragmentShader")) {
fragName = split[1].trim();
fragLanguage = typeAndLang[1];
for (Shader.ShaderType shaderType : Shader.ShaderType.values()) {
if(typeAndLang[0].equals(shaderType.toString()+"Shader")){
readShaderDefinition(shaderType,split[1].trim(),typeAndLang[1]);
}
}
}
private void readShaderDefinition(Shader.ShaderType shaderType,String name,String language){
shaderName.put(shaderType,name);
shaderLanguage.put(shaderType,language);
}
// LightMode <MODE>
private void readLightMode(String statement) throws IOException{
String[] split = statement.split(whitespacePattern);
@ -163,14 +167,14 @@ public class J3MLoader implements AssetLoader {
if (tex != null){
if (repeat){
tex.setWrap(WrapMode.Repeat);
}
}
}else{
tex = new Texture2D(PlaceholderAssets.getPlaceholderImage(assetManager));
if (repeat){
tex.setWrap(WrapMode.Repeat);
}
tex.setKey(texKey);
}
}
return tex;
}else{
String[] split = value.trim().split(whitespacePattern);
@ -216,13 +220,13 @@ public class J3MLoader implements AssetLoader {
}
}
}
// <TYPE> <NAME> [ "(" <FFBINDING> ")" ] [ ":" <DEFAULTVAL> ] [-LINEAR]
private void readParam(String statement) throws IOException{
String name;
String defaultVal = null;
ColorSpace colorSpace = null;
String[] split = statement.split("-");
if(split.length>1){
if(split[1].equalsIgnoreCase("LINEAR")){
@ -230,9 +234,9 @@ public class J3MLoader implements AssetLoader {
}
statement = split[0].trim();
}
split = statement.split(":");
// Parse default val
if (split.length == 1){
// Doesn't contain default value
@ -241,9 +245,9 @@ public class J3MLoader implements AssetLoader {
throw new IOException("Parameter statement syntax incorrect");
}
statement = split[0].trim();
defaultVal = split[1].trim();
defaultVal = split[1].trim();
}
// Parse ffbinding
int startParen = statement.indexOf("(");
if (startParen != -1){
@ -253,32 +257,32 @@ public class J3MLoader implements AssetLoader {
// don't care about bindingStr
statement = statement.substring(0, startParen);
}
// Parse type + name
split = statement.split(whitespacePattern);
if (split.length != 2){
throw new IOException("Parameter statement syntax incorrect");
}
VarType type;
if (split[0].equals("Color")){
type = VarType.Vector4;
}else{
type = VarType.valueOf(split[0]);
}
name = split[1];
Object defaultValObj = null;
if (defaultVal != null){
if (defaultVal != null){
defaultValObj = readValue(type, defaultVal);
}
if(type.isTextureType()){
materialDef.addMaterialParamTexture(type, name, colorSpace);
materialDef.addMaterialParamTexture(type, name, colorSpace);
}else{
materialDef.addMaterialParam(type, name, defaultValObj);
}
}
private void readValueParam(String statement) throws IOException{
@ -373,7 +377,7 @@ public class J3MLoader implements AssetLoader {
technique.setRenderState(renderState);
renderState = null;
}
private void readForcedRenderState(List<Statement> renderStates) throws IOException{
renderState = new RenderState();
for (Statement statement : renderStates){
@ -382,7 +386,7 @@ public class J3MLoader implements AssetLoader {
technique.setForcedRenderState(renderState);
renderState = null;
}
// <DEFINENAME> [ ":" <PARAMNAME> ]
private void readDefine(String statement) throws IOException{
String[] split = statement.split(":");
@ -402,9 +406,9 @@ public class J3MLoader implements AssetLoader {
}
}
private void readTechniqueStatement(Statement statement) throws IOException{
String[] split = statement.getLine().split("[ \\{]");
String[] split = statement.getLine().split("[ \\{]");
if (split[0].equals("VertexShader") ||
split[0].equals("FragmentShader")){
readShaderStatement(statement.getLine());
@ -414,12 +418,12 @@ public class J3MLoader implements AssetLoader {
readShadowMode(statement.getLine());
}else if (split[0].equals("WorldParameters")){
readWorldParams(statement.getContents());
}else if (split[0].equals("RenderState")){
}else if (split[0].equals("RenderState")){
readRenderState(statement.getContents());
}else if (split[0].equals("ForcedRenderState")){
}else if (split[0].equals("ForcedRenderState")){
readForcedRenderState(statement.getContents());
}else if (split[0].equals("Defines")){
readDefines(statement.getContents());
}else if (split[0].equals("Defines")){
readDefines(statement.getContents());
} else if (split[0].equals("ShaderNodesDefinitions")) {
initNodesLoader();
if (isUseNodes) {
@ -432,14 +436,14 @@ public class J3MLoader implements AssetLoader {
}
} else if (split[0].equals("FragmentShaderNodes")) {
initNodesLoader();
if (isUseNodes) {
if (isUseNodes) {
nodesLoaderDelegate.readFragmentShaderNodes(statement.getContents());
}
} else {
throw new MatParseException(null, split[0], statement);
}
}
private void readTransparentStatement(String statement) throws IOException{
String[] split = statement.split(whitespacePattern);
if (split.length != 2){
@ -459,30 +463,28 @@ public class J3MLoader implements AssetLoader {
} else {
throw new IOException("Technique statement syntax incorrect");
}
for (Statement statement : techStat.getContents()){
readTechniqueStatement(statement);
}
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){
technique.setShaderFile(vertName, fragName, vertLanguage, fragLanguage);
if(shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)){
technique.setShaderFile(shaderName,shaderLanguage);
}
materialDef.addTechniqueDef(technique);
technique = null;
vertName = null;
fragName = null;
vertLanguage = null;
fragLanguage = null;
shaderLanguage.clear();
shaderName.clear();
}
private void loadFromRoot(List<Statement> roots) throws IOException{
private void loadFromRoot(List<Statement> roots) throws IOException{
if (roots.size() == 2){
Statement exception = roots.get(0);
String line = exception.getLine();
@ -494,7 +496,7 @@ public class J3MLoader implements AssetLoader {
}else if (roots.size() != 1){
throw new IOException("Too many roots in J3M/J3MD file");
}
boolean extending = false;
Statement materialStat = roots.get(0);
String materialName = materialStat.getLine();
@ -507,16 +509,16 @@ public class J3MLoader implements AssetLoader {
}else{
throw new IOException("Specified file is not a Material file");
}
String[] split = materialName.split(":", 2);
if (materialName.equals("")){
throw new MatParseException("Material name cannot be empty", materialStat);
throw new MatParseException("Material name cannot be empty", materialStat);
}
if (split.length == 2){
if (!extending){
throw new MatParseException("Must use 'Material' when extending.", materialStat);
throw new MatParseException("Must use 'Material' when extending.", materialStat);
}
String extendedMat = split[1].trim();
@ -531,15 +533,15 @@ public class J3MLoader implements AssetLoader {
// material.setAssetName(fileName);
}else if (split.length == 1){
if (extending){
throw new MatParseException("Expected ':', got '{'", materialStat);
throw new MatParseException("Expected ':', got '{'", materialStat);
}
materialDef = new MaterialDef(assetManager, materialName);
// NOTE: pass file name for defs so they can be loaded later
materialDef.setAssetName(key.getName());
}else{
throw new MatParseException("Cannot use colon in material name/path", materialStat);
throw new MatParseException("Cannot use colon in material name/path", materialStat);
}
for (Statement statement : materialStat.getContents()){
split = statement.getLine().split("[ \\{]");
String statType = split[0];
@ -557,25 +559,25 @@ public class J3MLoader implements AssetLoader {
}else if (statType.equals("MaterialParameters")){
readMaterialParams(statement.getContents());
}else{
throw new MatParseException("Expected material statement, got '"+statType+"'", statement);
throw new MatParseException("Expected material statement, got '"+statType+"'", statement);
}
}
}
}
public Object load(AssetInfo info) throws IOException {
public Object load(AssetInfo info) throws IOException {
this.assetManager = info.getManager();
InputStream in = info.openStream();
InputStream in = info.openStream();
try {
key = info.getKey();
key = info.getKey();
loadFromRoot(BlockLanguageParser.parse(in));
} finally {
if (in != null){
in.close();
}
}
if (material != null){
if (!(info.getKey() instanceof MaterialKey)){
throw new IOException("Material instances must be loaded via MaterialKey");
@ -587,7 +589,7 @@ public class J3MLoader implements AssetLoader {
return materialDef;
}
}
public MaterialDef loadMaterialDef(List<Statement> roots, AssetManager manager, AssetKey key) throws IOException {
this.key = key;
this.assetManager = manager;
@ -597,8 +599,8 @@ public class J3MLoader implements AssetLoader {
protected void initNodesLoader() {
if (!isUseNodes) {
isUseNodes = fragName == null && vertName == null;
if (isUseNodes) {
isUseNodes = shaderName.get(Shader.ShaderType.Vertex) == null && shaderName.get(Shader.ShaderType.Fragment) == null;
if (isUseNodes) {
if(nodesLoaderDelegate == null){
nodesLoaderDelegate = new ShaderNodeLoaderDelegate();
}else{
@ -609,6 +611,6 @@ public class J3MLoader implements AssetLoader {
nodesLoaderDelegate.setAssetManager(assetManager);
}
}
}
}
}

@ -38,11 +38,8 @@ public class ShaderCheck {
for (TechniqueDef techDef : def.getDefaultTechniques()){
DefineList dl = new DefineList();
dl.addFrom(techDef.getShaderPresetDefines());
ShaderKey shaderKey = new ShaderKey(techDef.getVertexShaderName(),
techDef.getFragmentShaderName(),
dl,
techDef.getVertexShaderLanguage(),
techDef.getFragmentShaderLanguage());
ShaderKey shaderKey = new ShaderKey(dl,techDef.getShaderProgramLanguages(),techDef.getShaderProgramNames());
Shader shader = assetManager.loadShader(shaderKey);
for (Validator validator : validators){

Loading…
Cancel
Save