* Materials.equals() method now works correctly (checking if material will look the same if rendered, in 99.9% of cases..)
* ListMap entries now implement equals method as required by spec git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9289 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
c3ed68cfbb
commit
ddca06e607
@ -328,21 +328,36 @@ When arrays can be inserted in J3M files
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object obj) {
|
||||||
if (!(other instanceof MatParam)) {
|
if (obj == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
MatParam otherParam = (MatParam) other;
|
return false;
|
||||||
return otherParam.type == type
|
}
|
||||||
&& otherParam.name.equals(name);
|
final MatParam other = (MatParam) obj;
|
||||||
|
if (this.type != other.type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.value != other.value && (this.value == null || !this.value.equals(other.value))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.ffBinding != other.ffBinding) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 5;
|
int hash = 7;
|
||||||
hash = 17 * hash + (this.type != null ? this.type.hashCode() : 0);
|
hash = 59 * hash + (this.type != null ? this.type.hashCode() : 0);
|
||||||
hash = 17 * hash + (this.name != null ? this.name.hashCode() : 0);
|
hash = 59 * hash + (this.name != null ? this.name.hashCode() : 0);
|
||||||
|
hash = 59 * hash + (this.value != null ? this.value.hashCode() : 0);
|
||||||
|
hash = 59 * hash + (this.ffBinding != null ? this.ffBinding.hashCode() : 0);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.material;
|
package com.jme3.material;
|
||||||
|
|
||||||
import com.jme3.asset.Asset;
|
import com.jme3.asset.CloneableSmartAsset;
|
||||||
import com.jme3.asset.AssetKey;
|
import com.jme3.asset.AssetKey;
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.export.*;
|
import com.jme3.export.*;
|
||||||
@ -63,9 +63,10 @@ import java.util.logging.Logger;
|
|||||||
* Setting the parameters can modify the behavior of a
|
* Setting the parameters can modify the behavior of a
|
||||||
* shader.
|
* shader.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class Material implements Asset, Cloneable, Savable, Comparable<Material> {
|
public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||||
|
|
||||||
// Version #2: Fixed issue with RenderState.apply*** flags not getting exported
|
// Version #2: Fixed issue with RenderState.apply*** flags not getting exported
|
||||||
public static final int SAVABLE_VERSION = 2;
|
public static final int SAVABLE_VERSION = 2;
|
||||||
@ -188,27 +189,6 @@ public class Material implements Asset, Cloneable, Savable, Comparable<Material>
|
|||||||
return sortingId;
|
return sortingId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses the sorting ID for each material to compare them.
|
|
||||||
*
|
|
||||||
* @param m The other material to compare to.
|
|
||||||
*
|
|
||||||
* @return zero if the materials are equal, returns a negative value
|
|
||||||
* if <code>this</code> has a lower sorting ID than <code>m</code>,
|
|
||||||
* otherwise returns a positive value.
|
|
||||||
*/
|
|
||||||
public int compareTo(Material m) {
|
|
||||||
return m.getSortId() - getSortId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj instanceof Material) {
|
|
||||||
return ((Material) obj).compareTo(this) == 0;
|
|
||||||
}
|
|
||||||
return super.equals(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clones this material. The result is returned.
|
* Clones this material. The result is returned.
|
||||||
*/
|
*/
|
||||||
@ -237,77 +217,84 @@ public class Material implements Asset, Cloneable, Savable, Comparable<Material>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares two materials and returns true if they are equal.
|
* Compares two materials and returns true if they are equal.
|
||||||
* This methods compare definition, params, additional render states
|
* This methods compare definition, parameters, additional render states
|
||||||
* The difference with the equals method is that it's truely comaring the objects. (equals compare the sort ids for geometry sorting)
|
*
|
||||||
* @param mat the material to cmpare to this material
|
* @param otherObj the material to compare to this material
|
||||||
* @return true if the materials are equal.
|
* @return true if the materials are equal.
|
||||||
*/
|
*/
|
||||||
public boolean isEqual(Material mat) {
|
@Override
|
||||||
//early exit if the material are the same object
|
public boolean equals(Object otherObj) {
|
||||||
if (this == mat) {
|
if (!(otherObj instanceof Material)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Material other = (Material) otherObj;
|
||||||
|
|
||||||
|
// Early exit if the material are the same object
|
||||||
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check material definition
|
||||||
//comparing matrial definition
|
if (this.getMaterialDef() != other.getMaterialDef()) {
|
||||||
if (this.getMaterialDef() != mat.getMaterialDef()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//early exit if the size of the params is different
|
// Early exit if the size of the params is different
|
||||||
if (paramValues.size() != mat.paramValues.size()) {
|
if (this.paramValues.size() != other.paramValues.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//comparing params
|
// 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
|
||||||
|
// are not equal.
|
||||||
|
String thisDefName = this.technique != null ? this.technique.getDef().getName() : null;
|
||||||
|
String otherDefName = other.technique != null ? other.technique.getDef().getName() : null;
|
||||||
|
if (!thisDefName.equals(otherDefName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparing parameters
|
||||||
for (String paramKey : paramValues.keySet()) {
|
for (String paramKey : paramValues.keySet()) {
|
||||||
MatParam paramOrig = getParam(paramKey);
|
MatParam thisParam = this.getParam(paramKey);
|
||||||
MatParam param = mat.getParam(paramKey);
|
MatParam otherParam = other.getParam(paramKey);
|
||||||
//this param does not exist in compared mat
|
|
||||||
if (param == null) {
|
// This param does not exist in compared mat
|
||||||
|
if (otherParam == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//params exist in both materials but they not of the same type
|
if (!otherParam.equals(thisParam)) {
|
||||||
if (param.type != paramOrig.type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param instanceof MatParamTexture) {
|
|
||||||
MatParamTexture tex = (MatParamTexture) param;
|
|
||||||
MatParamTexture texOrig = (MatParamTexture) paramOrig;
|
|
||||||
//comparing textures
|
|
||||||
if (getTextureId(tex) != getTextureId(texOrig)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!param.getValue().equals(paramOrig.getValue())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// Comparing additional render states
|
||||||
//comparing additional render states
|
|
||||||
if (additionalState == null) {
|
if (additionalState == null) {
|
||||||
if (mat.additionalState != null) {
|
if (other.additionalState != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!additionalState.equals(mat.additionalState)) {
|
if (!additionalState.equals(other.additionalState)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getTextureId(MatParamTexture param) {
|
@Override
|
||||||
if (param.getTextureValue() != null && param.getTextureValue().getImage() != null) {
|
public int hashCode() {
|
||||||
return param.getTextureValue().getImage().getId();
|
int hash = 7;
|
||||||
}
|
hash = 29 * hash + (this.def != null ? this.def.hashCode() : 0);
|
||||||
return -1;
|
hash = 29 * hash + (this.paramValues != null ? this.paramValues.hashCode() : 0);
|
||||||
|
hash = 29 * hash + (this.technique != null ? this.technique.getDef().getName().hashCode() : 0);
|
||||||
|
hash = 29 * hash + (this.additionalState != null ? this.additionalState.hashCode() : 0);
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -701,18 +688,17 @@ public class Material implements Asset, Cloneable, Savable, Comparable<Material>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads the lights in the light list as two uniform arrays.<br/><br/>
|
* Uploads the lights in the light list as two uniform arrays.<br/><br/> *
|
||||||
* * <p>
|
* <p>
|
||||||
* <code>uniform vec4 g_LightColor[numLights];</code><br/>
|
* <code>uniform vec4 g_LightColor[numLights];</code><br/> //
|
||||||
* // g_LightColor.rgb is the diffuse/specular color of the light.<br/>
|
* g_LightColor.rgb is the diffuse/specular color of the light.<br/> //
|
||||||
* // g_Lightcolor.a is the type of light, 0 = Directional, 1 = Point, <br/>
|
* g_Lightcolor.a is the type of light, 0 = Directional, 1 = Point, <br/> //
|
||||||
* // 2 = Spot. <br/>
|
* 2 = Spot. <br/> <br/>
|
||||||
* <br/>
|
* <code>uniform vec4 g_LightPosition[numLights];</code><br/> //
|
||||||
* <code>uniform vec4 g_LightPosition[numLights];</code><br/>
|
* g_LightPosition.xyz is the position of the light (for point lights)<br/>
|
||||||
* // g_LightPosition.xyz is the position of the light (for point lights)<br/>
|
* // or the direction of the light (for directional lights).<br/> //
|
||||||
* // or the direction of the light (for directional lights).<br/>
|
* g_LightPosition.w is the inverse radius (1/r) of the light (for
|
||||||
* // g_LightPosition.w is the inverse radius (1/r) of the light (for attenuation) <br/>
|
* attenuation) <br/> </p>
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
protected void updateLightListUniforms(Shader shader, Geometry g, int numLights) {
|
protected void updateLightListUniforms(Shader shader, Geometry g, int numLights) {
|
||||||
if (numLights == 0) { // this shader does not do lighting, ignore.
|
if (numLights == 0) { // this shader does not do lighting, ignore.
|
||||||
|
@ -304,6 +304,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
StencilOperation backStencilDepthPassOperation = StencilOperation.Keep;
|
StencilOperation backStencilDepthPassOperation = StencilOperation.Keep;
|
||||||
TestFunction frontStencilFunction = TestFunction.Always;
|
TestFunction frontStencilFunction = TestFunction.Always;
|
||||||
TestFunction backStencilFunction = TestFunction.Always;
|
TestFunction backStencilFunction = TestFunction.Always;
|
||||||
|
int cachedHashCode = -1;
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
@ -505,6 +506,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setPointSprite(boolean pointSprite) {
|
public void setPointSprite(boolean pointSprite) {
|
||||||
applyPointSprite = true;
|
applyPointSprite = true;
|
||||||
this.pointSprite = pointSprite;
|
this.pointSprite = pointSprite;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -522,6 +524,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setAlphaFallOff(float alphaFallOff) {
|
public void setAlphaFallOff(float alphaFallOff) {
|
||||||
applyAlphaFallOff = true;
|
applyAlphaFallOff = true;
|
||||||
this.alphaFallOff = alphaFallOff;
|
this.alphaFallOff = alphaFallOff;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -539,6 +542,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setAlphaTest(boolean alphaTest) {
|
public void setAlphaTest(boolean alphaTest) {
|
||||||
applyAlphaTest = true;
|
applyAlphaTest = true;
|
||||||
this.alphaTest = alphaTest;
|
this.alphaTest = alphaTest;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -553,6 +557,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setColorWrite(boolean colorWrite) {
|
public void setColorWrite(boolean colorWrite) {
|
||||||
applyColorWrite = true;
|
applyColorWrite = true;
|
||||||
this.colorWrite = colorWrite;
|
this.colorWrite = colorWrite;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -570,6 +575,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setFaceCullMode(FaceCullMode cullMode) {
|
public void setFaceCullMode(FaceCullMode cullMode) {
|
||||||
applyCullMode = true;
|
applyCullMode = true;
|
||||||
this.cullMode = cullMode;
|
this.cullMode = cullMode;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -589,6 +595,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setBlendMode(BlendMode blendMode) {
|
public void setBlendMode(BlendMode blendMode) {
|
||||||
applyBlendMode = true;
|
applyBlendMode = true;
|
||||||
this.blendMode = blendMode;
|
this.blendMode = blendMode;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -604,6 +611,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setDepthTest(boolean depthTest) {
|
public void setDepthTest(boolean depthTest) {
|
||||||
applyDepthTest = true;
|
applyDepthTest = true;
|
||||||
this.depthTest = depthTest;
|
this.depthTest = depthTest;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -618,6 +626,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setDepthWrite(boolean depthWrite) {
|
public void setDepthWrite(boolean depthWrite) {
|
||||||
applyDepthWrite = true;
|
applyDepthWrite = true;
|
||||||
this.depthWrite = depthWrite;
|
this.depthWrite = depthWrite;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -632,6 +641,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
public void setWireframe(boolean wireframe) {
|
public void setWireframe(boolean wireframe) {
|
||||||
applyWireFrame = true;
|
applyWireFrame = true;
|
||||||
this.wireframe = wireframe;
|
this.wireframe = wireframe;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -651,6 +661,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
offsetEnabled = true;
|
offsetEnabled = true;
|
||||||
offsetFactor = factor;
|
offsetFactor = factor;
|
||||||
offsetUnits = units;
|
offsetUnits = units;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -699,6 +710,7 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
this.backStencilDepthPassOperation = _backStencilDepthPassOperation;
|
this.backStencilDepthPassOperation = _backStencilDepthPassOperation;
|
||||||
this.frontStencilFunction = _frontStencilFunction;
|
this.frontStencilFunction = _frontStencilFunction;
|
||||||
this.backStencilFunction = _backStencilFunction;
|
this.backStencilFunction = _backStencilFunction;
|
||||||
|
cachedHashCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1032,6 +1044,36 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
return applyWireFrame;
|
return applyWireFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (cachedHashCode == -1){
|
||||||
|
int hash = 7;
|
||||||
|
hash = 79 * hash + (this.pointSprite ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.wireframe ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.cullMode != null ? this.cullMode.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.depthWrite ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.depthTest ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.colorWrite ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.blendMode != null ? this.blendMode.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.alphaTest ? 1 : 0);
|
||||||
|
hash = 79 * hash + Float.floatToIntBits(this.alphaFallOff);
|
||||||
|
hash = 79 * hash + Float.floatToIntBits(this.offsetFactor);
|
||||||
|
hash = 79 * hash + Float.floatToIntBits(this.offsetUnits);
|
||||||
|
hash = 79 * hash + (this.offsetEnabled ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.stencilTest ? 1 : 0);
|
||||||
|
hash = 79 * hash + (this.frontStencilStencilFailOperation != null ? this.frontStencilStencilFailOperation.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.frontStencilDepthFailOperation != null ? this.frontStencilDepthFailOperation.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.frontStencilDepthPassOperation != null ? this.frontStencilDepthPassOperation.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.backStencilStencilFailOperation != null ? this.backStencilStencilFailOperation.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.backStencilDepthFailOperation != null ? this.backStencilDepthFailOperation.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.backStencilDepthPassOperation != null ? this.backStencilDepthPassOperation.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.frontStencilFunction != null ? this.frontStencilFunction.hashCode() : 0);
|
||||||
|
hash = 79 * hash + (this.backStencilFunction != null ? this.backStencilFunction.hashCode() : 0);
|
||||||
|
cachedHashCode = hash;
|
||||||
|
}
|
||||||
|
return cachedHashCode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges <code>this</code> state and <code>additionalState</code> into
|
* Merges <code>this</code> state and <code>additionalState</code> into
|
||||||
* the parameter <code>state</code> based on a specific criteria.
|
* the parameter <code>state</code> based on a specific criteria.
|
||||||
@ -1141,11 +1183,35 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
state.frontStencilFunction = frontStencilFunction;
|
state.frontStencilFunction = frontStencilFunction;
|
||||||
state.backStencilFunction = backStencilFunction;
|
state.backStencilFunction = backStencilFunction;
|
||||||
}
|
}
|
||||||
|
state.cachedHashCode = -1;
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RenderState[\n" + "pointSprite=" + pointSprite + "\napplyPointSprite=" + applyPointSprite + "\nwireframe=" + wireframe + "\napplyWireFrame=" + applyWireFrame + "\ncullMode=" + cullMode + "\napplyCullMode=" + applyCullMode + "\ndepthWrite=" + depthWrite + "\napplyDepthWrite=" + applyDepthWrite + "\ndepthTest=" + depthTest + "\napplyDepthTest=" + applyDepthTest + "\ncolorWrite=" + colorWrite + "\napplyColorWrite=" + applyColorWrite + "\nblendMode=" + blendMode + "\napplyBlendMode=" + applyBlendMode + "\nalphaTest=" + alphaTest + "\napplyAlphaTest=" + applyAlphaTest + "\nalphaFallOff=" + alphaFallOff + "\napplyAlphaFallOff=" + applyAlphaFallOff + "\noffsetEnabled=" + offsetEnabled + "\napplyPolyOffset=" + applyPolyOffset + "\noffsetFactor=" + offsetFactor + "\noffsetUnits=" + offsetUnits + "\n]";
|
return "RenderState[\n"
|
||||||
|
+ "pointSprite=" + pointSprite
|
||||||
|
+ "\napplyPointSprite=" + applyPointSprite
|
||||||
|
+ "\nwireframe=" + wireframe
|
||||||
|
+ "\napplyWireFrame=" + applyWireFrame
|
||||||
|
+ "\ncullMode=" + cullMode
|
||||||
|
+ "\napplyCullMode=" + applyCullMode
|
||||||
|
+ "\ndepthWrite=" + depthWrite
|
||||||
|
+ "\napplyDepthWrite=" + applyDepthWrite
|
||||||
|
+ "\ndepthTest=" + depthTest
|
||||||
|
+ "\napplyDepthTest=" + applyDepthTest
|
||||||
|
+ "\ncolorWrite=" + colorWrite
|
||||||
|
+ "\napplyColorWrite=" + applyColorWrite
|
||||||
|
+ "\nblendMode=" + blendMode
|
||||||
|
+ "\napplyBlendMode=" + applyBlendMode
|
||||||
|
+ "\nalphaTest=" + alphaTest
|
||||||
|
+ "\napplyAlphaTest=" + applyAlphaTest
|
||||||
|
+ "\nalphaFallOff=" + alphaFallOff
|
||||||
|
+ "\napplyAlphaFallOff=" + applyAlphaFallOff
|
||||||
|
+ "\noffsetEnabled=" + offsetEnabled
|
||||||
|
+ "\napplyPolyOffset=" + applyPolyOffset
|
||||||
|
+ "\noffsetFactor=" + offsetFactor
|
||||||
|
+ "\noffsetUnits=" + offsetUnits
|
||||||
|
+ "\n]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,12 @@ public enum Caps {
|
|||||||
/**
|
/**
|
||||||
* Supports multisampling on the screen
|
* Supports multisampling on the screen
|
||||||
*/
|
*/
|
||||||
Multisample;
|
Multisample,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supports FBO with Depth24Stencil8 image format
|
||||||
|
*/
|
||||||
|
PackedDepthStencilBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if given the renderer capabilities, the texture
|
* Returns true if given the renderer capabilities, the texture
|
||||||
@ -251,6 +256,8 @@ public enum Caps {
|
|||||||
|
|
||||||
Format fmt = img.getFormat();
|
Format fmt = img.getFormat();
|
||||||
switch (fmt){
|
switch (fmt){
|
||||||
|
case Depth24Stencil8:
|
||||||
|
return caps.contains(Caps.PackedDepthStencilBuffer);
|
||||||
case Depth32F:
|
case Depth32F:
|
||||||
return caps.contains(Caps.FloatDepthBuffer);
|
return caps.contains(Caps.FloatDepthBuffer);
|
||||||
case LATC:
|
case LATC:
|
||||||
@ -269,6 +276,29 @@ public enum Caps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean supportsColorBuffer(Collection<Caps> caps, RenderBuffer colorBuf){
|
||||||
|
Format colorFmt = colorBuf.getFormat();
|
||||||
|
if (colorFmt.isDepthFormat())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (colorFmt.isCompressed())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (colorFmt){
|
||||||
|
case RGB111110F:
|
||||||
|
return caps.contains(Caps.PackedFloatColorBuffer);
|
||||||
|
case RGB16F_to_RGB111110F:
|
||||||
|
case RGB16F_to_RGB9E5:
|
||||||
|
case RGB9E5:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
if (colorFmt.isFloatingPont())
|
||||||
|
return caps.contains(Caps.FloatColorBuffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if given the renderer capabilities, the framebuffer
|
* Returns true if given the renderer capabilities, the framebuffer
|
||||||
* can be supported by the renderer.
|
* can be supported by the renderer.
|
||||||
@ -285,9 +315,7 @@ public enum Caps {
|
|||||||
&& !caps.contains(Caps.FrameBufferMultisample))
|
&& !caps.contains(Caps.FrameBufferMultisample))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RenderBuffer colorBuf = fb.getColorBuffer();
|
|
||||||
RenderBuffer depthBuf = fb.getDepthBuffer();
|
RenderBuffer depthBuf = fb.getDepthBuffer();
|
||||||
|
|
||||||
if (depthBuf != null){
|
if (depthBuf != null){
|
||||||
Format depthFmt = depthBuf.getFormat();
|
Format depthFmt = depthBuf.getFormat();
|
||||||
if (!depthFmt.isDepthFormat()){
|
if (!depthFmt.isDepthFormat()){
|
||||||
@ -296,28 +324,15 @@ public enum Caps {
|
|||||||
if (depthFmt == Format.Depth32F
|
if (depthFmt == Format.Depth32F
|
||||||
&& !caps.contains(Caps.FloatDepthBuffer))
|
&& !caps.contains(Caps.FloatDepthBuffer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (depthFmt == Format.Depth24Stencil8
|
||||||
|
&& !caps.contains(Caps.PackedDepthStencilBuffer))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (colorBuf != null){
|
for (int i = 0; i < fb.getNumColorBuffers(); i++){
|
||||||
Format colorFmt = colorBuf.getFormat();
|
if (!supportsColorBuffer(caps, fb.getColorBuffer(i))){
|
||||||
if (colorFmt.isDepthFormat())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (colorFmt.isCompressed())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (colorFmt){
|
|
||||||
case RGB111110F:
|
|
||||||
return caps.contains(Caps.PackedFloatColorBuffer);
|
|
||||||
case RGB16F_to_RGB111110F:
|
|
||||||
case RGB16F_to_RGB9E5:
|
|
||||||
case RGB9E5:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
if (colorFmt.isFloatingPont())
|
|
||||||
return caps.contains(Caps.FloatColorBuffer);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -74,9 +74,8 @@ public class OpaqueComparator implements GeometryComparator {
|
|||||||
Material m1 = o1.getMaterial();
|
Material m1 = o1.getMaterial();
|
||||||
Material m2 = o2.getMaterial();
|
Material m2 = o2.getMaterial();
|
||||||
|
|
||||||
int sortId = m1.compareTo(m2);
|
int compareResult = m2.getSortId() - m1.getSortId();
|
||||||
|
if (compareResult == 0){
|
||||||
if (sortId == 0){
|
|
||||||
// use the same shader.
|
// use the same shader.
|
||||||
// sort front-to-back then.
|
// sort front-to-back then.
|
||||||
float d1 = distanceToCam(o1);
|
float d1 = distanceToCam(o1);
|
||||||
@ -89,7 +88,7 @@ public class OpaqueComparator implements GeometryComparator {
|
|||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
return sortId;
|
return compareResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ public class BatchNode extends Node implements Savable {
|
|||||||
if (list == null) {
|
if (list == null) {
|
||||||
//trying to compare materials with the isEqual method
|
//trying to compare materials with the isEqual method
|
||||||
for ( Map.Entry<Material, List<Geometry>> mat : map.entrySet()) {
|
for ( Map.Entry<Material, List<Geometry>> mat : map.entrySet()) {
|
||||||
if (g.getMaterial().isEqual(mat.getKey())) {
|
if (g.getMaterial().equals(mat.getKey())) {
|
||||||
list = mat.getValue();
|
list = mat.getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
package com.jme3.texture;
|
package com.jme3.texture;
|
||||||
|
|
||||||
import com.jme3.export.*;
|
import com.jme3.export.*;
|
||||||
|
import com.jme3.renderer.Caps;
|
||||||
import com.jme3.renderer.Renderer;
|
import com.jme3.renderer.Renderer;
|
||||||
import com.jme3.util.NativeObject;
|
import com.jme3.util.NativeObject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -255,7 +256,13 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ {
|
|||||||
* Luminance/grayscale texture compression.
|
* Luminance/grayscale texture compression.
|
||||||
* Called BC4 in DirectX10.
|
* Called BC4 in DirectX10.
|
||||||
*/
|
*/
|
||||||
LTC(4, false, true, false);
|
LTC(4, false, true, false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 24-bit depth with 8-bit stencil.
|
||||||
|
* Check the cap {@link Caps#PackedDepthStencilBuffer}.
|
||||||
|
*/
|
||||||
|
Depth24Stencil8(32, true, false, false);
|
||||||
|
|
||||||
private int bpp;
|
private int bpp;
|
||||||
private boolean isDepth;
|
private boolean isDepth;
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
|
|
||||||
package com.jme3.texture;
|
package com.jme3.texture;
|
||||||
|
|
||||||
import com.jme3.asset.Asset;
|
|
||||||
import com.jme3.asset.AssetKey;
|
import com.jme3.asset.AssetKey;
|
||||||
import com.jme3.asset.AssetNotFoundException;
|
import com.jme3.asset.AssetNotFoundException;
|
||||||
|
import com.jme3.asset.CloneableSmartAsset;
|
||||||
import com.jme3.asset.TextureKey;
|
import com.jme3.asset.TextureKey;
|
||||||
import com.jme3.export.*;
|
import com.jme3.export.*;
|
||||||
import com.jme3.util.PlaceholderAssets;
|
import com.jme3.util.PlaceholderAssets;
|
||||||
@ -57,7 +57,7 @@ import java.util.logging.Logger;
|
|||||||
* @author Joshua Slack
|
* @author Joshua Slack
|
||||||
* @version $Id: Texture.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
* @version $Id: Texture.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
||||||
*/
|
*/
|
||||||
public abstract class Texture implements Asset, Savable, Cloneable {
|
public abstract class Texture implements CloneableSmartAsset, Savable, Cloneable {
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
|
|
||||||
@ -502,7 +502,11 @@ public abstract class Texture implements Asset, Savable, Cloneable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Texture other = (Texture) obj;
|
final Texture other = (Texture) obj;
|
||||||
if (this.image != other.image && (this.image == null || !this.image.equals(other.image))) {
|
|
||||||
|
// NOTE: Since images are generally considered unique assets in jME3,
|
||||||
|
// using the image's equals() implementation is not neccessary here
|
||||||
|
// (would be too slow)
|
||||||
|
if (this.image != other.image) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.minificationFilter != other.minificationFilter) {
|
if (this.minificationFilter != other.minificationFilter) {
|
||||||
@ -523,7 +527,10 @@ public abstract class Texture implements Asset, Savable, Cloneable {
|
|||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 5;
|
int hash = 5;
|
||||||
hash = 67 * hash + (this.image != null ? this.image.hashCode() : 0);
|
// NOTE: Since images are generally considered unique assets in jME3,
|
||||||
|
// using the image's hashCode() implementation is not neccessary here
|
||||||
|
// (would be too slow)
|
||||||
|
hash = 67 * hash + (this.image != null ? System.identityHashCode(this.image) : 0);
|
||||||
hash = 67 * hash + (this.minificationFilter != null ? this.minificationFilter.hashCode() : 0);
|
hash = 67 * hash + (this.minificationFilter != null ? this.minificationFilter.hashCode() : 0);
|
||||||
hash = 67 * hash + (this.magnificationFilter != null ? this.magnificationFilter.hashCode() : 0);
|
hash = 67 * hash + (this.magnificationFilter != null ? this.magnificationFilter.hashCode() : 0);
|
||||||
hash = 67 * hash + (this.shadowCompareMode != null ? this.shadowCompareMode.hashCode() : 0);
|
hash = 67 * hash + (this.shadowCompareMode != null ? this.shadowCompareMode.hashCode() : 0);
|
||||||
@ -531,33 +538,29 @@ public abstract class Texture implements Asset, Savable, Cloneable {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// public abstract Texture createSimpleClone();
|
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve a basic clone of this Texture (ie, clone everything but the
|
/** Retrieve a basic clone of this Texture (ie, clone everything but the
|
||||||
* image data, which is shared)
|
* image data, which is shared)
|
||||||
*
|
*
|
||||||
* @return Texture
|
* @return Texture
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link Texture#clone()} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Texture createSimpleClone(Texture rVal) {
|
public Texture createSimpleClone(Texture rVal) {
|
||||||
rVal.setMinFilter(minificationFilter);
|
rVal.setMinFilter(minificationFilter);
|
||||||
rVal.setMagFilter(magnificationFilter);
|
rVal.setMagFilter(magnificationFilter);
|
||||||
rVal.setShadowCompareMode(shadowCompareMode);
|
rVal.setShadowCompareMode(shadowCompareMode);
|
||||||
// rVal.setHasBorder(hasBorder);
|
|
||||||
rVal.setAnisotropicFilter(anisotropicFilter);
|
rVal.setAnisotropicFilter(anisotropicFilter);
|
||||||
rVal.setImage(image); // NOT CLONED.
|
rVal.setImage(image); // NOT CLONED.
|
||||||
// rVal.memReq = memReq;
|
|
||||||
rVal.setKey(key);
|
rVal.setKey(key);
|
||||||
rVal.setName(name);
|
rVal.setName(name);
|
||||||
// rVal.setBlendColor(blendColor != null ? blendColor.clone() : null);
|
|
||||||
// if (getTextureKey() != null) {
|
|
||||||
// rVal.setTextureKey(getTextureKey());
|
|
||||||
// }
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link Texture#clone()} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract Texture createSimpleClone();
|
public abstract Texture createSimpleClone();
|
||||||
|
|
||||||
public void write(JmeExporter e) throws IOException {
|
public void write(JmeExporter e) throws IOException {
|
||||||
|
@ -33,11 +33,8 @@
|
|||||||
package com.jme3.util;
|
package com.jme3.util;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of a Map that favors iteration speed rather than
|
* Implementation of a Map that favors iteration speed rather than
|
||||||
@ -45,7 +42,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
public final class ListMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable {
|
||||||
|
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
Map<String, String> map = new ListMap<String, String>();
|
Map<String, String> map = new ListMap<String, String>();
|
||||||
@ -89,6 +86,29 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
return new ListMapEntry<K, V>(key, value);
|
return new ListMapEntry<K, V>(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ListMapEntry<K, V> other = (ListMapEntry<K, V>) obj;
|
||||||
|
if (this.key != other.key && (this.key == null || !this.key.equals(other.key))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.value != other.value && (this.value == null || !this.value.equals(other.value))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (this.key != null ? this.key.hashCode() : 0) ^
|
||||||
|
(this.value != null ? this.value.hashCode() : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final HashMap<K, V> backingMap;
|
private final HashMap<K, V> backingMap;
|
||||||
@ -115,6 +135,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
putAll(map);
|
putAll(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
// return entries.size();
|
// return entries.size();
|
||||||
return backingMap.size();
|
return backingMap.size();
|
||||||
@ -135,6 +156,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
return entries[index].key;
|
return entries[index].key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
@ -147,6 +169,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return a == null ? (b == null) : a.equals(b);
|
// return a == null ? (b == null) : a.equals(b);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean containsKey(Object key) {
|
public boolean containsKey(Object key) {
|
||||||
return backingMap.containsKey( (K) key);
|
return backingMap.containsKey( (K) key);
|
||||||
// if (key == null)
|
// if (key == null)
|
||||||
@ -160,6 +183,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean containsValue(Object value) {
|
public boolean containsValue(Object value) {
|
||||||
return backingMap.containsValue( (V) value);
|
return backingMap.containsValue( (V) value);
|
||||||
// for (int i = 0; i < entries.size(); i++){
|
// for (int i = 0; i < entries.size(); i++){
|
||||||
@ -169,6 +193,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public V get(Object key) {
|
public V get(Object key) {
|
||||||
return backingMap.get( (K) key);
|
return backingMap.get( (K) key);
|
||||||
// if (key == null)
|
// if (key == null)
|
||||||
@ -182,6 +207,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return null;
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public V put(K key, V value) {
|
public V put(K key, V value) {
|
||||||
if (backingMap.containsKey(key)){
|
if (backingMap.containsKey(key)){
|
||||||
// set the value on the entry
|
// set the value on the entry
|
||||||
@ -222,6 +248,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return null;
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public V remove(Object key) {
|
public V remove(Object key) {
|
||||||
V element = backingMap.remove( (K) key);
|
V element = backingMap.remove( (K) key);
|
||||||
if (element != null){
|
if (element != null){
|
||||||
@ -255,6 +282,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return null;
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void putAll(Map<? extends K, ? extends V> map) {
|
public void putAll(Map<? extends K, ? extends V> map) {
|
||||||
for (Entry<? extends K, ? extends V> entry : map.entrySet()){
|
for (Entry<? extends K, ? extends V> entry : map.entrySet()){
|
||||||
put(entry.getKey(), entry.getValue());
|
put(entry.getKey(), entry.getValue());
|
||||||
@ -275,6 +303,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
backingMap.clear();
|
backingMap.clear();
|
||||||
// entries.clear();
|
// entries.clear();
|
||||||
@ -287,6 +316,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<K> keySet() {
|
public Set<K> keySet() {
|
||||||
return backingMap.keySet();
|
return backingMap.keySet();
|
||||||
// HashSet<K> keys = new HashSet<K>();
|
// HashSet<K> keys = new HashSet<K>();
|
||||||
@ -297,6 +327,7 @@ public final class ListMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
|||||||
// return keys;
|
// return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Collection<V> values() {
|
public Collection<V> values() {
|
||||||
return backingMap.values();
|
return backingMap.values();
|
||||||
// ArrayList<V> values = new ArrayList<V>();
|
// ArrayList<V> values = new ArrayList<V>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user