Fixes handling of blend equations and factors in GLRenderer (#848)

* Stronger separation of BlendMode.Custom from the other blend modes
* Custom blend equations and factors now only gets used on BlendMode.Custom
* Updated some JavaDocs in RenderState class
shader-nodes-enhancement
theMinka 7 years ago committed by Rémy Bouquet
parent 2f683c10bc
commit cd7c60cc59
  1. 167
      jme3-core/src/main/java/com/jme3/material/RenderState.java
  2. 29
      jme3-core/src/main/java/com/jme3/renderer/RenderContext.java
  3. 123
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@ -331,9 +331,17 @@ public class RenderState implements Cloneable, Savable {
*/ */
Exclusion, Exclusion,
/** /**
* Allows for custom blending by using glBlendFuncSeparate. * Uses the blend equations and blend factors defined by the render state.
* <p> * <p>
* * These attributes can be set by using the following methods:
* <ul>
* <li>{@link RenderState#setBlendEquation(BlendEquation)}<br/>
* <li>{@link RenderState#setBlendEquationAlpha(BlendEquationAlpha)}<br/>
* <li>{@link RenderState#setCustomBlendFactors(BlendFunc, BlendFunc, BlendFunc, BlendFunc)}<br/>
* </ul>
* <p>
* Result.RGB = BlendEquation( sfactorRGB * Source.RGB , dfactorRGB * Destination.RGB )<br/>
* Result.A = BlendEquationAlpha( sfactorAlpha * Source.A , dfactorAlpha * Destination.A )
*/ */
Custom Custom
} }
@ -425,8 +433,6 @@ public class RenderState implements Cloneable, Savable {
ADDITIONAL.applyDepthWrite = false; ADDITIONAL.applyDepthWrite = false;
ADDITIONAL.applyDepthTest = false; ADDITIONAL.applyDepthTest = false;
ADDITIONAL.applyColorWrite = false; ADDITIONAL.applyColorWrite = false;
ADDITIONAL.applyBlendEquation = false;
ADDITIONAL.applyBlendEquationAlpha = false;
ADDITIONAL.applyBlendMode = false; ADDITIONAL.applyBlendMode = false;
ADDITIONAL.applyPolyOffset = false; ADDITIONAL.applyPolyOffset = false;
} }
@ -441,9 +447,7 @@ public class RenderState implements Cloneable, Savable {
boolean colorWrite = true; boolean colorWrite = true;
boolean applyColorWrite = true; boolean applyColorWrite = true;
BlendEquation blendEquation = BlendEquation.Add; BlendEquation blendEquation = BlendEquation.Add;
boolean applyBlendEquation = true;
BlendEquationAlpha blendEquationAlpha = BlendEquationAlpha.InheritColor; BlendEquationAlpha blendEquationAlpha = BlendEquationAlpha.InheritColor;
boolean applyBlendEquationAlpha = true;
BlendMode blendMode = BlendMode.Off; BlendMode blendMode = BlendMode.Off;
boolean applyBlendMode = true; boolean applyBlendMode = true;
float offsetFactor = 0; float offsetFactor = 0;
@ -466,10 +470,10 @@ public class RenderState implements Cloneable, Savable {
TestFunction frontStencilFunction = TestFunction.Always; TestFunction frontStencilFunction = TestFunction.Always;
TestFunction backStencilFunction = TestFunction.Always; TestFunction backStencilFunction = TestFunction.Always;
int cachedHashCode = -1; int cachedHashCode = -1;
BlendFunc sfactorRGB=BlendFunc.One; BlendFunc sfactorRGB = BlendFunc.One;
BlendFunc dfactorRGB=BlendFunc.Zero; BlendFunc dfactorRGB = BlendFunc.One;
BlendFunc sfactorAlpha=BlendFunc.One; BlendFunc sfactorAlpha = BlendFunc.One;
BlendFunc dfactorAlpha=BlendFunc.Zero; BlendFunc dfactorAlpha = BlendFunc.One;
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
@ -507,8 +511,6 @@ public class RenderState implements Cloneable, Savable {
oc.write(applyDepthWrite, "applyDepthWrite", true); oc.write(applyDepthWrite, "applyDepthWrite", true);
oc.write(applyDepthTest, "applyDepthTest", true); oc.write(applyDepthTest, "applyDepthTest", true);
oc.write(applyColorWrite, "applyColorWrite", true); oc.write(applyColorWrite, "applyColorWrite", true);
oc.write(applyBlendEquation, "applyBlendEquation", true);
oc.write(applyBlendEquationAlpha, "applyBlendEquationAlpha", true);
oc.write(applyBlendMode, "applyBlendMode", true); oc.write(applyBlendMode, "applyBlendMode", true);
oc.write(applyPolyOffset, "applyPolyOffset", true); oc.write(applyPolyOffset, "applyPolyOffset", true);
oc.write(applyDepthFunc, "applyDepthFunc", true); oc.write(applyDepthFunc, "applyDepthFunc", true);
@ -541,9 +543,9 @@ public class RenderState implements Cloneable, Savable {
depthFunc = ic.readEnum("depthFunc", TestFunction.class, TestFunction.LessOrEqual); depthFunc = ic.readEnum("depthFunc", TestFunction.class, TestFunction.LessOrEqual);
lineWidth = ic.readFloat("lineWidth", 1); lineWidth = ic.readFloat("lineWidth", 1);
sfactorRGB = ic.readEnum("sfactorRGB", BlendFunc.class, BlendFunc.One); sfactorRGB = ic.readEnum("sfactorRGB", BlendFunc.class, BlendFunc.One);
dfactorAlpha = ic.readEnum("dfactorRGB", BlendFunc.class, BlendFunc.Zero); dfactorAlpha = ic.readEnum("dfactorRGB", BlendFunc.class, BlendFunc.One);
sfactorRGB = ic.readEnum("sfactorAlpha", BlendFunc.class, BlendFunc.One); sfactorRGB = ic.readEnum("sfactorAlpha", BlendFunc.class, BlendFunc.One);
dfactorAlpha = ic.readEnum("dfactorAlpha", BlendFunc.class, BlendFunc.Zero); dfactorAlpha = ic.readEnum("dfactorAlpha", BlendFunc.class, BlendFunc.One);
applyWireFrame = ic.readBoolean("applyWireFrame", true); applyWireFrame = ic.readBoolean("applyWireFrame", true);
@ -551,14 +553,11 @@ public class RenderState implements Cloneable, Savable {
applyDepthWrite = ic.readBoolean("applyDepthWrite", true); applyDepthWrite = ic.readBoolean("applyDepthWrite", true);
applyDepthTest = ic.readBoolean("applyDepthTest", true); applyDepthTest = ic.readBoolean("applyDepthTest", true);
applyColorWrite = ic.readBoolean("applyColorWrite", true); applyColorWrite = ic.readBoolean("applyColorWrite", true);
applyBlendEquation = ic.readBoolean("applyBlendEquation", true);
applyBlendEquationAlpha = ic.readBoolean("applyBlendEquationAlpha", true);
applyBlendMode = ic.readBoolean("applyBlendMode", true); applyBlendMode = ic.readBoolean("applyBlendMode", true);
applyPolyOffset = ic.readBoolean("applyPolyOffset", true); applyPolyOffset = ic.readBoolean("applyPolyOffset", true);
applyDepthFunc = ic.readBoolean("applyDepthFunc", true); applyDepthFunc = ic.readBoolean("applyDepthFunc", true);
applyLineWidth = ic.readBoolean("applyLineWidth", true); applyLineWidth = ic.readBoolean("applyLineWidth", true);
} }
/** /**
@ -615,18 +614,31 @@ public class RenderState implements Cloneable, Savable {
return false; return false;
} }
if (blendEquation != rs.blendEquation) { if (blendMode != rs.blendMode) {
return false; return false;
} }
if (blendMode == BlendMode.Custom) {
if (blendEquation != rs.blendEquation) {
return false;
}
if (blendEquationAlpha != rs.blendEquationAlpha) { if (blendEquationAlpha != rs.blendEquationAlpha) {
return false; return false;
} }
if (blendMode != rs.blendMode) { if (sfactorRGB != rs.sfactorRGB) {
return false; return false;
} }
if (dfactorRGB != rs.dfactorRGB) {
return false;
}
if (sfactorAlpha != rs.sfactorAlpha) {
return false;
}
if (dfactorAlpha != rs.dfactorAlpha) {
return false;
}
}
if (offsetEnabled != rs.offsetEnabled) { if (offsetEnabled != rs.offsetEnabled) {
return false; return false;
@ -676,14 +688,6 @@ public class RenderState implements Cloneable, Savable {
return false; return false;
} }
if (blendMode.equals(BlendMode.Custom)) {
return sfactorRGB==rs.getCustomSfactorRGB()
&& dfactorRGB==rs.getCustomDfactorRGB()
&& sfactorAlpha==rs.getCustomSfactorAlpha()
&& dfactorAlpha==rs.getCustomDfactorAlpha();
}
return true; return true;
} }
@ -768,27 +772,21 @@ public class RenderState implements Cloneable, Savable {
} }
/** /**
* Set the blending equation. * Set the blending equation for the color component (RGB).
* <p> * <p>
* When blending is enabled, (<code>blendMode</code> is not * The blending equation determines, how the RGB values of the input pixel
* {@link BlendMode#Off}) the input pixel will be blended with the pixel * will be blended with the RGB values of the pixel already in the color buffer.<br/>
* already in the color buffer. The blending equation is determined by the * For example, {@link BlendEquation#Add} will add the input pixel's color
* {@link BlendEquation}. For example, the mode {@link BlendMode#Additive} * to the color already in the color buffer:
* and {@link BlendEquation#Add} will add the input pixel's color to the
* color already in the color buffer:
* <br/> * <br/>
* <code>Result = Source Color + Destination Color</code> * <code>Result = Source Color + Destination Color</code>
* <br/> * <p>
* However, the mode {@link BlendMode#Additive} * <b>Note:</b> This gets only used in {@link BlendMode#Custom} mode.
* and {@link BlendEquation#Subtract} will subtract the input pixel's color to the * All other blend modes will ignore this setting.
* color already in the color buffer:
* <br/>
* <code>Result = Source Color - Destination Color</code>
* *
* @param blendEquation The blend equation to use. * @param blendEquation The {@link BlendEquation} to use.
*/ */
public void setBlendEquation(BlendEquation blendEquation) { public void setBlendEquation(BlendEquation blendEquation) {
applyBlendEquation = true;
this.blendEquation = blendEquation; this.blendEquation = blendEquation;
cachedHashCode = -1; cachedHashCode = -1;
} }
@ -796,44 +794,38 @@ public class RenderState implements Cloneable, Savable {
/** /**
* Set the blending equation for the alpha component. * Set the blending equation for the alpha component.
* <p> * <p>
* When blending is enabled, (<code>blendMode</code> is not * The alpha blending equation determines, how the alpha values of the input pixel
* {@link BlendMode#Off}) the input pixel will be blended with the pixel * will be blended with the alpha values of the pixel already in the color buffer.<br/>
* already in the color buffer. The blending equation is determined by the * For example, {@link BlendEquationAlpha#Add} will add the input pixel's color
* {@link BlendEquation} and can be overrode for the alpha component using * to the color already in the color buffer:
* the {@link BlendEquationAlpha} . For example, the mode
* {@link BlendMode#Additive} and {@link BlendEquationAlpha#Add} will add
* the input pixel's alpha to the alpha component already in the color
* buffer:
* <br/> * <br/>
* <code>Result = Source Alpha + Destination Alpha</code> * <code>Result = Source Color + Destination Color</code>
* <br/> * <p>
* However, the mode {@link BlendMode#Additive} and * <b>Note:</b> This gets only used in {@link BlendMode#Custom} mode.
* {@link BlendEquationAlpha#Subtract} will subtract the input pixel's alpha * All other blend modes will ignore this setting.
* to the alpha component already in the color buffer:
* <br/>
* <code>Result = Source Alpha - Destination Alpha</code>
* *
* @param blendEquationAlpha The blend equation to use for the alpha * @param blendEquationAlpha The {@link BlendEquationAlpha} to use.
* component.
*/ */
public void setBlendEquationAlpha(BlendEquationAlpha blendEquationAlpha) { public void setBlendEquationAlpha(BlendEquationAlpha blendEquationAlpha) {
applyBlendEquationAlpha = true;
this.blendEquationAlpha = blendEquationAlpha; this.blendEquationAlpha = blendEquationAlpha;
cachedHashCode = -1; cachedHashCode = -1;
} }
/** /**
* Sets the custom blend factors for <code>BlendMode.Custom</code> as * Sets the blend factors used for the source and destination color.
* defined by the appropriate <code>BlendFunc</code>. * <p>
* These factors will be multiplied with the color values of the input pixel
* and the pixel already in the color buffer, before both colors gets combined by the {@link BlendEquation}.
* <p>
* <b>Note:</b> This gets only used in {@link BlendMode#Custom} mode.
* All other blend modes will ignore this setting.
* *
* @param sfactorRGB The source blend factor for RGB components. * @param sfactorRGB The source blend factor for RGB components.
* @param dfactorRGB The destination 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 sfactorAlpha The source blend factor for the alpha component.
* @param dfactorAlpha The destination blend factor for the alpha component. * @param dfactorAlpha The destination blend factor for the alpha component.
*/ */
public void setCustomBlendFactors(BlendFunc sfactorRGB, BlendFunc dfactorRGB, BlendFunc sfactorAlpha, BlendFunc dfactorAlpha) public void setCustomBlendFactors(BlendFunc sfactorRGB, BlendFunc dfactorRGB, BlendFunc sfactorAlpha, BlendFunc dfactorAlpha) {
{
this.sfactorRGB = sfactorRGB; this.sfactorRGB = sfactorRGB;
this.dfactorRGB = dfactorRGB; this.dfactorRGB = dfactorRGB;
this.sfactorAlpha = sfactorAlpha; this.sfactorAlpha = sfactorAlpha;
@ -1374,14 +1366,6 @@ public class RenderState implements Cloneable, Savable {
return applyBlendMode; return applyBlendMode;
} }
public boolean isApplyBlendEquation() {
return applyBlendEquation;
}
public boolean isApplyBlendEquationAlpha() {
return applyBlendEquationAlpha;
}
public boolean isApplyColorWrite() { public boolean isApplyColorWrite() {
return applyColorWrite; return applyColorWrite;
} }
@ -1511,27 +1495,26 @@ public class RenderState implements Cloneable, Savable {
} else { } else {
state.colorWrite = colorWrite; state.colorWrite = colorWrite;
} }
if (additionalState.applyBlendEquation) {
state.blendEquation = additionalState.blendEquation;
} else {
state.blendEquation = blendEquation;
}
if (additionalState.applyBlendEquationAlpha) {
state.blendEquationAlpha = additionalState.blendEquationAlpha;
} else {
state.blendEquationAlpha = blendEquationAlpha;
}
if (additionalState.applyBlendMode) { if (additionalState.applyBlendMode) {
state.blendMode = additionalState.blendMode; state.blendMode = additionalState.blendMode;
if (additionalState.getBlendMode().equals(BlendMode.Custom)) { if (additionalState.blendMode == BlendMode.Custom) {
state.setCustomBlendFactors( state.blendEquation = additionalState.blendEquation;
additionalState.getCustomSfactorRGB(), state.blendEquationAlpha = additionalState.blendEquationAlpha;
additionalState.getCustomDfactorRGB(), state.sfactorRGB = additionalState.sfactorRGB;
additionalState.getCustomSfactorAlpha(), state.dfactorRGB = additionalState.dfactorRGB;
additionalState.getCustomDfactorAlpha()); state.sfactorAlpha = additionalState.sfactorAlpha;
state.dfactorAlpha = additionalState.dfactorAlpha;
} }
} else { } else {
state.blendMode = blendMode; state.blendMode = blendMode;
if (blendMode == BlendMode.Custom) {
state.blendEquation = blendEquation;
state.blendEquationAlpha = blendEquationAlpha;
state.sfactorRGB = sfactorRGB;
state.dfactorRGB = dfactorRGB;
state.sfactorAlpha = sfactorAlpha;
state.dfactorAlpha = dfactorAlpha;
}
} }
if (additionalState.applyPolyOffset) { if (additionalState.applyPolyOffset) {
@ -1608,8 +1591,6 @@ public class RenderState implements Cloneable, Savable {
applyDepthWrite = true; applyDepthWrite = true;
applyDepthTest = true; applyDepthTest = true;
applyColorWrite = true; applyColorWrite = true;
applyBlendEquation = true;
applyBlendEquationAlpha = true;
applyBlendMode = true; applyBlendMode = true;
applyPolyOffset = true; applyPolyOffset = true;
applyDepthFunc = true; applyDepthFunc = true;
@ -1636,8 +1617,6 @@ public class RenderState implements Cloneable, Savable {
+ "\ncolorWrite=" + colorWrite + "\ncolorWrite=" + colorWrite
+ "\napplyColorWrite=" + applyColorWrite + "\napplyColorWrite=" + applyColorWrite
+ "\nblendEquation=" + blendEquation + "\nblendEquation=" + blendEquation
+ "\napplyBlendEquation=" + applyBlendEquation
+ "\napplyBlendEquationAlpha=" + applyBlendEquationAlpha
+ "\nblendMode=" + blendMode + "\nblendMode=" + blendMode
+ "\napplyBlendMode=" + applyBlendMode + "\napplyBlendMode=" + applyBlendMode
+ "\noffsetEnabled=" + offsetEnabled + "\noffsetEnabled=" + offsetEnabled

@ -32,6 +32,7 @@
package com.jme3.renderer; package com.jme3.renderer;
import com.jme3.material.RenderState; import com.jme3.material.RenderState;
import com.jme3.material.RenderState.BlendFunc;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.scene.Mesh; import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer;
@ -110,6 +111,30 @@ public class RenderContext {
*/ */
public RenderState.BlendEquationAlpha blendEquationAlpha = RenderState.BlendEquationAlpha.InheritColor; public RenderState.BlendEquationAlpha blendEquationAlpha = RenderState.BlendEquationAlpha.InheritColor;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc sfactorRGB = RenderState.BlendFunc.One;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc dfactorRGB = RenderState.BlendFunc.One;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc sfactorAlpha = RenderState.BlendFunc.One;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc dfactorAlpha = RenderState.BlendFunc.One;
/** /**
* @see RenderState#setWireframe(boolean) * @see RenderState#setWireframe(boolean)
*/ */
@ -266,6 +291,10 @@ public class RenderContext {
blendMode = RenderState.BlendMode.Off; blendMode = RenderState.BlendMode.Off;
blendEquation = RenderState.BlendEquation.Add; blendEquation = RenderState.BlendEquation.Add;
blendEquationAlpha = RenderState.BlendEquationAlpha.InheritColor; blendEquationAlpha = RenderState.BlendEquationAlpha.InheritColor;
sfactorRGB = BlendFunc.One;
dfactorRGB = BlendFunc.One;
sfactorAlpha = BlendFunc.One;
dfactorAlpha = BlendFunc.One;
wireframe = false; wireframe = false;
boundShaderProgram = 0; boundShaderProgram = 0;
boundShader = null; boundShader = null;

@ -33,6 +33,7 @@ package com.jme3.renderer.opengl;
import com.jme3.material.RenderState; import com.jme3.material.RenderState;
import com.jme3.material.RenderState.BlendFunc; import com.jme3.material.RenderState.BlendFunc;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.RenderState.StencilOperation; import com.jme3.material.RenderState.StencilOperation;
import com.jme3.material.RenderState.TestFunction; import com.jme3.material.RenderState.TestFunction;
import com.jme3.math.*; import com.jme3.math.*;
@ -743,68 +744,57 @@ public final class GLRenderer implements Renderer {
context.cullMode = state.getFaceCullMode(); context.cullMode = state.getFaceCullMode();
} }
if (state.getBlendMode() != context.blendMode) { // Always update the blend equations and factors when using custom blend mode.
if (state.getBlendMode() == RenderState.BlendMode.Off) { if (state.getBlendMode() == BlendMode.Custom) {
gl.glDisable(GL.GL_BLEND); changeBlendMode(BlendMode.Custom);
} else {
if (context.blendMode == RenderState.BlendMode.Off) { blendFuncSeparate(
gl.glEnable(GL.GL_BLEND); state.getCustomSfactorRGB(),
} state.getCustomDfactorRGB(),
state.getCustomSfactorAlpha(),
state.getCustomDfactorAlpha());
blendEquationSeparate(state.getBlendEquation(), state.getBlendEquationAlpha());
// Update the blend equations and factors only on a mode change for all the other (common) blend modes.
} else if (state.getBlendMode() != context.blendMode) {
changeBlendMode(state.getBlendMode());
switch (state.getBlendMode()) { switch (state.getBlendMode()) {
case Off: case Off:
break; break;
case Additive: case Additive:
gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); blendFunc(RenderState.BlendFunc.One, RenderState.BlendFunc.One);
break; break;
case AlphaAdditive: case AlphaAdditive:
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); blendFunc(RenderState.BlendFunc.Src_Alpha, RenderState.BlendFunc.One);
break; break;
case Alpha: case Alpha:
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); blendFunc(RenderState.BlendFunc.Src_Alpha, RenderState.BlendFunc.One_Minus_Src_Alpha);
break; break;
case PremultAlpha: case PremultAlpha:
gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA); blendFunc(RenderState.BlendFunc.One, RenderState.BlendFunc.One_Minus_Src_Alpha);
break; break;
case Modulate: case Modulate:
gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_ZERO); blendFunc(RenderState.BlendFunc.Dst_Color, RenderState.BlendFunc.Zero);
break; break;
case ModulateX2: case ModulateX2:
gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_SRC_COLOR); blendFunc(RenderState.BlendFunc.Dst_Color, RenderState.BlendFunc.Src_Color);
break; break;
case Color: case Color:
case Screen: case Screen:
gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_COLOR); blendFunc(RenderState.BlendFunc.One, RenderState.BlendFunc.One_Minus_Src_Color);
break; break;
case Exclusion: case Exclusion:
gl.glBlendFunc(GL.GL_ONE_MINUS_DST_COLOR, GL.GL_ONE_MINUS_SRC_COLOR); blendFunc(RenderState.BlendFunc.One_Minus_Dst_Color, RenderState.BlendFunc.One_Minus_Src_Color);
break;
case Custom:
gl.glBlendFuncSeparate(
convertBlendFunc(state.getCustomSfactorRGB()),
convertBlendFunc(state.getCustomDfactorRGB()),
convertBlendFunc(state.getCustomSfactorAlpha()),
convertBlendFunc(state.getCustomDfactorAlpha()));
break; break;
default: default:
throw new UnsupportedOperationException("Unrecognized blend mode: " throw new UnsupportedOperationException("Unrecognized blend mode: "
+ state.getBlendMode()); + state.getBlendMode());
} }
if (state.getBlendEquation() != context.blendEquation || state.getBlendEquationAlpha() != context.blendEquationAlpha) { // All of the common modes requires the ADD equation.
int colorMode = convertBlendEquation(state.getBlendEquation()); // (This might change in the future?)
int alphaMode; blendEquationSeparate(RenderState.BlendEquation.Add, RenderState.BlendEquationAlpha.InheritColor);
if (state.getBlendEquationAlpha() == RenderState.BlendEquationAlpha.InheritColor) {
alphaMode = colorMode;
} else {
alphaMode = convertBlendEquationAlpha(state.getBlendEquationAlpha());
}
gl.glBlendEquationSeparate(colorMode, alphaMode);
context.blendEquation = state.getBlendEquation();
context.blendEquationAlpha = state.getBlendEquationAlpha();
}
}
context.blendMode = state.getBlendMode();
} }
if (context.stencilTest != state.isStencilTest() if (context.stencilTest != state.isStencilTest()
@ -852,6 +842,65 @@ public final class GLRenderer implements Renderer {
} }
} }
private void changeBlendMode(RenderState.BlendMode blendMode) {
if (blendMode != context.blendMode) {
if (blendMode == RenderState.BlendMode.Off) {
gl.glDisable(GL.GL_BLEND);
} else if (context.blendMode == RenderState.BlendMode.Off) {
gl.glEnable(GL.GL_BLEND);
}
context.blendMode = blendMode;
}
}
private void blendEquationSeparate(RenderState.BlendEquation blendEquation, RenderState.BlendEquationAlpha blendEquationAlpha) {
if (blendEquation != context.blendEquation || blendEquationAlpha != context.blendEquationAlpha) {
int glBlendEquation = convertBlendEquation(blendEquation);
int glBlendEquationAlpha = blendEquationAlpha == RenderState.BlendEquationAlpha.InheritColor
? glBlendEquation
: convertBlendEquationAlpha(blendEquationAlpha);
gl.glBlendEquationSeparate(glBlendEquation, glBlendEquationAlpha);
context.blendEquation = blendEquation;
context.blendEquationAlpha = blendEquationAlpha;
}
}
private void blendFunc(RenderState.BlendFunc sfactor, RenderState.BlendFunc dfactor) {
if (sfactor != context.sfactorRGB
|| dfactor != context.dfactorRGB
|| sfactor != context.sfactorAlpha
|| dfactor != context.dfactorAlpha) {
gl.glBlendFunc(
convertBlendFunc(sfactor),
convertBlendFunc(dfactor));
context.sfactorRGB = sfactor;
context.dfactorRGB = dfactor;
context.sfactorAlpha = sfactor;
context.dfactorAlpha = dfactor;
}
}
private void blendFuncSeparate(RenderState.BlendFunc sfactorRGB, RenderState.BlendFunc dfactorRGB,
RenderState.BlendFunc sfactorAlpha, RenderState.BlendFunc dfactorAlpha) {
if (sfactorRGB != context.sfactorRGB
|| dfactorRGB != context.dfactorRGB
|| sfactorAlpha != context.sfactorAlpha
|| dfactorAlpha != context.dfactorAlpha) {
gl.glBlendFuncSeparate(
convertBlendFunc(sfactorRGB),
convertBlendFunc(dfactorRGB),
convertBlendFunc(sfactorAlpha),
convertBlendFunc(dfactorAlpha));
context.sfactorRGB = sfactorRGB;
context.dfactorRGB = dfactorRGB;
context.sfactorAlpha = sfactorAlpha;
context.dfactorAlpha = dfactorAlpha;
}
}
private int convertBlendEquation(RenderState.BlendEquation blendEquation) { private int convertBlendEquation(RenderState.BlendEquation blendEquation) {
switch (blendEquation) { switch (blendEquation) {
case Add: case Add:

Loading…
Cancel
Save