From fe72dd67dd33f402b8e755f07001bb172f9156d2 Mon Sep 17 00:00:00 2001 From: David Bernard Date: Fri, 3 Jul 2015 20:49:20 +0200 Subject: [PATCH 1/8] add TechniqueDef.noRender --- .../main/java/com/jme3/material/Material.java | 153 +++++++++--------- .../java/com/jme3/material/TechniqueDef.java | 135 +++++++++------- .../com/jme3/material/plugins/J3MLoader.java | 94 +++++------ 3 files changed, 205 insertions(+), 177 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/material/Material.java b/jme3-core/src/main/java/com/jme3/material/Material.java index 5f0ab8f91..44bfb73f5 100644 --- a/jme3-core/src/main/java/com/jme3/material/Material.java +++ b/jme3-core/src/main/java/com/jme3/material/Material.java @@ -69,7 +69,7 @@ import java.util.logging.Logger; * Setting the parameters can modify the behavior of a * shader. *

- * + * * @author Kirill Vainer */ public class Material implements CloneableSmartAsset, Cloneable, Savable { @@ -146,7 +146,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { public String getName() { return name; } - + /** * This method sets the name of the material. * The name is not the same as the asset name. @@ -222,11 +222,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { } /** - * Compares two materials and returns true if they are equal. + * Compares two materials and returns true if they are equal. * This methods compare definition, parameters, additional render states. - * Since materials are mutable objects, implementing equals() properly is not possible, + * Since materials are mutable objects, implementing equals() properly is not possible, * hence the name contentEquals(). - * + * * @param otherObj the material to compare to this material * @return true if the materials are equal. */ @@ -234,15 +234,15 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { if (!(otherObj instanceof Material)) { return false; } - + Material other = (Material) otherObj; - + // Early exit if the material are the same object if (this == other) { return true; } - // Check material definition + // Check material definition if (this.getMaterialDef() != other.getMaterialDef()) { return false; } @@ -251,12 +251,12 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { if (this.paramValues.size() != other.paramValues.size()) { return false; } - + // Checking technique if (this.technique != null || other.technique != null) { // Techniques are considered equal if their names are the same - // E.g. if user chose custom technique for one material but - // uses default technique for other material, the materials + // E.g. if user chose custom technique for one material but + // uses default technique for other material, the materials // are not equal. String thisDefName = this.technique != null ? this.technique.getDef().getName() : "Default"; String otherDefName = other.technique != null ? other.technique.getDef().getName() : "Default"; @@ -290,7 +290,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { return false; } } - + return true; } @@ -305,7 +305,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { hash = 29 * hash + (this.additionalState != null ? this.additionalState.contentHashCode() : 0); return hash; } - + /** * Returns the currently active technique. *

@@ -436,7 +436,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { public Collection getParams() { return paramValues.values(); } - + /** * Returns the ListMap of all parameters set on this material. * @@ -473,7 +473,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { */ public void setParam(String name, VarType type, Object value) { checkSetParam(type, name); - + if (type.isTextureType()) { setTextureParam(name, type, (Texture)value); } else { @@ -501,7 +501,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { if (matParam == null) { return; } - + paramValues.remove(name); if (matParam instanceof MatParamTexture) { int texUnit = ((MatParamTexture) matParam).getUnit(); @@ -728,7 +728,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { renderer.renderMesh(mesh, lodLevel, 1, null); } } - + /** * Uploads the lights in the light list as two uniform arrays.

* *

@@ -747,30 +747,30 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { return 0; } - Uniform lightData = shader.getUniform("g_LightData"); - lightData.setVector4Length(numLights * 3);//8 lights * max 3 + Uniform lightData = shader.getUniform("g_LightData"); + lightData.setVector4Length(numLights * 3);//8 lights * max 3 Uniform ambientColor = shader.getUniform("g_AmbientLightColor"); - - if (startIndex != 0) { + + if (startIndex != 0) { // apply additive blending for 2nd and future passes rm.getRenderer().applyRenderState(additiveLight); - ambientColor.setValue(VarType.Vector4, ColorRGBA.Black); + ambientColor.setValue(VarType.Vector4, ColorRGBA.Black); }else{ ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList,true)); } - + int lightDataIndex = 0; TempVars vars = TempVars.get(); Vector4f tmpVec = vars.vect4f1; int curIndex; int endIndex = numLights + startIndex; for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) { - - - Light l = lightList.get(curIndex); + + + Light l = lightList.get(curIndex); if(l.getType() == Light.Type.Ambient){ - endIndex++; + endIndex++; continue; } ColorRGBA color = l.getColor(); @@ -781,14 +781,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { l.getType().getId(), lightDataIndex); lightDataIndex++; - + switch (l.getType()) { case Directional: DirectionalLight dl = (DirectionalLight) l; - Vector3f dir = dl.getDirection(); + Vector3f dir = dl.getDirection(); //Data directly sent in view space to avoid a matrix mult for each pixel tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); // tmpVec.divideLocal(tmpVec.w); // tmpVec.normalizeLocal(); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex); @@ -802,7 +802,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { Vector3f pos = pl.getPosition(); float invRadius = pl.getInvRadius(); tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); //tmpVec.divideLocal(tmpVec.w); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex); lightDataIndex++; @@ -810,37 +810,37 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { lightData.setVector4InArray(0,0,0,0, lightDataIndex); lightDataIndex++; break; - case Spot: + case Spot: SpotLight sl = (SpotLight) l; Vector3f pos2 = sl.getPosition(); Vector3f dir2 = sl.getDirection(); float invRange = sl.getInvSpotRange(); float spotAngleCos = sl.getPackedAngleCos(); tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); // tmpVec.divideLocal(tmpVec.w); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex); lightDataIndex++; - + //We transform the spot direction in view space here to save 5 varying later in the lighting shader //one vec4 less and a vec4 that becomes a vec3 //the downside is that spotAngleCos decoding happens now in the frag shader. tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); tmpVec.normalizeLocal(); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex); lightDataIndex++; - break; + break; default: throw new UnsupportedOperationException("Unknown type of light: " + l.getType()); } } - vars.release(); + vars.release(); //Padding of unsued buffer space while(lightDataIndex < numLights * 3) { lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex); - lightDataIndex++; - } + lightDataIndex++; + } return curIndex; } @@ -887,10 +887,10 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { case Directional: DirectionalLight dl = (DirectionalLight) l; Vector3f dir = dl.getDirection(); - //FIXME : there is an inconstency here due to backward + //FIXME : there is an inconstency here due to backward //compatibility of the lighting shader. - //The directional light direction is passed in the - //LightPosition uniform. The lighting shader needs to be + //The directional light direction is passed in the + //LightPosition uniform. The lighting shader needs to be //reworked though in order to fix this. tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1); lightPos.setValue(VarType.Vector4, tmpLightPosition); @@ -987,11 +987,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { for (TechniqueDef techDef : techDefs) { if (rendererCaps.containsAll(techDef.getRequiredCaps())) { // use the first one that supports all the caps - tech = new Technique(this, techDef); + tech = new Technique(this, techDef); techniques.put(name, tech); if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() || tech.getDef().getLightMode() == LightMode.Disable){ - break; + break; } } lastTech = techDef; @@ -1078,7 +1078,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { Uniform u = uniforms.getValue(i); if (!u.isSetByCurrentMaterial()) { if (u.getName().charAt(0) != 'g') { - // Don't reset world globals! + // Don't reset world globals! // The benefits gained from this are very minimal // and cause lots of matrix -> FloatBuffer conversions. u.clearValue(); @@ -1093,21 +1093,21 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { *

* The material is rendered as follows: *

- *
  • If the technique uses a shader, the model is then rendered according + *
  • If the technique uses a shader, the model is then rendered according * to the lighting mode specified on the technique definition. - *
  • For techniques that do not use shaders, + *
  • For techniques that do not use shaders, * fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface): @@ -1147,10 +1147,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { */ public void render(Geometry geom, LightList lights, RenderManager rm) { autoSelectTechnique(rm); + TechniqueDef techDef = technique.getDef(); - Renderer r = rm.getRenderer(); + if (techDef.isNoRender()) return; - TechniqueDef techDef = technique.getDef(); + Renderer r = rm.getRenderer(); if (rm.getForcedRenderState() != null) { r.applyRenderState(rm.getForcedRenderState()); @@ -1169,7 +1170,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { // reset unchanged uniform flag clearUniformsSetByCurrent(technique.getShader()); rm.updateUniformBindings(technique.getWorldBindUniforms()); - + // setup textures and uniforms for (int i = 0; i < paramValues.size(); i++) { @@ -1212,24 +1213,24 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { // any unset uniforms will be set to 0 resetUniformsNotSetByCurrent(shader); r.setShader(shader); - + renderMeshFromGeometry(r, geom); } /** * Called by {@link RenderManager} to render the geometry by * using this material. - * + * * Note that this version of the render method * does not perform light filtering. - * + * * @param geom The geometry to render * @param rm The render manager requesting the rendering */ public void render(Geometry geom, RenderManager rm) { render(geom, geom.getWorldLightList(), rm); } - + public void write(JmeExporter ex) throws IOException { OutputCapsule oc = ex.getCapsule(this); oc.write(def.getAssetName(), "material_def", null); @@ -1304,14 +1305,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { continue; } } - + if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) { // Ancient version of jME3 ... param.setName(param.getName().substring(2)); } - + if (def.getMaterialParam(param.getName()) == null) { - logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..", + logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..", param.getName()); } else { checkSetParam(param.getVarType(), param.getName()); diff --git a/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java b/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java index f8152e563..d7523956c 100644 --- a/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java +++ b/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java @@ -40,7 +40,7 @@ import java.util.*; /** * Describes a technique definition. - * + * * @author Kirill Vainer */ public class TechniqueDef implements Savable { @@ -49,7 +49,7 @@ 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. */ @@ -58,15 +58,15 @@ public class TechniqueDef implements Savable { * Disable light-based rendering */ Disable, - + /** - * Enable light rendering by using a single pass. + * Enable light rendering by using a single pass. *

    * An array of light positions and light colors is passed to the shader * containing the world light list for the geometry being rendered. */ SinglePass, - + /** * Enable light rendering by using multi-pass rendering. *

    @@ -77,7 +77,7 @@ public class TechniqueDef implements Savable { * passes have it set to black. */ MultiPass, - + /** * @deprecated OpenGL1 is not supported anymore */ @@ -96,15 +96,16 @@ public class TechniqueDef implements Savable { private EnumMap shaderLanguages; private EnumMap shaderNames; - + private DefineList presetDefines; private boolean usesNodes = false; private List shaderNodes; private ShaderGenerationInfo shaderGenerationInfo; + private boolean noRender = false; private RenderState renderState; private RenderState forcedRenderState; - + private LightMode lightMode = LightMode.Disable; private ShadowMode shadowMode = ShadowMode.Disable; @@ -115,7 +116,7 @@ public class TechniqueDef implements Savable { * Creates a new technique definition. *

    * Used internally by the J3M/J3MD loader. - * + * * @param name The name of the technique, should be set to null * for default techniques. */ @@ -135,7 +136,7 @@ public class TechniqueDef implements Savable { /** * Returns the name of this technique as specified in the J3MD file. * Default techniques have the name "Default". - * + * * @return the name of this technique */ public String getName(){ @@ -153,9 +154,9 @@ public class TechniqueDef implements Savable { /** * Set the light mode - * + * * @param lightMode the light mode - * + * * @see LightMode */ public void setLightMode(LightMode lightMode) { @@ -172,9 +173,9 @@ public class TechniqueDef implements Savable { /** * Set the shadow mode. - * + * * @param shadowMode the shadow mode. - * + * * @see ShadowMode */ public void setShadowMode(ShadowMode shadowMode) { @@ -184,7 +185,7 @@ public class TechniqueDef implements Savable { /** * Returns the render state that this technique is using * @return the render state that this technique is using - * @see #setRenderState(com.jme3.material.RenderState) + * @see #setRenderState(com.jme3.material.RenderState) */ public RenderState getRenderState() { return renderState; @@ -192,15 +193,37 @@ public class TechniqueDef implements Savable { /** * Sets the render state that this technique is using. - * + * * @param renderState the render state that this technique is using. - * + * * @see RenderState */ public void setRenderState(RenderState renderState) { this.renderState = renderState; } + /** + * Sets if this technique should not be used to render. + * + * @param noRender not render or render ? + * + * @see NoRender + */ + public void setNoRender(boolean noRender) { + this.noRender = noRender; + } + + /** + * Returns true if this technique should not be used to render. + * (eg. to not render a material with default technique) + * + * @return true if this technique should not be rendered, false otherwise. + * + */ + public boolean isNoRender(){ + return noRender; + } + /** * @deprecated jME3 always requires shaders now */ @@ -208,12 +231,12 @@ public class TechniqueDef implements Savable { public boolean isUsingShaders(){ return true; } - + /** * Returns true if this technique uses Shader Nodes, false otherwise. - * + * * @return true if this technique uses Shader Nodes, false otherwise. - * + * */ public boolean isUsingShaderNodes(){ return usesNodes; @@ -222,7 +245,7 @@ public class TechniqueDef implements Savable { /** * Gets the {@link Caps renderer capabilities} that are required * by this technique. - * + * * @return the required renderer capabilities */ public EnumSet getRequiredCaps() { @@ -231,7 +254,7 @@ public class TechniqueDef implements Savable { /** * Sets the shaders that this technique definition will use. - * + * * @param vertexShader The name of the vertex shader * @param fragmentShader The name of the fragment shader * @param vertLanguage The vertex shader language @@ -242,7 +265,7 @@ public class TechniqueDef implements Savable { this.shaderNames.put(Shader.ShaderType.Vertex, vertexShader); this.shaderLanguages.put(Shader.ShaderType.Fragment, fragLanguage); this.shaderNames.put(Shader.ShaderType.Fragment, fragmentShader); - + requiredCaps.clear(); Caps vertCap = Caps.valueOf(vertLanguage); requiredCaps.add(vertCap); @@ -259,17 +282,17 @@ public class TechniqueDef implements Savable { */ public void setShaderFile(EnumMap shaderNames, EnumMap shaderLanguages) { requiredCaps.clear(); - + for (Shader.ShaderType shaderType : shaderNames.keySet()) { String language = shaderLanguages.get(shaderType); String shaderFile = shaderNames.get(shaderType); - + this.shaderLanguages.put(shaderType, language); this.shaderNames.put(shaderType, shaderFile); - + Caps vertCap = Caps.valueOf(language); requiredCaps.add(vertCap); - + if (shaderType.equals(Shader.ShaderType.Geometry)) { requiredCaps.add(Caps.GeometryShader); } else if (shaderType.equals(Shader.ShaderType.TessellationControl)) { @@ -280,11 +303,11 @@ public class TechniqueDef implements Savable { /** * Returns the define name which the given material parameter influences. - * + * * @param paramName The parameter name to look up * @return The define name - * - * @see #addShaderParamDefine(java.lang.String, java.lang.String) + * + * @see #addShaderParamDefine(java.lang.String, java.lang.String) */ public String getShaderParamDefine(String paramName){ if (defineParams == null) { @@ -297,11 +320,11 @@ public class TechniqueDef implements Savable { * Adds a define linked to a material parameter. *

    * Any time the material parameter on the parent material is altered, - * the appropriate define on the technique will be modified as well. - * See the method + * the appropriate define on the technique will be modified as well. + * See the method * {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) } * on the exact details of how the material parameter changes the define. - * + * * @param paramName The name of the material parameter to link to. * @param defineName The name of the define parameter, e.g. USE_LIGHTING */ @@ -314,26 +337,26 @@ public class TechniqueDef implements Savable { /** * Returns the {@link DefineList} for the preset defines. - * + * * @return the {@link DefineList} for the preset defines. - * - * @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object) + * + * @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object) */ public DefineList getShaderPresetDefines() { return presetDefines; } - + /** - * Adds a preset define. + * Adds a preset define. *

    * Preset defines do not depend upon any parameters to be activated, * they are always passed to the shader as long as this technique is used. - * + * * @param defineName The name of the define parameter, e.g. USE_LIGHTING - * @param type The type of the define. See + * @param type The type of the define. See * {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) } * to see why it matters. - * + * * @param value The value of the define */ public void addShaderPresetDefine(String defineName, VarType type, Object value){ @@ -346,18 +369,18 @@ public class TechniqueDef implements Savable { /** * Returns the name of the fragment shader used by the technique, or null * if no fragment shader is specified. - * + * * @return the name of the fragment shader to be used. */ public String getFragmentShaderName() { return shaderNames.get(Shader.ShaderType.Fragment); } - + /** * Returns the name of the vertex shader used by the technique, or null * if no vertex shader is specified. - * + * * @return the name of the vertex shader to be used. */ public String getVertexShaderName() { @@ -370,7 +393,7 @@ public class TechniqueDef implements Savable { public String getFragmentShaderLanguage() { return shaderLanguages.get(Shader.ShaderType.Fragment); } - + /** * Returns the language of the vertex shader used in this technique. */ @@ -390,10 +413,10 @@ public class TechniqueDef implements Savable { public String getShaderProgramName(Shader.ShaderType shaderType){ return shaderNames.get(shaderType); } - + /** * Adds a new world parameter by the given name. - * + * * @param name The world parameter to add. * @return True if the world parameter name was found and added * to the list of world parameters, false otherwise. @@ -402,7 +425,7 @@ public class TechniqueDef implements Savable { if (worldBinds == null){ worldBinds = new ArrayList(); } - + try { worldBinds.add( UniformBinding.valueOf(name) ); return true; @@ -418,11 +441,11 @@ public class TechniqueDef implements Savable { public void setForcedRenderState(RenderState forcedRenderState) { this.forcedRenderState = forcedRenderState; } - + /** * Returns a list of world parameters that are used by this * technique definition. - * + * * @return The list of world parameters */ public List getWorldBindings() { @@ -448,10 +471,11 @@ public class TechniqueDef implements Savable { oc.write(lightMode, "lightMode", LightMode.Disable); oc.write(shadowMode, "shadowMode", ShadowMode.Disable); oc.write(renderState, "renderState", null); + oc.write(noRender, "noRender", false); oc.write(usesNodes, "usesNodes", false); oc.writeSavableArrayList((ArrayList)shaderNodes,"shaderNodes", null); oc.write(shaderGenerationInfo, "shaderGenerationInfo", null); - + // TODO: Finish this when Map export is available // oc.write(defineParams, "defineParams", null); // TODO: Finish this when List export is available @@ -470,7 +494,8 @@ public class TechniqueDef implements Savable { lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable); shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable); renderState = (RenderState) ic.readSavable("renderState", null); - + noRender = ic.readBoolean("noRender", false); + if (ic.getSavableVersion(TechniqueDef.class) == 0) { // Old version shaderLanguages.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null)); @@ -483,7 +508,7 @@ public class TechniqueDef implements Savable { shaderLanguages.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrlLanguage", null)); shaderLanguages.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tsevalLanguage", null)); } - + usesNodes = ic.readBoolean("usesNodes", false); shaderNodes = ic.readSavableArrayList("shaderNodes", null); shaderGenerationInfo = (ShaderGenerationInfo) ic.readSavable("shaderGenerationInfo", null); @@ -525,6 +550,6 @@ public class TechniqueDef implements Savable { //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 + ", 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 + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + ", noRender=" + noRender + '}'; + } } diff --git a/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java b/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java index 0c81c3e14..d0620ca59 100644 --- a/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java +++ b/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java @@ -63,7 +63,7 @@ public class J3MLoader implements AssetLoader { // private ErrorLogger errors; private ShaderNodeLoaderDelegate nodesLoaderDelegate; boolean isUseNodes = false; - + private AssetManager assetManager; private AssetKey key; @@ -168,7 +168,7 @@ public class J3MLoader implements AssetLoader { if (tex != null){ if (repeat){ tex.setWrap(WrapMode.Repeat); - } + } }else{ tex = new Texture2D(PlaceholderAssets.getPlaceholderImage(assetManager)); if (repeat){ @@ -176,7 +176,7 @@ public class J3MLoader implements AssetLoader { } tex.setKey(texKey); tex.setName(texKey.getName()); - } + } return tex; }else{ String[] split = value.trim().split(whitespacePattern); @@ -222,15 +222,15 @@ public class J3MLoader implements AssetLoader { } } } - - // [ "(" ")" ] [-LINEAR] [ ":" ] + + // [ "(" ")" ] [-LINEAR] [ ":" ] private void readParam(String statement) throws IOException{ String name; String defaultVal = null; ColorSpace colorSpace = null; - + String[] split = statement.split(":"); - + // Parse default val if (split.length == 1){ // Doesn't contain default value @@ -239,14 +239,14 @@ public class J3MLoader implements AssetLoader { throw new IOException("Parameter statement syntax incorrect"); } statement = split[0].trim(); - defaultVal = split[1].trim(); + defaultVal = split[1].trim(); } - + if (statement.endsWith("-LINEAR")) { colorSpace = ColorSpace.Linear; statement = statement.substring(0, statement.length() - "-LINEAR".length()); } - + // Parse ffbinding int startParen = statement.indexOf("("); if (startParen != -1){ @@ -256,32 +256,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{ @@ -376,7 +376,7 @@ public class J3MLoader implements AssetLoader { technique.setRenderState(renderState); renderState = null; } - + private void readForcedRenderState(List renderStates) throws IOException{ renderState = new RenderState(); for (Statement statement : renderStates){ @@ -385,7 +385,7 @@ public class J3MLoader implements AssetLoader { technique.setForcedRenderState(renderState); renderState = null; } - + // [ ":" ] private void readDefine(String statement) throws IOException{ String[] split = statement.split(":"); @@ -405,9 +405,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") || split[0].equals("GeometryShader") || @@ -420,12 +420,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) { @@ -438,14 +438,16 @@ public class J3MLoader implements AssetLoader { } } else if (split[0].equals("FragmentShaderNodes")) { initNodesLoader(); - if (isUseNodes) { + if (isUseNodes) { nodesLoaderDelegate.readFragmentShaderNodes(statement.getContents()); } + } else if (split[0].equals("NoRender")) { + technique.setNoRender(true); } else { throw new MatParseException(null, split[0], statement); } } - + private void readTransparentStatement(String statement) throws IOException{ String[] split = statement.split(whitespacePattern); if (split.length != 2){ @@ -465,11 +467,11 @@ 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. @@ -479,14 +481,14 @@ public class J3MLoader implements AssetLoader { if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) { technique.setShaderFile(shaderName, shaderLanguage); } - + materialDef.addTechniqueDef(technique); technique = null; shaderLanguage.clear(); shaderName.clear(); } - private void loadFromRoot(List roots) throws IOException{ + private void loadFromRoot(List roots) throws IOException{ if (roots.size() == 2){ Statement exception = roots.get(0); String line = exception.getLine(); @@ -498,7 +500,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(); @@ -511,16 +513,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(); @@ -535,15 +537,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]; @@ -561,16 +563,16 @@ 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(); if (key.getExtension().equals("j3m") && !(key instanceof MaterialKey)) { @@ -584,7 +586,7 @@ public class J3MLoader implements AssetLoader { in.close(); } } - + if (material != null){ // material implementation return material; @@ -593,7 +595,7 @@ public class J3MLoader implements AssetLoader { return materialDef; } } - + public MaterialDef loadMaterialDef(List roots, AssetManager manager, AssetKey key) throws IOException { this.key = key; this.assetManager = manager; @@ -615,6 +617,6 @@ public class J3MLoader implements AssetLoader { nodesLoaderDelegate.setAssetManager(assetManager); } } - } + } } From 9883a18d85cddd916f8b03808343b63e83819551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Bouquet?= Date: Sat, 4 Jul 2015 18:58:12 +0200 Subject: [PATCH 2/8] Update CONTRIBUTING.md --- CONTRIBUTING.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ebecab28b..82ffeb4e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,13 +16,6 @@ When you're ready to submit your code, just make a [pull request](https://help.g - When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing. - If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks! -**Note to Eclipse users:** The Eclipse [git client does not support https](http://hub.jmonkeyengine.org/forum/topic/problem-cloning-the-new-git-repository/#post-265594). The current workaround is to use the command line to clone the repository. -To import the local repository as a project follow these steps: - -1. Add a line 'apply plugin: eclipse' to your common.gradle file in the main project directory. -2. Navigate to the project directory in command line and execute command 'gradle eclipse'. This will load all the dependancies for eclipse. -3. In Eclipse, add the repository as an existing Java Project. - p.s. We will try hold ourselves to a [certain standard](http://www.defmacro.org/2013/04/03/issue-etiquette.html) when it comes to GitHub etiquette. If at any point we fail to uphold this standard, let us know. #### Core Contributors From dca050b96b4e93b79dcc261f52c3436c11152a35 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 4 Jul 2015 18:51:02 +0200 Subject: [PATCH 3/8] Added a protected modifier to getReceivers in Abstract shadow renderer see issue https://github.com/jMonkeyEngine/jmonkeyengine/issues/212 --- .../src/main/java/com/jme3/shadow/AbstractShadowRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index 5ff4ac8a7..bd70465cb 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -459,7 +459,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable debug = true; } - abstract void getReceivers(GeometryList lightReceivers); + protected abstract void getReceivers(GeometryList lightReceivers); public void postFrame(FrameBuffer out) { if (skipPostPass) { From 2b8898b7b2e05a8700a584bb363e77ee225ffe84 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 4 Jul 2015 19:05:57 +0200 Subject: [PATCH 4/8] Here is the rest of last commit --- .../java/com/jme3/shadow/DirectionalLightShadowRenderer.java | 2 +- .../src/main/java/com/jme3/shadow/PointLightShadowRenderer.java | 2 +- .../src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java index d0189e854..acf8a9677 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java @@ -192,7 +192,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { } @Override - void getReceivers(GeometryList lightReceivers) { + protected void getReceivers(GeometryList lightReceivers) { if (lightReceivers.size()==0) { for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers); diff --git a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java index 2976a2460..f4a6455f1 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java @@ -139,7 +139,7 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { } @Override - void getReceivers(GeometryList lightReceivers) { + protected void getReceivers(GeometryList lightReceivers) { lightReceivers.clear(); for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers); diff --git a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java index dafd25ac4..b291e722e 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java @@ -151,7 +151,7 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { } @Override - void getReceivers(GeometryList lightReceivers) { + protected void getReceivers(GeometryList lightReceivers) { lightReceivers.clear(); Camera[] cameras = new Camera[1]; cameras[0] = shadowCam; From 6d1ab7af6590f3654f5349367ad2e87ed1162709 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sun, 5 Jul 2015 23:35:34 +0200 Subject: [PATCH 5/8] Redesign of the frag part of unshadedNodes so it's more modular, and can be properly used as GLSL 1.5 shader. Added a stress test for unshadedNodes. Changed the name of the texture parameter to textureMap in TextureFetch shaderNode as it was conflicting with the texture function used to fetch a texel from a a texture in glsl 1.5 --- .../Common/MatDefs/Misc/UnshadedNodes.j3md | 216 ++++++++++-------- .../ShaderNodes/Basic/TextureFetch.j3sn | 4 +- .../MatDefs/ShaderNodes/Basic/texture.frag | 2 +- .../MatDefs/ShaderNodes/Basic/texture15.frag | 2 +- .../stress/TestShaderNodesStress.java | 102 +++++++++ 5 files changed, 226 insertions(+), 100 deletions(-) create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md index f9fb05288..b35c17a9d 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md @@ -1,97 +1,121 @@ -MaterialDef UnshadedNodes { - - MaterialParameters { - Texture2D ColorMap - Texture2D LightMap - Color Color (Color) - Boolean VertexColor (UseVertexColor) - Boolean SeparateTexCoord - - // Alpha threshold for fragment discarding - Float AlphaDiscardThreshold (AlphaTestFallOff) - - // For hardware skinning - Int NumberOfBones - Matrix4Array BoneMatrices - - } - - Technique { - - WorldParameters { - WorldViewProjectionMatrix - //used for fog - WorldViewMatrix - } - - VertexShaderNodes{ - ShaderNode GpuSkinning{ - Definition: BasicGPUSkinning : Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn - Condition : NumberOfBones - InputMapping{ - modelPosition = Global.position; - boneMatrices = MatParam.BoneMatrices - boneWeight = Attr.inHWBoneWeight - boneIndex = Attr.inHWBoneIndex - } - OutputMapping{ - Global.position = modModelPosition - } - } - ShaderNode UnshadedVert{ - Definition: CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn - InputMapping{ - worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix - modelPosition = Global.position.xyz - texCoord1 = Attr.inTexCoord: ColorMap || (LightMap && !SeparateTexCoord) - texCoord2 = Attr.inTexCoord2: SeparateTexCoord - vertColor = Attr.inColor: VertexColor - } - OutputMapping{ - Global.position = projPosition - } - } - } - FragmentShaderNodes{ - ShaderNode UnshadedFrag{ - Definition: Unshaded : Common/MatDefs/ShaderNodes/Common/Unshaded.j3sn - InputMapping{ - texCoord = UnshadedVert.texCoord1: ColorMap - vertColor = UnshadedVert.vertColor: VertexColor - matColor = MatParam.Color: Color - colorMap = MatParam.ColorMap: ColorMap - color = Global.outColor - } - OutputMapping{ - Global.outColor = color - } - } - - ShaderNode AlphaDiscardThreshold{ - Definition: AlphaDiscard : Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn - Condition : AlphaDiscardThreshold - InputMapping{ - alpha = Global.outColor.a - threshold = MatParam.AlphaDiscardThreshold - } - } - ShaderNode LightMap{ - Definition: LightMapping : Common/MatDefs/ShaderNodes/LightMapping/LightMapping.j3sn - Condition: LightMap - InputMapping{ - texCoord = UnshadedVert.texCoord1: !SeparateTexCoord - texCoord = UnshadedVert.texCoord2: SeparateTexCoord - lightMap = MatParam.LightMap - color = Global.outColor - } - OutputMapping{ - Global.outColor = color - } - } - - } - - } - - +MaterialDef UnshadedNodes { + MaterialParameters { + Texture2D ColorMap + Texture2D LightMap + Color Color (Color) + Boolean VertexColor (UseVertexColor) + Boolean SeparateTexCoord + Float AlphaDiscardThreshold (AlphaTestFallOff) + Int NumberOfBones + Matrix4Array BoneMatrices + } + Technique { + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + } + VertexShaderNodes { + ShaderNode GpuSkinning { + Definition : BasicGPUSkinning : Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn + Condition : NumberOfBones + InputMapping { + modelPosition = Global.position + boneMatrices = MatParam.BoneMatrices + boneWeight = Attr.inHWBoneWeight + boneIndex = Attr.inHWBoneIndex + } + OutputMapping { + Global.position = modModelPosition + } + } + ShaderNode UnshadedVert { + Definition : CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn + InputMapping { + worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix + modelPosition = Global.position.xyz + texCoord1 = Attr.inTexCoord : ColorMap || (LightMap && !SeparateTexCoord) + texCoord2 = Attr.inTexCoord2 : SeparateTexCoord + vertColor = Attr.inColor : VertexColor + } + OutputMapping { + Global.position = projPosition + } + } + } + FragmentShaderNodes { + ShaderNode MatColorMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = MatParam.Color + color2 = Global.outColor + } + OutputMappings { + Global.outColor = outColor + } + Condition : Color + } + ShaderNode VertColorMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = UnshadedVert.vertColor + color2 = Global.outColor + } + OutputMappings { + Global.outColor = outColor + } + Condition : VertexColor + } + ShaderNode ColorMapTF { + Definition : TextureFetch : Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn + InputMappings { + texCoord = UnshadedVert.texCoord1 + textureMap = MatParam.ColorMap + } + OutputMappings { + } + Condition : ColorMap + } + ShaderNode ColorMapMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = ColorMapTF.outColor + color2 = Global.outColor + } + OutputMappings { + Global.outColor = outColor + } + Condition : ColorMap + } + ShaderNode AlphaDiscardThreshold { + Definition : AlphaDiscard : Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn + Condition : AlphaDiscardThreshold + InputMapping { + alpha = Global.outColor.a + threshold = MatParam.AlphaDiscardThreshold + } + } + ShaderNode LightMapTF { + Definition : TextureFetch : Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn + InputMappings { + textureMap = MatParam.LightMap + texCoord = UnshadedVert.texCoord2 : SeparateTexCoord + texCoord = UnshadedVert.texCoord1 : !SeparateTexCoord + } + OutputMappings { + } + Condition : LightMap + } + ShaderNode LightMapMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + OutputMappings { + Global.outColor = outColor + } + InputMappings { + color1 = LightMapTF.outColor + color2 = Global.outColor + } + Condition : LightMap + } + } + } } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn index 69fdec638..034fcd116 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn @@ -5,12 +5,12 @@ ShaderNodeDefinitions{ Shader GLSL150: Common/MatDefs/ShaderNodes/Basic/texture15.frag Documentation{ Fetches a color value in the given texture acording to given texture coordinates - @input texture the texture to read + @input textureMap the texture to read @input texCoord the texture coordinates @output outColor the fetched color } Input { - sampler2D texture + sampler2D textureMap vec2 texCoord } Output { diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag index eb83a7b1f..163fbc123 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag @@ -1,3 +1,3 @@ void main(){ - outColor = texture2D(texture,texCoord); + outColor = texture2D(textureMap,texCoord); } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag index b716c3e89..2ece0a646 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag @@ -1,3 +1,3 @@ void main(){ - outColor = texture(texture,texCoord); + outColor = texture(textureMap,texCoord); } \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java new file mode 100644 index 000000000..3364f5feb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java @@ -0,0 +1,102 @@ +package jme3test.stress; + +import com.jme3.app.BasicProfilerState; +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.profile.AppProfiler; +import com.jme3.profile.AppStep; +import com.jme3.profile.VpStep; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Texture; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestShaderNodesStress extends SimpleApplication { + + public static void main(String[] args) { + TestShaderNodesStress app = new TestShaderNodesStress(); + app.start(); + } + + @Override + public void simpleInitApp() { + + Quad q = new Quad(1, 1); + Geometry g = new Geometry("quad", q); + g.setLocalTranslation(-500, -500, 0); + g.setLocalScale(1000); + + rootNode.attachChild(g); + cam.setLocation(new Vector3f(0.0f, 0.0f, 0.40647888f)); + cam.setRotation(new Quaternion(0.0f, 1.0f, 0.0f, 0.0f)); + + Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md"); + //Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + + mat.setColor("Color", ColorRGBA.Yellow); + mat.setTexture("ColorMap", tex); + g.setMaterial(mat); + //place the geoms in the transparent bucket so that they are rendered back to front for maximum overdraw + g.setQueueBucket(RenderQueue.Bucket.Transparent); + + for (int i = 0; i < 1000; i++) { + Geometry cl = g.clone(false); + cl.move(0, 0, -(i + 1)); + rootNode.attachChild(cl); + } + + flyCam.setMoveSpeed(20); + Logger.getLogger("com.jme3").setLevel(Level.WARNING); + + this.setAppProfiler(new Profiler()); + + } + + private class Profiler implements AppProfiler { + + private long startTime; + private long updateTime; + private long renderTime; + private long sum; + private int nbFrames; + + @Override + public void appStep(AppStep step) { + + switch (step) { + case BeginFrame: + startTime = System.nanoTime(); + break; + case RenderFrame: + updateTime = System.nanoTime(); + // System.err.println("Update time : " + (updateTime - startTime)); + break; + case EndFrame: + nbFrames++; + if (nbFrames >= 150) { + renderTime = System.nanoTime(); + sum += renderTime - updateTime; + System.err.println("render time : " + (renderTime - updateTime)); + System.err.println("Average render time : " + ((float)sum / (float)(nbFrames-150))); + } + break; + + } + + } + + @Override + public void vpStep(VpStep step, ViewPort vp, RenderQueue.Bucket bucket) { + + } + + } +} From 34220640aa1db72ef11343a853c12965f57909fe Mon Sep 17 00:00:00 2001 From: Nehon Date: Mon, 6 Jul 2015 19:01:00 +0200 Subject: [PATCH 6/8] Fixed how model bound were refreshed in BathNode : issue https://github.com/jMonkeyEngine/jmonkeyengine/issues/275 --- .../main/java/com/jme3/scene/BatchNode.java | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/scene/BatchNode.java b/jme3-core/src/main/java/com/jme3/scene/BatchNode.java index 2d603ac2c..9a920093d 100644 --- a/jme3-core/src/main/java/com/jme3/scene/BatchNode.java +++ b/jme3-core/src/main/java/com/jme3/scene/BatchNode.java @@ -119,19 +119,6 @@ public class BatchNode extends GeometryGroupNode { setNeedsFullRebatch(true); } - @Override - public void updateGeometricState() { - if (!children.isEmpty()) { - for (Batch batch : batches.getArray()) { - if (batch.needMeshUpdate) { - batch.geometry.updateModelBound(); - batch.geometry.updateWorldBound(); - batch.needMeshUpdate = false; - } - } - } - super.updateGeometricState(); - } protected Matrix4f getTransformMatrix(Geometry g){ return g.cachedWorldMat; @@ -169,7 +156,7 @@ public class BatchNode extends GeometryGroupNode { nvb.updateData(normBuf); - batch.needMeshUpdate = true; + batch.geometry.updateModelBound(); } } @@ -234,7 +221,7 @@ public class BatchNode extends GeometryGroupNode { batch.geometry.setMesh(m); batch.geometry.getMesh().updateCounts(); - batch.geometry.getMesh().updateBound(); + batch.geometry.updateModelBound(); batches.add(batch); } if (batches.size() > 0) { @@ -747,8 +734,7 @@ public class BatchNode extends GeometryGroupNode { } } } - Geometry geometry; - boolean needMeshUpdate = false; + Geometry geometry; } protected void setNeedsFullRebatch(boolean needsFullRebatch) { From 57dd2748e25bf65a6deba37369eed8ab343d2a83 Mon Sep 17 00:00:00 2001 From: Nehon Date: Fri, 10 Jul 2015 21:28:42 +0200 Subject: [PATCH 7/8] Tested if a joystick axis is not the nullAxis before assigning action to it. --- .../src/main/java/com/jme3/input/DefaultJoystickAxis.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java b/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java index 954451145..8f32c2d6b 100644 --- a/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java +++ b/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java @@ -72,8 +72,10 @@ public class DefaultJoystickAxis implements JoystickAxis { * @param negativeMapping The mapping to receive events when the axis is positive */ public void assignAxis(String positiveMapping, String negativeMapping){ - inputManager.addMapping(positiveMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, false)); - inputManager.addMapping(negativeMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, true)); + if (axisIndex != -1) { + inputManager.addMapping(positiveMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, false)); + inputManager.addMapping(negativeMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, true)); + } } /** From 95d5fdf9c5b45f1bbd4d52e8e2a17f21ad03faa5 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 11 Jul 2015 21:15:42 +0200 Subject: [PATCH 8/8] Fixed issue https://github.com/jMonkeyEngine/jmonkeyengine/issues/252 This was due to a bug in the code where triangle data were stored after calculation. --- .../main/java/com/jme3/util/TangentBinormalGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java b/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java index 0f9aac1fc..5e85378ff 100644 --- a/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java +++ b/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java @@ -612,9 +612,9 @@ public class TangentBinormalGenerator { normal.normalizeLocal(); return new TriangleData( - tangent, - binormal, - normal); + tangent.clone(), + binormal.clone(), + normal.clone()); } finally { tmp.release(); }