import java.io.File; import java.io.IOException; import java.net.URL; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.Slider; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import javafx.scene.transform.Scale; import javafx.stage.FileChooser; import javafx.stage.Stage; public class ManualMipmapTest extends Application { static final int NUM_SCALED=10; static FileChooser.ExtensionFilter imgfilter = new FileChooser.ExtensionFilter("Img", ".jpg", ".gif", ".jpeg", ".png"); Image scaledImages[] = new Image[NUM_SCALED + 1]; ImageView normalView; ImageView mipmapView; ScrollPane normalPane; ScrollPane mipmapPane; Label normalLabel; Label mipmapLabel; Button loadButton; Slider scaleSlider; Label scaleLabel; double scale = 1.0; Scene scene; Stage stage; @Override public void start(Stage stage) { normalView = new ImageView(); mipmapView = new ImageView(); loadButton = new Button("Load Image"); loadButton.addEventHandler(ActionEvent.ACTION, new EventHandler() { @Override public void handle(ActionEvent event) { FileChooser dlg = new FileChooser(); dlg.setSelectedExtensionFilter(imgfilter); File file = dlg.showOpenDialog(scene.getWindow()); Image img = new Image(file.toURI().toString()); setImage(img); } }); scaleSlider = new Slider(0.0, 1.0, 1.0); scaleSlider.setShowTickLabels(true); scaleSlider.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Number oldValue, Number newValue) { setScale(newValue.doubleValue()); } }); scaleLabel = new Label("Scale = 1.0"); normalPane = new ScrollPane(normalView); mipmapPane = new ScrollPane(mipmapView); normalPane.setPrefSize(300, 300); mipmapPane.setPrefSize(300, 300); normalLabel = new Label("Normal Scaling"); mipmapLabel = new Label("Mipmap Scaling"); mipmapPane.setTranslateX(300); normalLabel.setTranslateX(75); normalLabel.setTranslateY(320); mipmapLabel.setTranslateX(375); mipmapLabel.setTranslateY(320); loadButton.setTranslateX(0); loadButton.setTranslateY(350); scaleSlider.setTranslateX(150); scaleSlider.setTranslateY(350); scaleLabel.setTranslateX(300); scaleLabel.setTranslateY(350); Group root = new Group(normalPane, mipmapPane, normalLabel, mipmapLabel, loadButton, scaleSlider, scaleLabel); scene = new Scene(root); stage.setScene(scene); this.stage = stage; stage.show(); setSyntheticImage(); } boolean isOn(int v) { if ((v & 7) == 0) return true; if (((v+1) & 31) < 2) return true; return (((v+2) & 127) < 4); } void setSyntheticImage() { int dim = 0xffe; WritableImage wimg = new WritableImage(dim, dim); PixelWriter pw = wimg.getPixelWriter(); for (int y = 0; y < dim; y++) { for (int x = 0; x < dim; x++) { pw.setColor(x, y, isOn(x) || isOn(y) ? Color.BLACK : Color.WHITE); } } setImage(wimg); } void setImage(Image img) { scaledImages[0] = img; ImageView tmpview = new ImageView(); tmpview.setScaleX(0.5); tmpview.setScaleY(0.5); for (int i = 1; i <= NUM_SCALED; i++) { tmpview.setImage(scaledImages[i-1]); scaledImages[i] = tmpview.snapshot(null, null); } setScale(scale); } void setScale(double scale) { this.scale = scale; scaleLabel.setText("Scale = "+scale); System.out.print("scaling to "+scale); normalView.setImage(scaledImages[0]); normalView.getTransforms().setAll(new Scale(scale, scale)); int i = 0; while (i < NUM_SCALED) { if (scale > 0.5) break; scale *= 2.0; i++; } System.out.println(" using image "+i+" with scale of "+scale); mipmapView.setImage(scaledImages[i]); mipmapView.getTransforms().setAll(new Scale(scale, scale)); } }