如何创建使用不同图像的立方体?在JavaFX中使用不同纹理创建立方体
我想选择使用用户输入动态使用的图像。
明显的解决办法是创建六个独立的矩形(这是不是可以表现更差明智?),但有利用现有Box
功能(例如,类似于TextureCubeMap
东西Java3D的)的方式?
到目前为止,所有我发现是解决使用一个图像作为纹理整个立方体(例如:this)
如何创建使用不同图像的立方体?在JavaFX中使用不同纹理创建立方体
我想选择使用用户输入动态使用的图像。
明显的解决办法是创建六个独立的矩形(这是不是可以表现更差明智?),但有利用现有Box
功能(例如,类似于TextureCubeMap
东西Java3D的)的方式?
到目前为止,所有我发现是解决使用一个图像作为纹理整个立方体(例如:this)
我写了一个原始纹理地图集类,结合图像使用WritableImage
。使用bin包装算法可能会更有效率,目前我正在阅读它,但在我的特殊情况下,所有图像的宽度相同,这对我来说工作得很好。它只是垂直放置图像。但是,其目前的结构应该很容易扩展到不同的地图集实施。
阿特拉斯:
public class TextureAtlas {
private final Image image;
private final Map<String, TextureRegion> regions;
public TextureAtlas(Image image) {
this.image = image;
regions = new HashMap<>();
}
/**
* Creates an extremely primitive texture atlas.
* Could use bin packing eventually.
*/
public TextureAtlas(Map<String, Image> images) {
this.regions = new HashMap<>();
int height = (int) Math.ceil(images.values().stream().mapToDouble(Image::getHeight).sum());
OptionalDouble w = images.values().stream().mapToDouble(Image::getWidth).max();
WritableImage i = new WritableImage(w.isPresent() ? (int) w.getAsDouble() : 0, height);
int h = 0;
PixelWriter writer = i.getPixelWriter();
for(Map.Entry<String, Image> entry : images.entrySet()) {
Image img = entry.getValue();
PixelReader reader = img.getPixelReader();
for(int x = 0; x < img.getWidth(); x++)
for(int y = 0; y < img.getHeight(); y++)
writer.setColor(x, y + h, reader.getColor(x, y));
createRegion(entry.getKey(), img, 0, h, (int) img.getWidth(), (int) img.getHeight());
h += img.getHeight();
} this.image = i;
}
public TextureRegion createRegion(String name, int x, int y, int width, int height) {
TextureRegion reg;
regions.put(name, reg = new TextureRegion(this, x, y, width, height));
return reg;
}
private TextureRegion createRegion(String name, Image image, int x, int y, int width, int height) {
TextureRegion reg;
regions.put(name, reg = new TextureRegion(this, x, y, width, height));
return reg;
}
public TextureRegion getRegion(String name) {
return regions.get(name);
}
public Map<String, TextureRegion> getRegions() {
return Collections.unmodifiableMap(regions);
}
public int getWidth() {
return (int) image.getWidth();
}
public int getHeight() {
return (int) image.getHeight();
}
public int getColorAt(int x, int y) {
if(x >= image.getWidth() || y >= image.getHeight()) return -1;
return image.getPixelReader().getArgb(x, y);
}
public Image getImage() {
return image;
}
}
纹理区域:
public class TextureRegion {
public final TextureAtlas atlas;
public final int x, y, width, height;
private Image image;
public TextureRegion(TextureAtlas atlas, int x, int y, int width, int height) {
this.atlas = atlas;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public TextureRegion(TextureAtlas atlas, Image image, int x, int y, int width, int height) {
this.atlas = atlas;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.image = image;
}
public int getColorAt(int x, int y) {
return atlas.getColorAt(this.x + x, this.y + y);
}
public double[] getTextureCoordinates(double x, double y) {
return new double[] {getU(x), getV(y)};
}
public double[] scaleTextureCoordinates(double u, double v, double max) {
return new double[] {scaleU(u, max), scaleV(v, max)};
}
public double getU(double x) {
return (this.x + x)/atlas.getWidth();
}
public double getV(double y) {
return (this.y + y)/atlas.getHeight();
}
public double scaleU(double u, double max) { //For conversion from UV systems using a different max value than 1.0
return getU(u/max * this.width);
}
public double scaleV(double v, double max) {
return getV(v/max * this.height);
}
public Image getImage() {
if(image != null) return image; //Lazily initialize
else {
WritableImage img = new WritableImage(width, height);
PixelWriter writer = img.getPixelWriter();
PixelReader reader = atlas.getImage().getPixelReader();
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
writer.setArgb(x, y, reader.getArgb(x + this.x, y + this.y));
return this.image = img;
}
}
}
TextureRegion
s为图谱和getImage
返回一个延迟初始化Image
表示整个区域的区域。
你为什么不只是单独的图像复制到一个单一的一个?您甚至可以通过画布和快照在程序中执行此操作。
干得好。这正是我回答你的问题时想到的。我应该明确地提到关键词“纹理地图集”:-)。 – mipa