Skip to content

Commit

Permalink
#105 - Modified IconComponent and QuadBackgroundComponent to allow th…
Browse files Browse the repository at this point in the history
…e alpha discard

to be set externally and the value now defaults to 0 instead of 0.1.  This is a breaking
change for any UIs relying on the hard-coded alpha discard of 0.1 but that should be the
rarer use-case.
  • Loading branch information
pspeed42 committed Jan 28, 2022
1 parent 8147b97 commit 7f3c3fb
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 43 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ buildscript {

apply plugin: 'java'

version='1.15.1-SNAPSHOT'
version='1.16.0-SNAPSHOT'

ext.jmeVersion='3.1.0-stable'
ext.slf4jVersion = '1.7.32'
Expand Down
14 changes: 12 additions & 2 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
Version 1.15.1 (unreleased)
--------------
Version 1.16.0 (unreleased)
---------------
* Added QuadBackgroundComponent.set/getAlphaDiscard().
Breaking change: QuadBackgroundComponent now defaults to 0 alpha discard
instead of the previous hard-coded 0.1 discard threshold. Discard
should be unnecessary for 2D UIs and may only be rarely necessary for
3D UIs.
* Added IconComponent.set/getAlphaDiscard().
Breaking change: IconComponent now defaults to 0 alpha discard
instead of the previous hard-coded 0.1 discard threshold. Discard
should be unnecessary for 2D UIs and may only be rarely necessary for
3D UIs.


Lemur 1.15.0 (latest)
Expand Down
62 changes: 42 additions & 20 deletions src/main/java/com/simsilica/lemur/component/IconComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public class IconComponent extends AbstractGuiComponent
private float xMargin = 0;
private float yMargin = 0;
private float zOffset = 0.01f;
private float alphaDiscard = 0;
private HAlignment hAlign = HAlignment.Left;
private VAlignment vAlign = VAlignment.Center;
private Vector3f offset = null;
Expand All @@ -85,24 +86,24 @@ public IconComponent( String imagePath, float iconScale,
float xMargin, float yMargin, float zOffset,
boolean lit ) {
this(imagePath, new Vector2f(iconScale, iconScale), xMargin, yMargin,
zOffset, lit);
zOffset, lit);
}

public IconComponent( String imagePath, Vector2f iconScale,
float xMargin, float yMargin, float zOffset,
boolean lit ) {
this(GuiGlobals.getInstance().loadTexture(imagePath, false, false),
iconScale, xMargin, yMargin, zOffset, lit);
}
iconScale, xMargin, yMargin, zOffset, lit);
}

public IconComponent( Texture image, Vector2f iconScale,
float xMargin, float yMargin, float zOffset,
boolean lit ) {
if( image == null ) {
throw new IllegalArgumentException("Image texture cannot be null");
}
// In the case where the 'imagePath' based constructors are called,
// the Text.name is the same as the imagePath provided originally.
// the Text.name is the same as the imagePath provided originally.
this.imagePath = image.getName();
this.image = image;
this.iconScale = iconScale;
Expand Down Expand Up @@ -154,7 +155,7 @@ public void setColor( ColorRGBA c ) {
this.color = c;
resetColor();
}

protected void resetColor() {
if( material == null ) {
return;
Expand Down Expand Up @@ -183,19 +184,19 @@ public void setAlpha( float f ) {
this.alpha = f;
resetColor();
}

@Override
public float getAlpha() {
return alpha;
}

public void setIconScale( float scale ) {
if( scale == this.iconScale.x && scale == this.iconScale.y ) {
return;
}
setIconScale(new Vector2f(scale, scale));
}

public void setIconScale( Vector2f scale ) {
if( this.iconScale.equals(scale) )
return;
Expand Down Expand Up @@ -223,16 +224,16 @@ public void setIconSize( Vector2f iconSize ) {
return;
}
this.iconSize = iconSize;

// Not very efficient
createIcon();

invalidate();
}

public Vector2f getIconSize() {
return iconSize;
}
}

public void setHAlignment( HAlignment a ) {
if( hAlign == a )
Expand Down Expand Up @@ -262,7 +263,7 @@ public void setMargin( float x, float y ) {

invalidate();
}

public void setMargin( Vector2f margin ) {
if( margin == null ) {
throw new IllegalArgumentException("Margin cannot be null");
Expand Down Expand Up @@ -302,6 +303,31 @@ public boolean isOverlay() {
return overlay;
}

/**
* Sets the alphaDiscardThreshold for the image material. If an
* alpha value is below this threshold then it will be discarded
* rather than being written to the color and zbuffers. Set to 0
* to disable. Defaults to 0.
*
* <p>Note: for 2D UIs this threshold is not necessary as 2D GUIs
* will always sort purely back-to-front on Z. For 3D UIs, this
* setting may prevent visual artifacts from certain directions
* for very transparent pixels (background showing through, etc.))</p>
*/
public void setAlphaDiscard( float alphaDiscard ) {
if( this.alphaDiscard == alphaDiscard ) {
return;
}
this.alphaDiscard = alphaDiscard;
if( material != null ) {
material.getMaterial().setFloat("AlphaDiscardThreshold", alphaDiscard);
}
}

public float getAlphaDiscard() {
return alphaDiscard;
}

public GuiMaterial getMaterial() {
return material;
}
Expand Down Expand Up @@ -420,11 +446,7 @@ protected void createIcon() {
material.setTexture(image);

material.getMaterial().getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
// AlphaTest and AlphaFalloff are deprecated in favor of the material
// parameter... in fact in current JME there are no-ops.
//material.getMaterial().getAdditionalRenderState().setAlphaTest(true);
//material.getMaterial().getAdditionalRenderState().setAlphaFallOff(0.01f);
material.getMaterial().setFloat("AlphaDiscardThreshold", 0.1f);
material.getMaterial().setFloat("AlphaDiscardThreshold", alphaDiscard);
}

icon.setMaterial(material.getMaterial());
Expand All @@ -439,7 +461,7 @@ protected void createIcon() {
getNode().attachChild(icon);
}
}

protected Vector2f getEffectiveIconSize() {
if( iconSize != null ) {
return iconSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class QuadBackgroundComponent extends AbstractGuiComponent
private float xMargin = 0;
private float yMargin = 0;
private float zOffset = 0.01f;
private float alphaDiscard = 0;
private boolean lit = false;

// Keep track of any scale we've already applied to the quad
Expand All @@ -70,7 +71,7 @@ public QuadBackgroundComponent() {
this(ColorRGBA.Gray, 0, 0, 0.01f, false);
}

public QuadBackgroundComponent( ColorRGBA color ) {
public QuadBackgroundComponent( ColorRGBA color ) {
this(color, 0, 0, 0.01f, false);
}

Expand All @@ -89,7 +90,7 @@ public QuadBackgroundComponent( ColorRGBA color,
createMaterial();
}

public QuadBackgroundComponent( Texture texture ) {
public QuadBackgroundComponent( Texture texture ) {
this(texture, 0, 0, 0.01f, false);
}

Expand Down Expand Up @@ -136,7 +137,7 @@ public void setColor( ColorRGBA c ) {
this.color = c;
resetColor();
}

protected void resetColor() {
if( material == null ) {
return;
Expand Down Expand Up @@ -165,7 +166,7 @@ public void setAlpha( float f ) {
this.alpha = f;
resetColor();
}

@Override
public float getAlpha() {
return alpha;
Expand Down Expand Up @@ -219,6 +220,31 @@ public float getZOffset() {
return zOffset;
}

/**
* Sets the alphaDiscardThreshold for the image material. If an
* alpha value is below this threshold then it will be discarded
* rather than being written to the color and zbuffers. Set to 0
* to disable. Defaults to 0.
*
* <p>Note: for 2D UIs this threshold is not necessary as 2D GUIs
* will always sort purely back-to-front on Z. For 3D UIs, this
* setting may prevent visual artifacts from certain directions
* for very transparent pixels (background showing through, etc.))</p>
*/
public void setAlphaDiscard( float alphaDiscard ) {
if( this.alphaDiscard == alphaDiscard ) {
return;
}
this.alphaDiscard = alphaDiscard;
if( material != null ) {
material.getMaterial().setFloat("AlphaDiscardThreshold", alphaDiscard);
}
}

public float getAlphaDiscard() {
return alphaDiscard;
}

public GuiMaterial getMaterial() {
return material;
}
Expand Down Expand Up @@ -248,11 +274,7 @@ protected void createMaterial() {
material.setTexture(texture);
}
material.getMaterial().getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
// AlphaTest and AlphaFalloff are deprecated in favor of the material
// parameter... in fact in current JME there are no-ops.
//material.getMaterial().getAdditionalRenderState().setAlphaTest(true);
//material.getMaterial().getAdditionalRenderState().setAlphaFallOff(0.1f);
material.getMaterial().setFloat("AlphaDiscardThreshold", 0.1f);
material.getMaterial().setFloat("AlphaDiscardThreshold", alphaDiscard);
}

protected void refreshBackground( Vector3f size ) {
Expand All @@ -272,13 +294,13 @@ protected void refreshBackground( Vector3f size ) {
// Can't do this even though it seems logical because it
// is just as likely that we are in bucket.gui. It is up to
// the caller to put the main 3D ui in the transparent bucket
//background.setQueueBucket(Bucket.Transparent);
//background.setQueueBucket(Bucket.Transparent);
if( material == null ) {
createMaterial();
}
background.setMaterial(material.getMaterial());
getNode().attachChild(background);

// If we've recreated the spatial then the applied scale
// should be reset also. We could either move slightly different
// scaling logic into the branch and the else branch... or just
Expand All @@ -288,26 +310,26 @@ protected void refreshBackground( Vector3f size ) {
} else {
// Else reset the size of the quad
Quad q = (Quad)background.getMesh();
if( size.x != q.getWidth() || size.y != q.getHeight() ) {
if( size.x != q.getWidth() || size.y != q.getHeight() ) {
q.updateGeometry(size.x, size.y);
q.clearCollisionData();
q.clearCollisionData();
}
}

Vector2f effectiveScale = textureCoordinateScale == null ? Vector2f.UNIT_XY : textureCoordinateScale;
if( !appliedTextureScale.equals(effectiveScale) ) {

// Need to apply new texture coordinate scaling
Mesh m = background.getMesh();

// Unscale what we already scaled
m.scaleTextureCoordinates(new Vector2f(1/appliedTextureScale.x, 1/appliedTextureScale.y));

appliedTextureScale.set(effectiveScale);
// And now apply the latest coordinate scaling.

// And now apply the latest coordinate scaling.
m.scaleTextureCoordinates(appliedTextureScale);

// Note: it's probably safer to have just applied the scale value directly to
// the quad's texture coordinate values instead of multiplying. The above may
// accumulate errors. Still, I thought this would be more future proof and
Expand Down

0 comments on commit 7f3c3fb

Please sign in to comment.