aboutsummaryrefslogtreecommitdiff
path: root/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java')
-rw-r--r--engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java162
1 files changed, 162 insertions, 0 deletions
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
new file mode 100644
index 0000000..75fc0c5
--- /dev/null
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
@@ -0,0 +1,162 @@
+package com.jme3.scene.plugins.blender.textures.blending;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.texture.Image;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture2D;
+import com.jme3.texture.Texture3D;
+import com.jme3.texture.Image.Format;
+import com.jme3.util.BufferUtils;
+
+/**
+ * The class that is responsible for blending the following texture types:
+ * <li> RGBA8
+ * <li> ABGR8
+ * <li> BGR8
+ * <li> RGB8
+ * Not yet supported (but will be):
+ * <li> ARGB4444:
+ * <li> RGB10:
+ * <li> RGB111110F:
+ * <li> RGB16:
+ * <li> RGB16F:
+ * <li> RGB16F_to_RGB111110F:
+ * <li> RGB16F_to_RGB9E5:
+ * <li> RGB32F:
+ * <li> RGB565:
+ * <li> RGB5A1:
+ * <li> RGB9E5:
+ * <li> RGBA16:
+ * <li> RGBA16F
+ * @author Marcin Roguski (Kaelthas)
+ */
+public class TextureBlenderAWT extends AbstractTextureBlender {
+ private static final Logger LOGGER = Logger.getLogger(TextureBlenderAWT.class.getName());
+
+ @Override
+ public Texture blend(float[] materialColor, Texture texture, float[] color, float affectFactor, int blendType, boolean neg, BlenderContext blenderContext) {
+ float[] pixelColor = new float[] { color[0], color[1], color[2], 1.0f };
+ Format format = texture.getImage().getFormat();
+ ByteBuffer data = texture.getImage().getData(0);
+ data.rewind();
+
+ int width = texture.getImage().getWidth();
+ int height = texture.getImage().getHeight();
+ int depth = texture.getImage().getDepth();
+ if (depth == 0) {
+ depth = 1;
+ }
+ ByteBuffer newData = BufferUtils.createByteBuffer(width * height * depth * 4);
+
+ float[] resultPixel = new float[4];
+ int dataIndex = 0;
+ while (data.hasRemaining()) {
+ float tin = this.setupMaterialColor(data, format, neg, pixelColor);
+ this.blendPixel(resultPixel, materialColor, color, tin, blendType, blenderContext);
+ newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
+ newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
+ newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
+ newData.put(dataIndex++, (byte) (pixelColor[3] * 255.0f));
+ }
+ if (texture.getType() == Texture.Type.TwoDimensional) {
+ return new Texture2D(new Image(Format.RGBA8, width, height, newData));
+ } else {
+ ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+ dataArray.add(newData);
+ return new Texture3D(new Image(Format.RGBA8, width, height, depth, dataArray));
+ }
+ }
+
+ /**
+ * 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 replaced 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) {
+ float tin = 0.0f;
+ byte pixelValue = data.get();// at least one byte is always taken :)
+ float firstPixelValue = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ switch (imageFormat) {
+ case RGBA8:
+ materialColor[0] = firstPixelValue;
+ pixelValue = data.get();
+ materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ pixelValue = data.get();
+ materialColor[2] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ pixelValue = data.get();
+ materialColor[3] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ break;
+ case ABGR8:
+ materialColor[3] = firstPixelValue;
+ pixelValue = data.get();
+ materialColor[2] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ pixelValue = data.get();
+ materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ pixelValue = data.get();
+ materialColor[0] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ break;
+ case BGR8:
+ materialColor[2] = firstPixelValue;
+ pixelValue = data.get();
+ materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ pixelValue = data.get();
+ materialColor[0] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ materialColor[3] = 1.0f;
+ break;
+ case RGB8:
+ materialColor[0] = firstPixelValue;
+ pixelValue = data.get();
+ materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ pixelValue = data.get();
+ materialColor[2] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
+ materialColor[3] = 1.0f;
+ break;
+ case ARGB4444:
+ 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:// TODO: implement these textures
+ LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", imageFormat);
+ break;
+ default:
+ throw new IllegalStateException("Invalid image format type for AWT texture blender: " + imageFormat);
+ }
+ if (neg) {
+ materialColor[0] = 1.0f - materialColor[0];
+ materialColor[1] = 1.0f - materialColor[1];
+ materialColor[2] = 1.0f - materialColor[2];
+ }
+ // Blender formula for texture intensity calculation:
+ // 0.35*texres.tr+0.45*texres.tg+0.2*texres.tb
+ tin = 0.35f * materialColor[0] + 0.45f * materialColor[1] + 0.2f * materialColor[2];
+ return tin;
+ }
+}