Diese Anwendung nutzt das
Raytracer-Package
von Tinyray,
um aus einem gegebenen
Tinyray-Programm
ein
3D-Bild
zu rendern.
package tinyray;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.raytracer.Element;
import tinyray.raytracer.RaytracerKit;
import tinyray.raytracer.Tinyray;
import tinyray.raytracer.Viewport;
/**
* Die Klasse UseRaytracer erzeugt aus einem Tinyray-Programm eine Bilddatei.
*/
public class UseRaytracer {
// Mögliche Ausgabeformate.
private static enum Format { ALL, ASCIIPPM, BINARYPPM, BMP, RAW, PNG, JPG }
/**
* Das Hauptprogramm, welches zu einem gegebenen Tinyray-Programm ein
* entsprechendes 3D-Bild rendert. Das Bild wird in das Verzeichnis
* gespeichert, in dem sich das Tinyray-Programm befindet.
* @param arguments Die Aufrufargumente.
* Argument 0 benennt das Tinyray-Programm (erforderlich).
* Argument 1 setzt das Ausgabeformat (optional; default all).
* Argument 2 setzt die Bildbreite (optional; default 360).
* Argument 3 setzt die Bildhöhe (optional; default 240).
* Argument 4 setzt die Rekursionstiefe (optional; default 3).
* Argument 5 setzt den Antialiaswert (optional; default 2).
*/
public static void main(String[] arguments) {
// Default-Einstellungen.
String sourcefile = null; // Wird mit Argument 0 überschrieben!
Format format = Format.ALL;
int width = 360;
int height = 240;
int depth = 3;
int antialias = 2;
/* Argumente prüfen. */
// Mindestens ein Argument erforderlich: <Dateiname>
if (arguments.length > 0) {
// Tinyray-Input (erforderlich)
sourcefile = arguments[0];
// Ausgabeformat (optional)
if (arguments.length > 1) {
if (arguments[1].toLowerCase().equals("all")) {
format = Format.ALL;
} else if (arguments[1].toLowerCase().equals("asciippm")) {
format = Format.ASCIIPPM;
} else if (arguments[1].toLowerCase().equals("binaryppm")) {
format = Format.BINARYPPM;
} else if (arguments[1].toLowerCase().equals("ppm")) {
format = Format.BINARYPPM;
} else if (arguments[1].toLowerCase().equals("bmp")) {
format = Format.BMP;
} else if (arguments[1].toLowerCase().equals("raw")) {
format = Format.RAW;
} else if (arguments[1].toLowerCase().equals("png")) {
format = Format.PNG;
} else if (arguments[1].toLowerCase().equals("jpg")) {
format = Format.JPG;
} else {
System.err.println("Fehler: Ungültiges Ausgabeformat.");
System.err.println(usage());
return;
}
}
// Breite des Ausgabebildes (optional)
if (arguments.length > 2) {
try {
width = Integer.parseInt(arguments[2]);
if (width <= 0) {
System.err.println("Fehler: Breite < 1.");
System.err.println(usage());
return;
}
} catch (NumberFormatException e) {
System.err.println("Fehler: Ungültige Breitenangabe.");
System.err.println(usage());
return;
}
}
// Höhe des Ausgabebildes (optional)
if (arguments.length > 3) {
try {
height = Integer.parseInt(arguments[3]);
if (height <= 0) {
System.err.println("Fehler: Höhe < 1.");
System.err.println(usage());
return;
}
} catch (NumberFormatException e) {
System.err.println("Fehler: Ungültige Höhenangabe.");
System.err.println(usage());
return;
}
}
// Rekursionstiefe (optional)
if (arguments.length > 4) {
try {
depth = Integer.parseInt(arguments[4]);
} catch (NumberFormatException e) {
System.err.println("Fehler: Ungültige Tiefenangabe.");
System.err.println(usage());
return;
}
}
// Antialias (optional)
if (arguments.length > 5) {
try {
antialias = Integer.parseInt(arguments[5]);
if (antialias <= 0) {
System.err.println("Fehler: Antialias < 1.");
System.err.println(usage());
return;
}
} catch (NumberFormatException e) {
System.err.println("Fehler: Ungültige Antialiasangabe.");
System.err.println(usage());
return;
}
}
} else {
System.out.println(usage());
return;
}
/* Hier gehts weiter, wenn die Argumente korrekt angegeben sind. */
try {
// Der Scanner erhält den Tinyray-Code als Stream.
Scanner scanner = new Scanner(new FileInputStream(sourcefile));
// Der Parser erhält den Scanner und eine konkreten Fabrik
// (hier RaytracerKit).
Parser<Element, Tinyray> parser =
new Parser<Element, Tinyray>(scanner, new RaytracerKit());
// Der Parse-Vorgang bringt einen Syntaxbaum hervor.
// Die einzelnen Knoten des Syntaxbaumes werden automatisch
// von der konkreten Fabrik "RaytracerKit" erzeugt.
// Die Wurzel des Syntaxbaumes ist der Raytracer und
// die Kindknoten beschreiben die Szene der 3D-Welt.
Tinyray tinyray = parser.parse();
// Zunächst wird ein leeres Ausgabebild mit den gewünschten
// Ausmaßen (Breite und Höhe) erzeugt.
Viewport viewport = new Viewport(width, height);
// Der Render-Vorgang wird gestartet. Die Ergebnisse werden
// in das Ausgabebild (Viewport) hineingeschrieben.
tinyray.render(viewport, depth, antialias);
// Das Ausgabebild wird im gewünschten Format mit der
// entsprechenden Dateiendung gespeichert.
try {
// Parameter in den Namen der Ausgabedatei integrieren
String imageprefix = sourcefile;
imageprefix += "." + width + "x" + height;
imageprefix += ".d" + depth;
imageprefix += ".a" + antialias;
if ((format == Format.ALL) || (format == Format.ASCIIPPM)) {
String output = imageprefix + ".ascii.ppm";
viewport.storeAsAsciiPPM(output);
System.out.println("Bild gespeichert: " + output);
}
if ((format == Format.ALL) || (format == Format.BINARYPPM)) {
String output = imageprefix + ".binary.ppm";
viewport.storeAsBinaryPPM(output);
System.out.println("Bild gespeichert: " + output);
}
if ((format == Format.ALL) || (format == Format.BMP)) {
String output = imageprefix + ".bmp";
viewport.storeAsBMP(output);
System.out.println("Bild gespeichert: " + output);
}
if ((format == Format.ALL) || (format == Format.RAW)) {
String output = imageprefix + ".raw";
viewport.storeAsRAW(output);
System.out.println("Bild gespeichert: " + output);
}
if ((format == Format.ALL) || (format == Format.PNG)) {
String output = imageprefix + ".png";
viewport.storeAsPNG(output);
System.out.println("Bild gespeichert: " + output);
}
if ((format == Format.ALL) || (format == Format.JPG)) {
String output = imageprefix + ".jpg";
viewport.storeAsJPG(output);
System.out.println("Bild gespeichert: " + output);
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
} catch (ParseException e) {
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
}
}
/**
* Erläuterung zum korrekten Aufruf (Kurzhilfe).
* @return Die Kurzhilfe als Zeichenkette.
*/
public static String usage() {
String result = "";
result += "java tinyray/UseRaytracer <TinyrayDatei> [<Format>\r\n";
result += " [<Breite>[<Höhe>[<Tiefe>[<Antialias>]]]]]\r\n";
result += "\r\n";
result += " Format: all | asciippm |";
result += " binaryppm | ppm | bmp | raw | png | jpg\r\n";
result += " Breite: integer (> 0)\r\n";
result += " Höhe: integer (> 0)\r\n";
result += " Tiefe: integer\r\n";
result += " Antialias: integer (> 0)\r\n";
result += "\r\n";
result += "Voreinstellungen:\r\n";
result += " Format = all\r\n";
result += " Breite = 360\r\n";
result += " Höhe = 240\r\n";
result += " Tiefe = 3\r\n";
result += " Antialias = 2\r\n";
result += "\r\n";
result += "Beispiele:\r\n";
result += " java tinyray/UseRaytracer MyFirst.tray bmp 160 120 0\r\n";
result += " java tinyray/UseRaytracer Test01.txt jpg 600 400 1 5\r\n";
result += " java tinyray/UseRaytracer Test02.txt binaryppm\r\n";
result += "\r\n";
result += "Hinweis:\r\n";
result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
return result;
}
}
Ein Programmaufruf ohne Aufrufparameter zeigt dem Aufrufenden die Programmkurzhilfe
(usage).
java tinyray/UseRaytracer <TinyrayDatei> [<Format>
[<Breite>[<Höhe>[<Tiefe>[<Antialias>]]]]]
Format: all | asciippm | binaryppm | ppm | bmp | raw | png | jpg
Breite: integer (> 0)
Höhe: integer (> 0)
Tiefe: integer
Antialias: integer (> 0)
Voreinstellungen:
Format = all
Breite = 360
Höhe = 240
Tiefe = 3
Antialias = 2
Beispiele:
java tinyray/UseRaytracer MyFirst.tray bmp 160 120 0
java tinyray/UseRaytracer Test01.txt jpg 600 400 1 5
java tinyray/UseRaytracer Test02.txt binaryppm
Hinweis:
Mindestens JRE (java-1.5.0) erforderlich.