diff --git a/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java b/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java index 8aeb883e0..12e743810 100644 --- a/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java +++ b/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java @@ -103,6 +103,10 @@ public class AndroidGL implements GL, GLExt, GLFbo { public void glBlendFunc(int sfactor, int dfactor) { GLES20.glBlendFunc(sfactor, dfactor); } + + public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha) { + GLES20.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + } public void glBufferData(int target, FloatBuffer data, int usage) { GLES20.glBufferData(target, getLimitBytes(data), data, usage); diff --git a/jme3-core/src/main/java/com/jme3/material/RenderState.java b/jme3-core/src/main/java/com/jme3/material/RenderState.java index 1fb33a079..9e3b1d257 100644 --- a/jme3-core/src/main/java/com/jme3/material/RenderState.java +++ b/jme3-core/src/main/java/com/jme3/material/RenderState.java @@ -32,6 +32,7 @@ package com.jme3.material; import com.jme3.export.*; +import com.jme3.renderer.opengl.GL; import com.jme3.scene.Mesh; import com.jme3.scene.Mesh.Mode; import java.io.IOException; @@ -277,7 +278,13 @@ public class RenderState implements Cloneable, Savable { * Result = (Source Color * (1 - Dest Color)) + (Dest Color * (1 - Source Color)) * -> (GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR) */ - Exclusion + Exclusion, + /** + * Allows for custom blending by using glBlendFuncSeparate. + *

+ * + */ + Custom } /** @@ -408,7 +415,11 @@ public class RenderState implements Cloneable, Savable { TestFunction frontStencilFunction = TestFunction.Always; TestFunction backStencilFunction = TestFunction.Always; int cachedHashCode = -1; - + int sfactorRGB=GL.GL_ONE; + int dfactorRGB=GL.GL_ZERO; + int sfactorAlpha=GL.GL_ONE; + int dfactorAlpha=GL.GL_ZERO; + public void write(JmeExporter ex) throws IOException { OutputCapsule oc = ex.getCapsule(this); oc.write(true, "pointSprite", false); @@ -434,6 +445,10 @@ public class RenderState implements Cloneable, Savable { oc.write(blendEquationAlpha, "blendEquationAlpha", BlendEquationAlpha.InheritColor); oc.write(depthFunc, "depthFunc", TestFunction.LessOrEqual); oc.write(lineWidth, "lineWidth", 1); + oc.write(sfactorRGB, "sfactorRGB", GL.GL_ONE); + oc.write(dfactorRGB, "dfactorRGB", GL.GL_ZERO); + oc.write(sfactorAlpha, "sfactorAlpha", GL.GL_ONE); + oc.write(dfactorAlpha, "dfactorAlpha", GL.GL_ZERO); // Only "additional render state" has them set to false by default oc.write(applyWireFrame, "applyWireFrame", true); @@ -474,6 +489,10 @@ public class RenderState implements Cloneable, Savable { blendEquationAlpha = ic.readEnum("blendEquationAlpha", BlendEquationAlpha.class, BlendEquationAlpha.InheritColor); depthFunc = ic.readEnum("depthFunc", TestFunction.class, TestFunction.LessOrEqual); lineWidth = ic.readFloat("lineWidth", 1); + sfactorRGB = ic.readInt("sfactorRGB", GL.GL_ONE); + dfactorAlpha = ic.readInt("dfactorRGB", GL.GL_ZERO); + sfactorRGB = ic.readInt("sfactorAlpha", GL.GL_ONE); + dfactorAlpha = ic.readInt("dfactorAlpha", GL.GL_ZERO); applyWireFrame = ic.readBoolean("applyWireFrame", true); @@ -605,6 +624,14 @@ public class RenderState implements Cloneable, Savable { if(lineWidth != rs.lineWidth){ return false; } + + if (blendMode.equals(BlendMode.Custom)) { + return sfactorRGB==rs.getCustomSfactorRGB() + && dfactorRGB==rs.getCustomDfactorRGB() + && sfactorAlpha==rs.getCustomSfactorAlpha() + && dfactorAlpha==rs.getCustomDfactorAlpha(); + + } return true; } @@ -744,6 +771,26 @@ public class RenderState implements Cloneable, Savable { cachedHashCode = -1; } + + /** + * Sets the custom blend factors for BlendMode.Custom as + * defined by glBlendFuncSeparate. + * + * @param sfactorRGB The source blend factor for RGB components. + * @param dfactorRGB The destination blend factor for RGB components. + * @param sfactorAlpha The source blend factor for the alpha component. + * @param dfactorAlpha The destination blend factor for the alpha component. + */ + public void setCustomBlendFactors(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha) + { + this.sfactorRGB = sfactorRGB; + this.dfactorRGB = dfactorRGB; + this.sfactorAlpha = sfactorAlpha; + this.dfactorAlpha = dfactorAlpha; + cachedHashCode = -1; + } + + /** * Enable depth testing. * @@ -1084,7 +1131,47 @@ public class RenderState implements Cloneable, Savable { public BlendMode getBlendMode() { return blendMode; } - + + /** + * Provides the source factor for the RGB components in + * BlendMode.Custom. + * + * @return the custom source factor for RGB components. + */ + public int getCustomSfactorRGB() { + return sfactorRGB; + } + + /** + * Provides the destination factor for the RGB components in + * BlendMode.Custom. + * + * @return the custom destination factor for RGB components. + */ + public int getCustomDfactorRGB() { + return dfactorRGB; + } + + /** + * Provides the source factor for the alpha component in + * BlendMode.Custom. + * + * @return the custom destination factor for alpha component. + */ + public int getCustomSfactorAlpha() { + return sfactorAlpha; + } + + /** + * Provides the destination factor for the alpha component in + * BlendMode.Custom. + * + * @return the custom destination factor for alpha component. + */ + public int getCustomDfactorAlpha() { + return dfactorAlpha; + } + /** * @return true * @deprecated Always returns true since point sprite is always enabled. @@ -1306,6 +1393,11 @@ public class RenderState implements Cloneable, Savable { hash = 79 * hash + (this.frontStencilFunction != null ? this.frontStencilFunction.hashCode() : 0); hash = 79 * hash + (this.backStencilFunction != null ? this.backStencilFunction.hashCode() : 0); hash = 79 * hash + Float.floatToIntBits(this.lineWidth); + + hash = 79 * hash + this.sfactorRGB; + hash = 79 * hash + this.dfactorRGB; + hash = 79 * hash + this.sfactorAlpha; + hash = 79 * hash + this.dfactorAlpha; cachedHashCode = hash; } return cachedHashCode; @@ -1380,6 +1472,13 @@ public class RenderState implements Cloneable, Savable { } if (additionalState.applyBlendMode) { state.blendMode = additionalState.blendMode; + if (additionalState.getBlendMode().equals(BlendMode.Custom)) { + state.setCustomBlendFactors( + additionalState.getCustomSfactorRGB(), + additionalState.getCustomDfactorRGB(), + additionalState.getCustomSfactorAlpha(), + additionalState.getCustomDfactorAlpha()); + } } else { state.blendMode = blendMode; } @@ -1464,6 +1563,11 @@ public class RenderState implements Cloneable, Savable { applyPolyOffset = true; applyDepthFunc = true; applyLineWidth = true; + + sfactorRGB = state.sfactorRGB; + dfactorRGB = state.dfactorRGB; + sfactorAlpha = state.sfactorAlpha; + dfactorAlpha = state.dfactorAlpha; } @Override @@ -1490,6 +1594,8 @@ public class RenderState implements Cloneable, Savable { + "\noffsetFactor=" + offsetFactor + "\noffsetUnits=" + offsetUnits + "\nlineWidth=" + lineWidth - + "\n]"; + + (blendMode.equals(BlendMode.Custom)? + "\ncustomBlendFactors=("+sfactorRGB+", "+dfactorRGB+", "+sfactorAlpha+", "+dfactorAlpha+")": + "\n]"); } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java index a4a738152..30996cd7d 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java @@ -197,6 +197,7 @@ public interface GL { public void glBindTexture(int target, int texture); public void glBlendEquationSeparate(int colorMode, int alphaMode); public void glBlendFunc(int sfactor, int dfactor); + public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha); public void glBufferData(int target, long data_size, int usage); public void glBufferData(int target, FloatBuffer data, int usage); public void glBufferData(int target, ShortBuffer data, int usage); diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java index ed6b336f8..6b15bb967 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java @@ -44,6 +44,12 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt { gl.glBlendFunc(sfactor, dfactor); checkError(); } + + public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dFactorAlpha) + { + gl.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dFactorAlpha); + checkError(); + } public void glBufferData(int target, FloatBuffer data, int usage) { gl.glBufferData(target, data, usage); diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index 1a8270435..bcb4a4d5c 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -748,6 +748,9 @@ public final class GLRenderer implements Renderer { case Exclusion: gl.glBlendFunc(GL.GL_ONE_MINUS_DST_COLOR, GL.GL_ONE_MINUS_SRC_COLOR); break; + case Custom: + gl.glBlendFuncSeparate(state.getCustomSfactorRGB(), state.getCustomDfactorRGB(), state.getCustomSfactorAlpha(), state.getCustomDfactorAlpha()); + break; default: throw new UnsupportedOperationException("Unrecognized blend mode: " + state.getBlendMode()); diff --git a/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java b/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java index 958163596..d73c5158a 100644 --- a/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java +++ b/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java @@ -135,6 +135,11 @@ public class IosGL implements GL, GLExt, GLFbo { public void glBlendFunc(int sfactor, int dfactor) { JmeIosGLES.glBlendFunc(sfactor, dfactor); } + + public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha) { + JmeIosGLES.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + } + public void glBufferData(int target, FloatBuffer data, int usage) { JmeIosGLES.glBufferData(target, getLimitBytes(data), data, usage); diff --git a/jme3-ios/src/main/java/com/jme3/renderer/ios/JmeIosGLES.java b/jme3-ios/src/main/java/com/jme3/renderer/ios/JmeIosGLES.java index b8ec75a77..b5cde6721 100644 --- a/jme3-ios/src/main/java/com/jme3/renderer/ios/JmeIosGLES.java +++ b/jme3-ios/src/main/java/com/jme3/renderer/ios/JmeIosGLES.java @@ -144,6 +144,7 @@ public class JmeIosGLES { // public static native void glBindVertexArray // TODO: Investigate this public static native void glBlendEquationSeparate(int colorMode, int alphaMode); public static native void glBlendFunc(int sfactor, int dfactor); + public static native void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha); public static native void glBufferData(int target, int size, Buffer data, int usage); public static native void glBufferData2(int target, int size, byte[] data, int offset, int usage); public static native void glBufferSubData(int target, int offset, int size, Buffer data); diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java index 8b222d751..bbd1b24f9 100644 --- a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java @@ -88,6 +88,11 @@ public class JoglGL implements GL, GL2, GL3, GL4 { GLContext.getCurrentGL().glBlendFunc(param1, param2); } + @Override + public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha) { + GLContext.getCurrentGL().glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + } + @Override public void glBufferData(int param1, long param2, int param3) { GLContext.getCurrentGL().glBufferData(param1, param2, null, param3); @@ -610,4 +615,5 @@ public class JoglGL implements GL, GL2, GL3, GL4 { public void glFramebufferTextureLayer(int param1, int param2, int param3, int param4, int param5) { GLContext.getCurrentGL().getGL3().glFramebufferTextureLayer(param1, param2, param3, param4, param5); } + } diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index abc419c41..59e50e3f7 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -58,6 +58,10 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 { GL11.glBlendFunc(param1, param2); } + public void glBlendFuncSeparate(int param1, int param2, int param3, int param4) { + GL14.glBlendFuncSeparate(param1, param2, param3, param4); + } + public void glBufferData(int param1, long param2, int param3) { GL15.glBufferData(param1, param2, param3); } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index 10358c009..f5f6a7b1a 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -86,6 +86,10 @@ public class LwjglGL implements GL, GL2, GL3, GL4 { public void glBlendFunc(int param1, int param2) { GL11.glBlendFunc(param1, param2); } + + public void glBlendFuncSeparate(int param1, int param2, int param3, int param4) { + GL14.glBlendFuncSeparate(param1, param2, param3, param4); + } public void glBufferData(int param1, long param2, int param3) { GL15.glBufferData(param1, param2, param3); diff --git a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MOutputCapsule.java b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MOutputCapsule.java index 7dd6a2a59..01ae2b915 100644 --- a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MOutputCapsule.java +++ b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MOutputCapsule.java @@ -367,7 +367,11 @@ public class J3MOutputCapsule implements OutputCapsule { @Override public void write(int value, String name, int defVal) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + if (value == defVal) { + return; + } + + putParameter(name, Integer.toString(value)); } @Override