|
|
@ -256,8 +256,7 @@ public class TextureHelper extends AbstractBlenderHelper { |
|
|
|
width <<= 1; |
|
|
|
width <<= 1; |
|
|
|
height <<= 1; |
|
|
|
height <<= 1; |
|
|
|
ColorBand colorBand = this.readColorband(tex, dataRepository); |
|
|
|
ColorBand colorBand = this.readColorband(tex, dataRepository); |
|
|
|
Format format = sType == com.jme3.scene.plugins.blender.helpers.v249.NoiseHelper.TEX_COLOR || colorBand != null ? Format.RGB8 |
|
|
|
Format format = sType == com.jme3.scene.plugins.blender.helpers.v249.NoiseHelper.TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8; |
|
|
|
: Format.Luminance8; |
|
|
|
|
|
|
|
int bytesPerPixel = sType == com.jme3.scene.plugins.blender.helpers.v249.NoiseHelper.TEX_COLOR || colorBand != null ? 3 : 1; |
|
|
|
int bytesPerPixel = sType == com.jme3.scene.plugins.blender.helpers.v249.NoiseHelper.TEX_COLOR || colorBand != null ? 3 : 1; |
|
|
|
|
|
|
|
|
|
|
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); |
|
|
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); |
|
|
@ -272,12 +271,9 @@ public class TextureHelper extends AbstractBlenderHelper { |
|
|
|
if (texres.nor != null) { |
|
|
|
if (texres.nor != null) { |
|
|
|
float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); |
|
|
|
float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); |
|
|
|
// calculate bumpnormal
|
|
|
|
// calculate bumpnormal
|
|
|
|
texres.nor[0] = noiseHelper.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, |
|
|
|
texres.nor[0] = noiseHelper.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis); |
|
|
|
noiseBasis); |
|
|
|
texres.nor[1] = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis); |
|
|
|
texres.nor[1] = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, |
|
|
|
texres.nor[2] = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis); |
|
|
|
noiseBasis); |
|
|
|
|
|
|
|
texres.nor[2] = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, |
|
|
|
|
|
|
|
noiseBasis); |
|
|
|
|
|
|
|
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository); |
|
|
|
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository); |
|
|
|
} |
|
|
|
} |
|
|
|
noiseHelper.brightnesAndContrastRGB(tex, texres); |
|
|
|
noiseHelper.brightnesAndContrastRGB(tex, texres); |
|
|
@ -1011,7 +1007,7 @@ public class TextureHelper extends AbstractBlenderHelper { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* This method blends the given texture with material color and the defined color in 'map to' panel. As a result of this method a new |
|
|
|
* This method blends the given texture with material color and the defined color in 'map to' panel. As a result of this method a new |
|
|
|
* texture is created. The input texture is NOT modified. |
|
|
|
* texture is created. The input texture is NOT. |
|
|
|
* |
|
|
|
* |
|
|
|
* @param materialColor |
|
|
|
* @param materialColor |
|
|
|
* the material diffuse color |
|
|
|
* the material diffuse color |
|
|
@ -1027,9 +1023,8 @@ public class TextureHelper extends AbstractBlenderHelper { |
|
|
|
* the data repository |
|
|
|
* the data repository |
|
|
|
* @return new texture that was created after the blending |
|
|
|
* @return new texture that was created after the blending |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Texture blendTexture(float[] materialColor, Texture texture, float[] color, float affectFactor, |
|
|
|
public Texture blendTexture(float[] materialColor, Texture texture, float[] color, float affectFactor, int blendType, boolean neg, DataRepository dataRepository) { |
|
|
|
int blendType, boolean neg, |
|
|
|
float[] materialColorClone = materialColor.clone();//this array may change, so we copy it
|
|
|
|
DataRepository dataRepository) { |
|
|
|
|
|
|
|
Format format = texture.getImage().getFormat(); |
|
|
|
Format format = texture.getImage().getFormat(); |
|
|
|
ByteBuffer data = texture.getImage().getData(0); |
|
|
|
ByteBuffer data = texture.getImage().getData(0); |
|
|
|
data.rewind(); |
|
|
|
data.rewind(); |
|
|
@ -1038,96 +1033,125 @@ public class TextureHelper extends AbstractBlenderHelper { |
|
|
|
ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 3); |
|
|
|
ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 3); |
|
|
|
|
|
|
|
|
|
|
|
float[] resultPixel = new float[3]; |
|
|
|
float[] resultPixel = new float[3]; |
|
|
|
float[] texPixel = new float[3]; |
|
|
|
|
|
|
|
int dataIndex = 0; |
|
|
|
int dataIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
while (data.hasRemaining()) { |
|
|
|
while (data.hasRemaining()) { |
|
|
|
byte pixelValue = data.get(); |
|
|
|
float tin = this.setupMaterialColor(data, format, neg, materialColorClone); |
|
|
|
texPixel[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
this.blendPixel(resultPixel, materialColorClone, color, tin, affectFactor, blendType, dataRepository); |
|
|
|
if(neg) { |
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f)); |
|
|
|
texPixel[0] = 1.0f - texPixel[0]; |
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f)); |
|
|
|
} |
|
|
|
} |
|
|
|
if (format == Format.ABGR8) { |
|
|
|
return new Texture2D(new Image(Format.RGB8, width, height, newData)); |
|
|
|
//intensity not used at the moment
|
|
|
|
|
|
|
|
pixelValue = data.get(); |
|
|
|
|
|
|
|
texPixel[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
|
|
|
|
if(neg) { |
|
|
|
|
|
|
|
texPixel[2] = 1.0f - texPixel[2]; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* This method alters the material color in a way dependent on the type of the image. |
|
|
|
|
|
|
|
* For example the color remains untouched if the texture is of Luminance type. |
|
|
|
|
|
|
|
* The luminance defines the interaction between the material color and color defined |
|
|
|
|
|
|
|
* for texture blending. |
|
|
|
|
|
|
|
* If the type has 3 or more color channels then the material color is replaces with the texture's |
|
|
|
|
|
|
|
* color and later blended with the defined blend color. |
|
|
|
|
|
|
|
* All alpha values (if present) are ignored and not used during blending. |
|
|
|
|
|
|
|
* @param data |
|
|
|
|
|
|
|
* the image data |
|
|
|
|
|
|
|
* @param imageFormat |
|
|
|
|
|
|
|
* the format of the image |
|
|
|
|
|
|
|
* @param neg |
|
|
|
|
|
|
|
* defines it the result color should be nagated |
|
|
|
|
|
|
|
* @param materialColor |
|
|
|
|
|
|
|
* the material's color (value may be changed) |
|
|
|
|
|
|
|
* @return texture intensity for the current pixel |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
protected float setupMaterialColor(ByteBuffer data, Format imageFormat, boolean neg, float[] materialColor) { |
|
|
|
|
|
|
|
// at least one byte is always taken :)
|
|
|
|
|
|
|
|
float tin = 0.0f; |
|
|
|
|
|
|
|
byte pixelValue = data.get(); |
|
|
|
|
|
|
|
float firstPixelValue = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
|
|
|
|
switch (imageFormat) { |
|
|
|
|
|
|
|
case ABGR8: |
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
|
|
|
|
texPixel[1] = 1.0f - texPixel[1]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
|
|
|
|
texPixel[0] = 1.0f - texPixel[0]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.blendPixel(resultPixel, materialColor, texPixel, 1.0f, affectFactor, blendType, dataRepository); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f)); |
|
|
|
|
|
|
|
} else if (format == Format.RGB8) { |
|
|
|
|
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
break; |
|
|
|
texPixel[1] = 1.0f - texPixel[1]; |
|
|
|
case BGR8: |
|
|
|
} |
|
|
|
materialColor[2] = firstPixelValue; |
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
|
|
|
|
texPixel[2] = 1.0f - texPixel[2]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
float tin = texPixel[0];//(texPixel[0] + texPixel[1] + texPixel[2]) / 3.0f;
|
|
|
|
|
|
|
|
this.blendPixel(resultPixel, texPixel, color, tin, affectFactor, blendType, dataRepository); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f)); |
|
|
|
|
|
|
|
} else if (format == Format.RGBA8) { |
|
|
|
|
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
break; |
|
|
|
texPixel[1] = 1.0f - texPixel[1]; |
|
|
|
case RGB8: |
|
|
|
} |
|
|
|
materialColor[0] = firstPixelValue; |
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
|
|
|
|
texPixel[2] = 1.0f - texPixel[2]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
data.get(); // ignore alpha
|
|
|
|
|
|
|
|
this.blendPixel(resultPixel, materialColor, texPixel, 1.0f, affectFactor, blendType, dataRepository); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f)); |
|
|
|
|
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f)); |
|
|
|
|
|
|
|
} else if (format == Format.BGR8) { |
|
|
|
|
|
|
|
texPixel[2] = texPixel[0]; |
|
|
|
|
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
break; |
|
|
|
texPixel[1] = 1.0f - texPixel[1]; |
|
|
|
case RGBA8: |
|
|
|
} |
|
|
|
materialColor[0] = firstPixelValue; |
|
|
|
pixelValue = data.get(); |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
if(neg) { |
|
|
|
pixelValue = data.get(); |
|
|
|
texPixel[0] = 1.0f - texPixel[0]; |
|
|
|
materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f; |
|
|
|
} |
|
|
|
data.get(); // ignore alpha
|
|
|
|
this.blendPixel(resultPixel, materialColor, texPixel, 1.0f, affectFactor, blendType, dataRepository); |
|
|
|
break; |
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f)); |
|
|
|
case Luminance8: |
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f)); |
|
|
|
tin = neg ? 1.0f - firstPixelValue : firstPixelValue; |
|
|
|
newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f)); |
|
|
|
neg = false;//do not negate the materialColor, it must be unchanged
|
|
|
|
} else if (format == Format.Luminance8) { |
|
|
|
break; |
|
|
|
this.blendPixel(resultPixel, materialColor, color, texPixel[0], affectFactor, blendType, dataRepository); |
|
|
|
case Luminance8Alpha8: |
|
|
|
newData.put((byte) (resultPixel[0] * 255.0f)); |
|
|
|
tin = neg ? 1.0f - firstPixelValue : firstPixelValue; |
|
|
|
newData.put((byte) (resultPixel[1] * 255.0f)); |
|
|
|
neg = false;//do not negate the materialColor, it must be unchanged
|
|
|
|
newData.put((byte) (resultPixel[2] * 255.0f)); |
|
|
|
data.get(); // ignore alpha
|
|
|
|
} else { |
|
|
|
break; |
|
|
|
throw new IllegalStateException("Invalid texture format for blending operation: " + format); |
|
|
|
case Luminance16: |
|
|
|
|
|
|
|
case Luminance16Alpha16: |
|
|
|
|
|
|
|
case Alpha16: |
|
|
|
|
|
|
|
case Alpha8: |
|
|
|
|
|
|
|
case ARGB4444: |
|
|
|
|
|
|
|
case Depth: |
|
|
|
|
|
|
|
case Depth16: |
|
|
|
|
|
|
|
case Depth24: |
|
|
|
|
|
|
|
case Depth32: |
|
|
|
|
|
|
|
case Depth32F: |
|
|
|
|
|
|
|
case DXT1: |
|
|
|
|
|
|
|
case DXT1A: |
|
|
|
|
|
|
|
case DXT3: |
|
|
|
|
|
|
|
case DXT5: |
|
|
|
|
|
|
|
case Intensity16: |
|
|
|
|
|
|
|
case Intensity8: |
|
|
|
|
|
|
|
case LATC: |
|
|
|
|
|
|
|
case LTC: |
|
|
|
|
|
|
|
case Luminance16F: |
|
|
|
|
|
|
|
case Luminance16FAlpha16F: |
|
|
|
|
|
|
|
case Luminance32F: |
|
|
|
|
|
|
|
case RGB10: |
|
|
|
|
|
|
|
case RGB111110F: |
|
|
|
|
|
|
|
case RGB16: |
|
|
|
|
|
|
|
case RGB16F: |
|
|
|
|
|
|
|
case RGB16F_to_RGB111110F: |
|
|
|
|
|
|
|
case RGB16F_to_RGB9E5: |
|
|
|
|
|
|
|
case RGB32F: |
|
|
|
|
|
|
|
case RGB565: |
|
|
|
|
|
|
|
case RGB5A1: |
|
|
|
|
|
|
|
case RGB9E5: |
|
|
|
|
|
|
|
case RGBA16: |
|
|
|
|
|
|
|
case RGBA16F: |
|
|
|
|
|
|
|
case RGBA32F: |
|
|
|
|
|
|
|
LOGGER.warning("Image type not yet supported for blending: " + imageFormat); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw new IllegalStateException("Unknown image format type: " + imageFormat); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (neg) { |
|
|
|
|
|
|
|
materialColor[0] = 1.0f - materialColor[0]; |
|
|
|
|
|
|
|
materialColor[1] = 1.0f - materialColor[1]; |
|
|
|
|
|
|
|
materialColor[2] = 1.0f - materialColor[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
return new Texture2D(new Image(Format.RGB8, width, height, newData)); |
|
|
|
return tin; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -1148,8 +1172,7 @@ public class TextureHelper extends AbstractBlenderHelper { |
|
|
|
* @param dataRepository |
|
|
|
* @param dataRepository |
|
|
|
* the data repository |
|
|
|
* the data repository |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void blendPixel(float[] result, float[] materialColor, float[] color, float textureIntensity, float textureFactor, |
|
|
|
public void blendPixel(float[] result, float[] materialColor, float[] color, float textureIntensity, float textureFactor, int blendtype, DataRepository dataRepository) { |
|
|
|
int blendtype, DataRepository dataRepository) { |
|
|
|
|
|
|
|
float facm, col; |
|
|
|
float facm, col; |
|
|
|
|
|
|
|
|
|
|
|
switch (blendtype) { |
|
|
|
switch (blendtype) { |
|
|
|