Java Code Examples for com.jme3.texture.Image#getHeight()

The following examples show how to use com.jme3.texture.Image#getHeight() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CombinedTexture.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * This method merges two given textures. The result is stored in the
 * 'target' texture.
 * 
 * @param target
 *            the target texture
 * @param source
 *            the source texture
 */
private void merge(Texture2D target, Texture2D source) {
    if (target.getImage().getDepth() != source.getImage().getDepth()) {
        throw new IllegalArgumentException("Cannot merge images with different depths!");
    }
    Image sourceImage = source.getImage();
    Image targetImage = target.getImage();
    PixelInputOutput sourceIO = PixelIOFactory.getPixelIO(sourceImage.getFormat());
    PixelInputOutput targetIO = PixelIOFactory.getPixelIO(targetImage.getFormat());
    TexturePixel sourcePixel = new TexturePixel();
    TexturePixel targetPixel = new TexturePixel();
    int depth = target.getImage().getDepth() == 0 ? 1 : target.getImage().getDepth();

    for (int layerIndex = 0; layerIndex < depth; ++layerIndex) {
        for (int x = 0; x < sourceImage.getWidth(); ++x) {
            for (int y = 0; y < sourceImage.getHeight(); ++y) {
                sourceIO.read(sourceImage, layerIndex, sourcePixel, x, y);
                targetIO.read(targetImage, layerIndex, targetPixel, x, y);
                targetPixel.merge(sourcePixel);
                targetIO.write(targetImage, layerIndex, targetPixel, x, y);
            }
        }
    }
}
 
Example 2
Source File: ImageToAwt.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public static void createData(Image image, boolean mipmaps){
    int bpp = image.getFormat().getBitsPerPixel();
    int w = image.getWidth();
    int h = image.getHeight();
    if (!mipmaps){
        image.setData(BufferUtils.createByteBuffer(w*h*bpp/8));
        return;
    }
    int expectedMipmaps = 1 + (int) Math.ceil(Math.log(Math.max(h, w)) / LOG2);
    int[] mipMapSizes = new int[expectedMipmaps];
    int total = 0;
    for (int i = 0; i < mipMapSizes.length; i++){
        int size = (w * h * bpp) / 8;
        total += size;
        mipMapSizes[i] = size;
        w /= 2;
        h /= 2;
    }
    image.setMipMapSizes(mipMapSizes);
    image.setData(BufferUtils.createByteBuffer(total));
}
 
Example 3
Source File: SkyFactory.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Create a cube-mapped sky using six textures.
 *
 * @param assetManager from which to load materials
 * @param west texture for the western face of the cube
 * @param east texture for the eastern face of the cube
 * @param north texture for the northern face of the cube
 * @param south texture for the southern face of the cube
 * @param up texture for the top face of the cube
 * @param down texture for the bottom face of the cube
 * @param normalScale The normal scale is multiplied by the 3D normal to get
 * a texture coordinate. Use Vector3f.UNIT_XYZ to not apply and
 * transformation to the normal.
 * @param sphereRadius the sky sphere's radius: for the sky to be visible,
 * its radius must fall between the near and far planes of the camera's
 * frustum
 * @return a new spatial representing the sky, ready to be attached to the
 * scene graph
 */
public static Spatial createSky(AssetManager assetManager, Texture west,
        Texture east, Texture north, Texture south, Texture up,
        Texture down, Vector3f normalScale, float sphereRadius) {

    Image westImg = west.getImage();
    Image eastImg = east.getImage();
    Image northImg = north.getImage();
    Image southImg = south.getImage();
    Image upImg = up.getImage();
    Image downImg = down.getImage();

    checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);

    Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null, westImg.getColorSpace());

    cubeImage.addData(westImg.getData(0));
    cubeImage.addData(eastImg.getData(0));
    cubeImage.addData(downImg.getData(0));
    cubeImage.addData(upImg.getData(0));
    cubeImage.addData(southImg.getData(0));
    cubeImage.addData(northImg.getData(0));
    
    TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
    return createSky(assetManager, cubeMap, normalScale, EnvMapType.CubeMap, sphereRadius);
}
 
Example 4
Source File: TbtQuadBackgroundComponent.java    From Lemur with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public static TbtQuadBackgroundComponent create( Texture t,
                                                 float imageScale,
                                                 int x1, int y1, int x2, int y2,
                                                 float zOffset, boolean lit ) {
    Image img = t.getImage();

    // we use the image size for the quad just to make sure
    // it is always big enough for whatever insets are thrown at it
    TbtQuad q = new TbtQuad(img.getWidth(), img.getHeight(),
                            x1, y1, x2, y2, img.getWidth(), img.getHeight(),
                            imageScale);
    TbtQuadBackgroundComponent c = new TbtQuadBackgroundComponent(q, t, x1, y1, zOffset, lit);
    return c;
}
 
Example 5
Source File: ImageFlipper.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public static void flipImage(Image img, int index){
    if (img.getFormat().isCompressed())
        throw new UnsupportedOperationException("Flipping compressed " +
                                                "images is unsupported.");

    int w = img.getWidth();
    int h = img.getHeight();
    int halfH = h / 2;

    // bytes per pixel
    int bpp = img.getFormat().getBitsPerPixel() / 8;
    int scanline = w * bpp;

    ByteBuffer data = img.getData(index);
    ByteBuffer temp = BufferUtils.createByteBuffer(scanline);
    
    data.rewind();
    for (int y = 0; y < halfH; y++){
        int oppY = h - y - 1;
        // read in scanline
        data.position(y * scanline);
        data.limit(data.position() + scanline);

        temp.rewind();
        temp.put(data);

    }
}
 
Example 6
Source File: TextureAtlas.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public Node insert(Image image) {
    if (!isLeaf()) {
        Node newNode = child[0].insert(image);

        if (newNode != null) {
            return newNode;
        }

        return child[1].insert(image);
    } else {
        if (occupied) {
            return null; // occupied
        }

        if (image.getWidth() > location.getWidth() || image.getHeight() > location.getHeight()) {
            return null; // does not fit
        }

        if (image.getWidth() == location.getWidth() && image.getHeight() == location.getHeight()) {
            occupied = true; // perfect fit
            return this;
        }

        int dw = location.getWidth() - image.getWidth();
        int dh = location.getHeight() - image.getHeight();

        if (dw > dh) {
            child[0] = new Node(location.getX(), location.getY(), image.getWidth(), location.getHeight());
            child[1] = new Node(location.getX() + image.getWidth(), location.getY(), location.getWidth() - image.getWidth(), location.getHeight());
        } else {
            child[0] = new Node(location.getX(), location.getY(), location.getWidth(), image.getHeight());
            child[1] = new Node(location.getX(), location.getY() + image.getHeight(), location.getWidth(), location.getHeight() - image.getHeight());
        }

        return child[0].insert(image);
    }
}
 
Example 7
Source File: TextureAtlas.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private boolean addImage(Image image, String name, String mapName, String sourceTextureName) {
    if (rootMapName == null) {
        rootMapName = mapName;
    }
    if (sourceTextureName == null && !rootMapName.equals(mapName)) {
        throw new IllegalStateException("Atlas already has a master map called " + rootMapName + "."
                + " Textures for new maps have to use a texture from the master map for their location.");
    }
    TextureAtlasTile location = locationMap.get(name);
    if (location != null) {
        //have location for texture
        if (!mapName.equals(mapNameMap.get(name))) {
            logger.log(Level.WARNING, "Same texture " + name + " is used in different maps! (" + mapName + " and " + mapNameMap.get(name) + "). Location will be based on location in " + mapNameMap.get(name) + "!");
            drawImage(image, location.getX(), location.getY(), mapName);
            return true;
        } else {
            return true;
        }
    } else if (sourceTextureName == null) {
        //need to make new tile
        Node node = root.insert(image);
        if (node == null) {
            return false;
        }
        location = node.location;
    } else {
        //got old tile to align to
        location = locationMap.get(sourceTextureName);
        if (location == null) {
            throw new IllegalStateException("Cannot find master map texture for " + name + ".");
        } else if (location.width != image.getWidth() || location.height != image.getHeight()) {
            throw new IllegalStateException(mapName + " " + name + " does not fit " + rootMapName + " tile size. Make sure all textures (diffuse, normal, specular) for one model are the same size.");
        }
    }
    mapNameMap.put(name, mapName);
    locationMap.put(name, location);
    drawImage(image, location.getX(), location.getY(), mapName);
    return true;
}
 
Example 8
Source File: SkyFactory.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private static void checkImage(Image image) {
//        if (image.getDepth() != 1)
//            throw new IllegalArgumentException("3D/Array images not allowed");

        if (image.getWidth() != image.getHeight()) {
            throw new IllegalArgumentException("Image width and height must be the same");
        }

        if (image.getMultiSamples() != 1) {
            throw new IllegalArgumentException("Multisample textures not allowed");
        }
    }
 
Example 9
Source File: DefaultImageRaster.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public DefaultImageRaster(Image image, int slice) {
    this.image = image;
    this.slice = slice;
    this.buffer = image.getData(slice);
    this.codec = ImageCodec.lookup(image.getFormat());
    this.width = image.getWidth();
    this.height = image.getHeight();
    if (codec instanceof ByteAlignedImageCodec || codec instanceof ByteOffsetImageCodec) {
        this.temp = new byte[codec.bpp];
    } else {
        this.temp = null;
    }
}
 
Example 10
Source File: SkyFactory.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private static void checkImagesForCubeMap(Image... images) {
    if (images.length == 1) {
        return;
    }

    Format fmt = images[0].getFormat();
    int width = images[0].getWidth();
    int height = images[0].getHeight();
    
    ByteBuffer data = images[0].getData(0);
    int size = data != null ? data.capacity() : 0;

    checkImage(images[0]);

    for (int i = 1; i < images.length; i++) {
        Image image = images[i];
        checkImage(images[i]);
        if (image.getFormat() != fmt) {
            throw new IllegalArgumentException("Images must have same format");
        }
        if (image.getWidth() != width || image.getHeight() != height)  {
            throw new IllegalArgumentException("Images must have same resolution");
        }
        ByteBuffer data2 = image.getData(0);
        if (data2 != null){
            if (data2.capacity() != size) {
                throw new IllegalArgumentException("Images must have same size");
            }
        }
    }
}
 
Example 11
Source File: SkyFactory.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private static void checkImage(Image image) {
//        if (image.getDepth() != 1)
//            throw new IllegalArgumentException("3D/Array images not allowed");

        if (image.getWidth() != image.getHeight()) {
            throw new IllegalArgumentException("Image width and height must be the same");
        }

        if (image.getMultiSamples() != 1) {
            throw new IllegalArgumentException("Multisample textures not allowed");
        }
    }
 
Example 12
Source File: TextureHelper.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * This method converts the given texture into normal-map texture.
 * 
 * @param source
 *            the source texture
 * @param strengthFactor
 *            the normal strength factor
 * @return normal-map texture
 */
public Image convertToNormalMapTexture(Image source, float strengthFactor) {
    BufferedImage sourceImage = ImageToAwt.convert(source, false, false, 0);

    BufferedImage heightMap = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
    BufferedImage bumpMap = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
    ColorConvertOp gscale = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
    gscale.filter(sourceImage, heightMap);

    Vector3f S = new Vector3f();
    Vector3f T = new Vector3f();
    Vector3f N = new Vector3f();

    for (int x = 0; x < bumpMap.getWidth(); ++x) {
        for (int y = 0; y < bumpMap.getHeight(); ++y) {
            // generating bump pixel
            S.x = 1;
            S.y = 0;
            S.z = strengthFactor * this.getHeight(heightMap, x + 1, y) - strengthFactor * this.getHeight(heightMap, x - 1, y);
            T.x = 0;
            T.y = 1;
            T.z = strengthFactor * this.getHeight(heightMap, x, y + 1) - strengthFactor * this.getHeight(heightMap, x, y - 1);

            float den = (float) Math.sqrt(S.z * S.z + T.z * T.z + 1);
            N.x = -S.z;
            N.y = -T.z;
            N.z = 1;
            N.divideLocal(den);

            // setting thge pixel in the result image
            bumpMap.setRGB(x, y, this.vectorToColor(N.x, N.y, N.z));
        }
    }
    ByteBuffer byteBuffer = BufferUtils.createByteBuffer(source.getWidth() * source.getHeight() * 3);
    ImageToAwt.convert(bumpMap, Format.RGB8, byteBuffer);
    return new Image(Format.RGB8, source.getWidth(), source.getHeight(), byteBuffer);
}
 
Example 13
Source File: TextureUtil.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
public void uploadTexture(Image image,
                          int target,
                          int index,
                          boolean linearizeSrgb) {

    boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
    Image.Format jmeFormat = image.getFormat();
    GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);

    ByteBuffer data = null;
    int sliceCount = 1;
    
    if (index >= 0) {
        data = image.getData(index);
    }
    
    if (image.getData() != null && image.getData().size() > 0) {
        sliceCount = image.getData().size();
    }

    int width = image.getWidth();
    int height = image.getHeight();
    int depth = image.getDepth();
    
    int[] mipSizes = image.getMipMapSizes();
    int pos = 0;
    // TODO: Remove unnecessary allocation
    if (mipSizes == null) {
        if (data != null) {
            mipSizes = new int[]{data.capacity()};
        } else {
            mipSizes = new int[]{width * height * jmeFormat.getBitsPerPixel() / 8};
        }
    }

    int samples = image.getMultiSamples();
    
    // For OGL3 core: setup texture swizzle.
    if (oglFormat.swizzleRequired) {
        setupTextureSwizzle(target, jmeFormat);
    }

    for (int i = 0; i < mipSizes.length; i++) {
        int mipWidth = Math.max(1, width >> i);
        int mipHeight = Math.max(1, height >> i);
        int mipDepth = Math.max(1, depth >> i);

        if (data != null) {
            data.position(pos);
            data.limit(pos + mipSizes[i]);
        }

        uploadTextureLevel(oglFormat, target, i, index, sliceCount, mipWidth, mipHeight, mipDepth, samples, data);

        pos += mipSizes[i];
    }
}
 
Example 14
Source File: SkyFactory.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale, int sphereRadius) {
    final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
    Geometry sky = new Geometry("Sky", sphereMesh);
    sky.setQueueBucket(Bucket.Sky);
    sky.setCullHint(Spatial.CullHint.Never);
    sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));

    Image westImg = west.getImage();
    Image eastImg = east.getImage();
    Image northImg = north.getImage();
    Image southImg = south.getImage();
    Image upImg = up.getImage();
    Image downImg = down.getImage();

    checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);

    Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);

    cubeImage.addData(westImg.getData(0));
    cubeImage.addData(eastImg.getData(0));

    cubeImage.addData(downImg.getData(0));
    cubeImage.addData(upImg.getData(0));

    cubeImage.addData(southImg.getData(0));
    cubeImage.addData(northImg.getData(0));
    
    if (westImg.getEfficentData() != null){
        // also consilidate efficient data
        ArrayList<Object> efficientData = new ArrayList<Object>(6);
        efficientData.add(westImg.getEfficentData());
        efficientData.add(eastImg.getEfficentData());
        efficientData.add(downImg.getEfficentData());
        efficientData.add(upImg.getEfficentData());
        efficientData.add(southImg.getEfficentData());
        efficientData.add(northImg.getEfficentData());
        cubeImage.setEfficentData(efficientData);
    }

    TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
    cubeMap.setAnisotropicFilter(0);
    cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
    cubeMap.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
    cubeMap.setWrap(Texture.WrapMode.EdgeClamp);

    Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
    skyMat.setTexture("Texture", cubeMap);
    skyMat.setVector3("NormalScale", normalScale);
    sky.setMaterial(skyMat);

    return sky;
}
 
Example 15
Source File: PaintTerrainToolAction.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * Goes through each pixel in the image. At each pixel it looks to see if the UV mouse coordinate is within the
 * of the brush. If it is in the brush radius, it gets the existing color from that pixel so it can add/subtract to/from it.
 * Essentially it does a radius check and adds in a fade value. It does this to the color value returned by the
 * first pixel color query.
 * Next it sets the color of that pixel. If it was within the radius, the color will change. If it was outside
 * the radius, then nothing will change, the color will be the same; but it will set it nonetheless. Not efficient.
 *
 * If the mouse is being dragged with the button down, then the dragged value should be set to true. This will reduce
 * the intensity of the brush to 10% of what it should be per spray. Otherwise it goes to 100% opacity within a few pixels.
 * This makes it work a little more realistically.
 *
 * @param image to manipulate
 * @param uv the world x,z coordinate
 * @param dragged true if the mouse button is down and it is being dragged, use to reduce brush intensity
 * @param radius in percentage so it can be translated to the image dimensions
 * @param erase true if the tool should remove the paint instead of add it
 * @param fadeFalloff the percentage of the radius when the paint begins to start fading
 */
protected void doPaintAction(int texIndex, Image image, Vector2f uv, boolean dragged, float radius, boolean erase, float fadeFalloff){
    Vector2f texuv = new Vector2f();
    ColorRGBA color = ColorRGBA.Black;
    
    float width = image.getWidth();
    float height = image.getHeight();

    int minx = (int) Math.max(0, (uv.x*width - radius*width)); // convert percents to pixels to limit how much we iterate
    int maxx = (int) Math.min(width,(uv.x*width + radius*width));
    int miny = (int) Math.max(0,(uv.y*height - radius*height));
    int maxy = (int) Math.min(height,(uv.y*height + radius*height));

    float radiusSquared = radius*radius;
    float radiusFalloff = radius*fadeFalloff;
    // go through each pixel, in the radius of the tool, in the image
    for (int y = miny; y < maxy; y++){
        for (int x = minx; x < maxx; x++){
            
            texuv.set((float)x / width, (float)y / height);// gets the position in percentage so it can compare with the mouse UV coordinate

            float dist = texuv.distanceSquared(uv);
            if (dist < radiusSquared ) { // if the pixel is within the distance of the radius, set a color (distance times intensity)
                manipulatePixel(image, x, y, color, false); // gets the color at that location (false means don't write to the buffer)

                // calculate the fade falloff intensity
                float intensity = 0.1f;
                if (dist > radiusFalloff) {
                    float dr = radius - radiusFalloff; // falloff to radius length
                    float d2 = dist - radiusFalloff; // dist minus falloff
                    d2 = d2/dr; // dist percentage of falloff length
                    intensity = 1-d2; // fade out more the farther away it is
                }

                //if (dragged)
                //	intensity = intensity*0.1f; // magical divide it by 10 to reduce its intensity when mouse is dragged

                if (erase) {
                    switch (texIndex) {
                        case 0:
                            color.r -= intensity; break;
                        case 1:
                            color.g -= intensity; break;
                        case 2:
                            color.b -= intensity; break;
                        case 3:
                            color.a -= intensity; break;
                    }
                } else {
                    switch (texIndex) {
                        case 0:
                            color.r += intensity; break;
                        case 1:
                            color.g += intensity; break;
                        case 2:
                            color.b += intensity; break;
                        case 3:
                            color.a += intensity; break;
                    }
                }
                color.clamp();

                manipulatePixel(image, x, y, color, true); // set the new color
            }

        }
    }

    image.getData(0).rewind();
}
 
Example 16
Source File: ImageToAwt.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
     * Convert the image from the given format to the output format.
     * It is assumed that both images have buffers with the appropriate
     * number of elements and that both have the same dimensions.
     *
     * @param input
     * @param output
     */
    public static void convert(Image input, Image output){
        DecodeParams inParams  = params.get(input.getFormat());
        DecodeParams outParams = params.get(output.getFormat());

        if (inParams == null || outParams == null)
            throw new UnsupportedOperationException();

        int width  = input.getWidth();
        int height = input.getHeight();

        if (width != output.getWidth() || height != output.getHeight())
            throw new IllegalArgumentException();

        ByteBuffer inData = input.getData(0);

        boolean inAlpha = false;
        boolean inLum = false;
        boolean inRGB = false;
        if (inParams.am != 0) {
            inAlpha = true;
        }

        if (inParams.rm != 0 && inParams.gm == 0 && inParams.bm == 0) {
            inLum = true;
        } else if (inParams.rm != 0 && inParams.gm != 0 && inParams.bm != 0) {
            inRGB = true;
        }

        int expansionA = 8 - Integer.bitCount(inParams.am);
        int expansionR = 8 - Integer.bitCount(inParams.rm);
        int expansionG = 8 - Integer.bitCount(inParams.gm);
        int expansionB = 8 - Integer.bitCount(inParams.bm);

        int inputPixel;
        for (int y = 0; y < height; y++){
            for (int x = 0; x < width; x++){
                int i = Ix(x, y, width) * inParams.bpp;
                inputPixel = (readPixel(inData, i, inParams.bpp) & inParams.im) >> inParams.is;
                
                int a = (inputPixel & inParams.am) >> inParams.as;
                int r = (inputPixel & inParams.rm) >> inParams.rs;
                int g = (inputPixel & inParams.gm) >> inParams.gs;
                int b = (inputPixel & inParams.bm) >> inParams.bs;

                r = r & 0xff;
                g = g & 0xff;
                b = b & 0xff;
                a = a & 0xff;

                a = a << expansionA;
                r = r << expansionR;
                g = g << expansionG;
                b = b << expansionB;

                if (inLum)
                    b = g = r;

                if (!inAlpha)
                    a = 0xff;

//                int argb = (a << 24) | (r << 16) | (g << 8) | b;
//                out.setRGB(x, y, argb);
            }
        }
    }
 
Example 17
Source File: TextureBlenderAWT.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
    this.prepareImagesForBlending(image, baseImage);

    float[] pixelColor = new float[] { color[0], color[1], color[2], 1.0f };
    Format format = image.getFormat();

    PixelInputOutput basePixelIO = null, pixelReader = PixelIOFactory.getPixelIO(format);
    TexturePixel basePixel = null, pixel = new TexturePixel();
    float[] materialColor = this.materialColor;
    if (baseImage != null) {
        basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
        materialColor = new float[this.materialColor.length];
        basePixel = new TexturePixel();
    }

    int width = image.getWidth();
    int height = image.getHeight();
    int depth = image.getDepth();
    if (depth == 0) {
        depth = 1;
    }
    ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);

    float[] resultPixel = new float[4];
    for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
        ByteBuffer data = image.getData(dataLayerIndex);
        data.rewind();
        ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 4);

        int dataIndex = 0, x = 0, y = 0, index = 0;
        while (index < data.limit()) {
            // getting the proper material color if the base texture is applied
            if (basePixelIO != null) {
                basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
                basePixel.toRGBA(materialColor);
            }

            // reading the current texture's pixel
            pixelReader.read(image, dataLayerIndex, pixel, index);
            index += image.getFormat().getBitsPerPixel() >> 3;
            pixel.toRGBA(pixelColor);
            if (negateTexture) {
                pixel.negate();
            }

            this.blendPixel(resultPixel, materialColor, pixelColor, 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));

            ++x;
            if (x >= width) {
                x = 0;
                ++y;
            }
        }
        dataArray.add(newData);
    }

    Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
    if (image.getMipMapSizes() != null) {
        result.setMipMapSizes(image.getMipMapSizes().clone());
    }
    return result;
}
 
Example 18
Source File: TriangulatedTexture.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * Constructor that creates the image element from the given texture and
 * UV coordinates (it cuts out the smallest rectasngle possible from the
 * given image that will hold the triangle defined by the given UV
 * coordinates). After the image is cut out the UV coordinates are
 * recalculated to be fit for the new image.
 * 
 * @param faceIndex
 *            the index of mesh's face this image refers to
 * @param sourceImage
 *            the source image
 * @param uvCoordinates
 *            the UV coordinates that define the image
 */
public TriangleTextureElement(int faceIndex, Image sourceImage, List<Vector2f> uvCoordinates, boolean wholeUVList, BlenderContext blenderContext) {
    TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
    this.faceIndex = faceIndex;

    uv = wholeUVList ? new Vector2f[] { uvCoordinates.get(faceIndex * 3).clone(), uvCoordinates.get(faceIndex * 3 + 1).clone(), uvCoordinates.get(faceIndex * 3 + 2).clone() } : new Vector2f[] { uvCoordinates.get(0).clone(), uvCoordinates.get(1).clone(), uvCoordinates.get(2).clone() };

    // be careful here, floating point operations might cause the
    // texture positions to be inapropriate
    int[][] texturePosition = new int[3][2];
    for (int i = 0; i < texturePosition.length; ++i) {
        texturePosition[i][0] = textureHelper.getPixelPosition(uv[i].x, sourceImage.getWidth());
        texturePosition[i][1] = textureHelper.getPixelPosition(uv[i].y, sourceImage.getHeight());
    }

    // calculating the extent of the texture
    int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE;
    int maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
    float minUVX = Float.MAX_VALUE, minUVY = Float.MAX_VALUE;
    float maxUVX = Float.MIN_VALUE, maxUVY = Float.MIN_VALUE;

    for (int i = 0; i < texturePosition.length; ++i) {
        minX = Math.min(texturePosition[i][0], minX);
        minY = Math.min(texturePosition[i][1], minY);

        maxX = Math.max(texturePosition[i][0], maxX);
        maxY = Math.max(texturePosition[i][1], maxY);

        minUVX = Math.min(uv[i].x, minUVX);
        minUVY = Math.min(uv[i].y, minUVY);
        maxUVX = Math.max(uv[i].x, maxUVX);
        maxUVY = Math.max(uv[i].y, maxUVY);
    }
    int width = maxX - minX;
    int height = maxY - minY;

    if (width == 0) {
        width = 1;
    }
    if (height == 0) {
        height = 1;
    }

    // copy the pixel from the texture to the result image
    PixelInputOutput pixelReader = PixelIOFactory.getPixelIO(sourceImage.getFormat());
    TexturePixel pixel = new TexturePixel();
    ByteBuffer data = BufferUtils.createByteBuffer(width * height * 4);
    for (int y = minY; y < maxY; ++y) {
        for (int x = minX; x < maxX; ++x) {
            int xPos = x >= sourceImage.getWidth() ? x - sourceImage.getWidth() : x;
            int yPos = y >= sourceImage.getHeight() ? y - sourceImage.getHeight() : y;
            pixelReader.read(sourceImage, 0, pixel, xPos, yPos);
            data.put(pixel.getR8());
            data.put(pixel.getG8());
            data.put(pixel.getB8());
            data.put(pixel.getA8());
        }
    }
    image = new Image(Format.RGBA8, width, height, data);

    // modify the UV values so that they fit the new image
    float heightUV = maxUVY - minUVY;
    float widthUV = maxUVX - minUVX;
    for (int i = 0; i < uv.length; ++i) {
        // first translate it to the image borders
        uv[i].x -= minUVX;
        uv[i].y -= minUVY;
        // then scale so that it fills the whole area
        uv[i].x /= widthUV;
        uv[i].y /= heightUV;
    }
}
 
Example 19
Source File: CombinedTexture.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * This method determines if the given texture has no alpha channel.
 * 
 * @param texture
 *            the texture to check for alpha channel
 * @return <b>true</b> if the texture has no alpha channel and <b>false</b>
 *         otherwise
 */
private boolean isWithoutAlpha(TextureData textureData, BlenderContext blenderContext) {
    ColorBand colorBand = new ColorBand(textureData.textureStructure, blenderContext);
    if (!colorBand.hasTransparencies()) {
        int type = ((Number) textureData.textureStructure.getFieldValue("type")).intValue();
        if (type == TextureHelper.TEX_MAGIC) {
            return true;
        }
        if (type == TextureHelper.TEX_VORONOI) {
            int voronoiColorType = ((Number) textureData.textureStructure.getFieldValue("vn_coltype")).intValue();
            return voronoiColorType != 0;// voronoiColorType == 0:
                                         // intensity, voronoiColorType
                                         // != 0: col1, col2 or col3
        }
        if (type == TextureHelper.TEX_CLOUDS) {
            int sType = ((Number) textureData.textureStructure.getFieldValue("stype")).intValue();
            return sType == 1;// sType==0: without colors, sType==1: with
                              // colors
        }

        // checking the flat textures for alpha values presence
        if (type == TextureHelper.TEX_IMAGE) {
            Image image = textureData.texture.getImage();
            switch (image.getFormat()) {
                case BGR8:
                case DXT1:
                case Luminance16:
                case Luminance16F:
                case Luminance32F:
                case Luminance8:
                case RGB10:
                case RGB111110F:
                case RGB16:
                case RGB16F:
                case RGB32F:
                case RGB565:
                case RGB8:
                    return true;// these types have no alpha by definition
                case ABGR8:
                case DXT3:
                case DXT5:
                case Luminance16Alpha16:
                case Luminance16FAlpha16F:
                case Luminance8Alpha8:
                case RGBA16:
                case RGBA16F:
                case RGBA32F:
                case RGBA8:// with these types it is better to make sure if the texture is or is not transparent
                    PixelInputOutput pixelInputOutput = PixelIOFactory.getPixelIO(image.getFormat());
                    TexturePixel pixel = new TexturePixel();
                    int depth = image.getDepth() == 0 ? 1 : image.getDepth();
                    for (int layerIndex = 0; layerIndex < depth; ++layerIndex) {
                        for (int x = 0; x < image.getWidth(); ++x) {
                            for (int y = 0; y < image.getHeight(); ++y) {
                                pixelInputOutput.read(image, layerIndex, pixel, x, y);
                                if (pixel.alpha < 1.0f) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
            }
        }
    }
    return false;
}
 
Example 20
Source File: TriangulatedTexture.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 3 votes vote down vote up
/**
 * This method draws the source image on the target image starting with the
 * specified positions.
 * 
 * @param target
 *            the target image
 * @param source
 *            the source image
 * @param targetXPos
 *            start X position on the target image
 * @param targetYPos
 *            start Y position on the target image
 */
private void draw(Image target, Image source, int targetXPos, int targetYPos) {
    PixelInputOutput sourceIO = PixelIOFactory.getPixelIO(source.getFormat());
    PixelInputOutput targetIO = PixelIOFactory.getPixelIO(target.getFormat());
    TexturePixel pixel = new TexturePixel();

    for (int x = 0; x < source.getWidth(); ++x) {
        for (int y = 0; y < source.getHeight(); ++y) {
            sourceIO.read(source, 0, pixel, x, y);
            targetIO.write(target, 0, pixel, targetXPos + x, targetYPos + y);
        }
    }
}