/** * Constructor that simply stores precalculated images. * * @param faceTextures * a collection of images for the mesh's faces * @param blenderContext * the blender context */ public TriangulatedTexture(Collection<TriangleTextureElement> faceTextures, BlenderContext blenderContext) { maxTextureSize = blenderContext.getBlenderKey().getMaxTextureSize(); this.faceTextures = faceTextures; for (TriangleTextureElement faceTextureElement : faceTextures) { if (format == null) { format = faceTextureElement.image.getFormat(); } else if (format != faceTextureElement.image.getFormat()) { throw new IllegalArgumentException("Face texture element images MUST have the same image format!"); } } }
/** * This method blends the each image using the given blender and taking base * texture into consideration. * * @param textureBlender * the texture blender that holds the blending definition * @param baseTexture * the texture that is 'below' the current texture (can be null) * @param blenderContext * the blender context */ public void blend(TextureBlender textureBlender, TriangulatedTexture baseTexture, BlenderContext blenderContext) { Format newFormat = null; for (TriangleTextureElement triangleTextureElement : faceTextures) { Image baseImage = baseTexture == null ? null : baseTexture.getFaceTextureElement(triangleTextureElement.faceIndex).image; triangleTextureElement.image = textureBlender.blend(triangleTextureElement.image, baseImage, blenderContext); if (newFormat == null) { newFormat = triangleTextureElement.image.getFormat(); } else if (newFormat != triangleTextureElement.image.getFormat()) { throw new IllegalArgumentException("Face texture element images MUST have the same image format!"); } } format = newFormat; }
public void setDepthTexture(TextureArray tex, int layer){ if (id != -1) throw new UnsupportedOperationException("FrameBuffer already initialized."); Image img = tex.getImage(); checkSetTexture(tex, true); depthBuf = new RenderBuffer(); depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH; depthBuf.tex = tex; depthBuf.format = img.getFormat(); depthBuf.layer = layer; }
/** * Set the depth texture to use for this framebuffer. * * @param tex The color texture to set. */ public void setDepthTexture(Texture2D tex){ if (id != -1) throw new UnsupportedOperationException("FrameBuffer already initialized."); Image img = tex.getImage(); checkSetTexture(tex, true); depthBuf = new RenderBuffer(); depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH; depthBuf.tex = tex; depthBuf.format = img.getFormat(); } public void setDepthTexture(TextureArray tex, int layer){
/** * Resizes the image to the given width and height. * @param source * the source image (this remains untouched, the new image instance is created) * @param width * the target image width * @param height * the target image height * @return the resized image */ public static Image resizeTo(Image source, int width, int height) { BufferedImage sourceImage = ImageToAwt.convert(source, false, false, 0); double scaleX = width / (double) sourceImage.getWidth(); double scaleY = height / (double) sourceImage.getHeight(); AffineTransform scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY); AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR); BufferedImage scaledImage = bilinearScaleOp.filter(sourceImage, new BufferedImage(width, height, sourceImage.getType())); return ImageUtils.toJmeImage(scaledImage, source.getFormat()); }
private void checkSetTexture(Texture tex, boolean depth){ Image img = tex.getImage(); if (img == null) throw new IllegalArgumentException("Texture not initialized with RTT."); if (depth && !img.getFormat().isDepthFormat()) throw new IllegalArgumentException("Texture image format must be depth."); else if (!depth && img.getFormat().isDepthFormat()) throw new IllegalArgumentException("Texture image format must be color/luminance."); // check that resolution matches texture resolution if (width != img.getWidth() || height != img.getHeight()) throw new IllegalArgumentException("Texture image resolution " + "must match FB resolution"); if (samples != tex.getImage().getMultiSamples()) throw new IllegalStateException("Texture samples must match framebuffer samples"); }
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); } }
/** * Add a color texture array to use for this framebuffer. * If MRT is enabled, then each subsequently added texture can be * rendered to through a shader that writes to the array <code>gl_FragData</code>. * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) } * is rendered to by the shader. * * @param tex The texture array to add. */ public void addColorTexture(TextureArray tex, int layer) { if (id != -1) throw new UnsupportedOperationException("FrameBuffer already initialized."); Image img = tex.getImage(); checkSetTexture(tex, false); RenderBuffer colorBuf = new RenderBuffer(); colorBuf.slot = colorBufs.size(); colorBuf.tex = tex; colorBuf.format = img.getFormat(); colorBuf.layer = layer; colorBufs.add(colorBuf); }
/** * Add a color texture to use for this framebuffer. * If MRT is enabled, then each subsequently added texture can be * rendered to through a shader that writes to the array <code>gl_FragData</code>. * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) } * is rendered to by the shader. * * @param tex The texture to add. * @see #addColorBuffer(com.jme3.texture.Image.Format) */ public void addColorTexture(Texture2D tex) { if (id != -1) throw new UnsupportedOperationException("FrameBuffer already initialized."); Image img = tex.getImage(); checkSetTexture(tex, false); RenderBuffer colorBuf = new RenderBuffer(); colorBuf.slot = colorBufs.size(); colorBuf.tex = tex; colorBuf.format = img.getFormat(); colorBufs.add(colorBuf); }
public void write(Image image, int layer, TexturePixel pixel, int x, int y) { int index = (y * image.getWidth() + x) * (image.getFormat().getBitsPerPixel() >> 3); this.write(image, layer, pixel, index); } }
public void read(Image image, int layer, TexturePixel pixel, int index) { ByteBuffer data = image.getData(layer); switch (image.getFormat()) { case Luminance8: pixel.fromIntensity(data.get(index)); break; case Luminance8Alpha8: pixel.fromIntensity(data.get(index)); pixel.setAlpha(data.get(index + 1)); break; case Luminance16F: pixel.intensity = FastMath.convertHalfToFloat(data.getShort(index)); break; case Luminance16FAlpha16F: pixel.intensity = FastMath.convertHalfToFloat(data.getShort(index)); pixel.alpha = FastMath.convertHalfToFloat(data.getShort(index + 2)); break; case Luminance32F: pixel.intensity = Float.intBitsToFloat(data.getInt(index)); break; default: throw new IllegalStateException("Unknown luminance format type."); } }
/** * Add a color texture to use for this framebuffer. * If MRT is enabled, then each subsequently added texture can be * rendered to through a shader that writes to the array <code>gl_FragData</code>. * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) } * is rendered to by the shader. * * @param tex The cube-map texture to add. * @param face The face of the cube-map to render to. */ public void addColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) { if (id != -1) throw new UnsupportedOperationException("FrameBuffer already initialized."); Image img = tex.getImage(); checkSetTexture(tex, false); RenderBuffer colorBuf = new RenderBuffer(); colorBuf.slot = colorBufs.size(); colorBuf.tex = tex; colorBuf.format = img.getFormat(); colorBuf.face = face.ordinal(); colorBufs.add(colorBuf); }
public void read(Image image, int layer, TexturePixel pixel, int x, int y) { int index = (y * image.getWidth() + x) * (image.getFormat().getBitsPerPixel() >> 3); this.read(image, layer, pixel, index); }
/** * This method converts the given texture into black and whit (grayscale) texture. * * @param source * the source texture * @return grayscale texture */ public static Image convertToGrayscaleTexture(Image source) { BufferedImage sourceImage = ImageToAwt.convert(source, false, false, 0); ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); op.filter(sourceImage, sourceImage); return ImageUtils.toJmeImage(sourceImage, source.getFormat()); }
/** * This method triangulates the given flat texture. The given texture is not * changed. * * @param texture2d * the texture to be triangulated * @param uvs * the UV coordinates for each face */ public TriangulatedTexture(Texture2D texture2d, List<Vector2f> uvs, BlenderContext blenderContext) { maxTextureSize = blenderContext.getBlenderKey().getMaxTextureSize(); faceTextures = new TreeSet<TriangleTextureElement>(new Comparator<TriangleTextureElement>() { public int compare(TriangleTextureElement o1, TriangleTextureElement o2) { return o1.faceIndex - o2.faceIndex; } }); int facesCount = uvs.size() / 3; for (int i = 0; i < facesCount; ++i) { faceTextures.add(new TriangleTextureElement(i, texture2d.getImage(), uvs, true, blenderContext)); } format = texture2d.getImage().getFormat(); }
/** * Creates a new three-dimensional texture using the given image. * @param img The image to use. */ public Texture3D(Image img) { super(); setImage(img); if (img.getFormat().isDepthFormat()) { setMagFilter(MagFilter.Nearest); setMinFilter(MinFilter.NearestNoMipMaps); } }
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)); }
/** * Inits the mip maps of a cube map witht he given number of mip maps * @param nbMipMaps the number of mip maps to initialize */ public void initMipMaps(int nbMipMaps) { int maxMipMap = (int) (Math.log(image.getWidth()) / Math.log(2) + 1); if (nbMipMaps > maxMipMap) { throw new IllegalArgumentException("Max mip map number for a " + image.getWidth() + "x" + image.getHeight() + " cube map is " + maxMipMap); } sizes = new int[nbMipMaps]; int totalSize = 0; for (int i = 0; i < nbMipMaps; i++) { int size = (int) pow(2, maxMipMap - 1 - i); sizes[i] = size * size * image.getFormat().getBitsPerPixel() / 8; totalSize += sizes[i]; } image.setMipMapSizes(sizes); image.getData().clear(); for (int i = 0; i < 6; i++) { image.addData(BufferUtils.createByteBuffer(totalSize)); } mipMapRaster = new MipMapImageRaster(image, 0); } }
public static void resizeToPowerOf2(Image image){ BufferedImage original = ImageToAwt.convert(image, false, true, 0); int potWidth = FastMath.nearestPowerOfTwo(image.getWidth()); int potHeight = FastMath.nearestPowerOfTwo(image.getHeight()); int potSize = Math.max(potWidth, potHeight); BufferedImage scaled = scaleDown(original, potSize, potSize); AWTLoader loader = new AWTLoader(); Image output = loader.load(scaled, false); image.setWidth(potSize); image.setHeight(potSize); image.setDepth(0); image.setData(output.getData(0)); image.setFormat(output.getFormat()); image.setMipMapSizes(null); }
private void convertAndPutImage(Image image, float posX, float posY) { Texture tex = new Texture2D(image); tex.setMagFilter(MagFilter.Nearest); tex.setMinFilter(MinFilter.NearestNoMipMaps); tex.setAnisotropicFilter(16); Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); mat.setTexture("ColorMap", tex); Quad q = new Quad(5, 5); Geometry g = new Geometry("quad", q); g.setLocalTranslation(posX, posY - 5, -0.0001f); g.setMaterial(mat); rootNode.attachChild(g); BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); BitmapText txt = new BitmapText(fnt); txt.setBox(new Rectangle(0, 0, 5, 5)); txt.setQueueBucket(RenderQueue.Bucket.Transparent); txt.setSize(0.5f); txt.setText(image.getFormat().name()); txt.setLocalTranslation(posX, posY, 0); rootNode.attachChild(txt); }