// Hallo Welt!
Tinyray {
Sphere {
[0, 0, 0]; // Wo liegt die Kugel?
2.0 // Welchen Radius besitzt die Kugel?
}
Sun {
[1, 1, 1]; // In welcher Richtung befindet sich die Sonne?
[1, 1, 1] // Welche Farbe hat die Sonne?
}
}
package tinyray;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.LanguageKit;
import tinyray.language.PrettyPrint;
import tinyray.language.Tinyray;
import tinyray.language.Visitable;
/**
* Die Klasse UsePrettyPrint wandelt einen Tinyray-Code in einen sauber
* formatierten Tinyray-Code um.
*/
public class UsePrettyPrint {
/**
* Das Hauptprogramm, welches einen gegebenen Tinyray-Code in einen
* sauber formatierten Tinyray-Code umwandelt.
* Zudem wird der PrettyPrint-Test angewendet und ausgegeben.
* Das Ergebnis wird auf der Konsole ausgegeben (System.out).
* @param arguments Die Aufrufargumente.
* Das erste Argument gibt den Dateinamen der Tinyray-Datei an.
* Ist das erste Argument nicht gesetzt, erhält der Benutzer
* einen kurzen Hilfetext.
*/
public static void main(String[] arguments) {
// Mindestens ein Argument erforderlich: <Dateiname>
if (arguments.length > 0) {
try {
// Der Scanner erhält den Tinyray-Code als Stream.
Scanner scanner =
new Scanner(new FileInputStream(arguments[0]));
// Der Parser erhält den Scanner und eine konkreten Fabrik
// (hier: LanguageKit).
Parser<Visitable, Tinyray> parser =
new Parser<Visitable, Tinyray>(scanner, new LanguageKit());
// Der Parse-Vorgang bringt einen Syntaxbaum hervor.
// Die einzelnen Knoten des Syntaxbaumes werden mit Hilfe
// der konkreten Fabrik "LanguageKit", die dem Parser bei
// der Instantiierung mitgegeben wird, erzeugt.
Tinyray tinyray = parser.parse();
// Der Syntaxbaum besteht aus besuchbaren Knoten (accept).
// PrettyPrint ist ein Besucher, der die Wurzel des
// Syntaxbaums besucht und dabei einen sauber formatierten
// Tinyray-Code (prettyprint) generiert.
String prettyprint = tinyray.accept(new PrettyPrint(), "");
// Ausgabe des sauber formatierten Tinyray-Codes.
System.out.println(prettyprint);
// PrettyPrint-Test
System.out.print("\r\n// PrettyPrint-Test: ");
FileInputStream input = new FileInputStream(arguments[0]);
if (UsePrettyPrint.isValid(input)) {
System.out.println("OKAY.");
} else {
// Wird der Else-Zweig besucht, arbeitet der Parser
// oder der PrettyPrinter inkorrekt, d.h.
// PrettyPrint(code) != PrettyPrint(PrettyPrint(code))
// mit der Voraussetzung code steht für ein korrektes
// Tinyray-Quellprogramm.
System.out.println("FAILED.");
}
} catch (ParseException e) {
// Fehlermeldung, falls gegebener Tinyray-Code fehlerhaft.
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
// Fehlermeldung, falls das erste Argument keine Datei benennt.
System.err.println(e.getMessage());
}
} else {
// Kurzhilfe, falls Aufruf ohne Argument.
System.out.println(usage());
}
}
/**
* Erläuterung zum korrekten Aufruf (Kurzhilfe).
* @return Die Kurzhilfe als Zeichenkette.
*/
public static String usage() {
String result = "";
result += "java tinyray/UsePrettyPrint <TinyrayDatei>\r\n";
result += "\r\nBeispiele:\r\n";
result += " java tinyray/UsePrettyPrint MyScene.tinyray\r\n";
result += " java tinyray/UsePrettyPrint Test01.txt\r\n";
result += "\r\nHinweis:\r\n";
result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
return result;
}
/**
* Prüft, ob der Parser bezüglich eines bestimmten Eingabestroms
* (Tinyray-Programm) korrekt arbeitet. Dies wird geprüft mit der Formel:
* PrettyPrint(input) = PrettyPrint(PrettyPrint(input)).
* @param input Der Eingabestrom.
* @return true, falls korrekt.
* @throws ParseException Der Eingabestrom muss fehlerfrei geparst
* werden können, falls nicht wird eine ParseException geworfen.
* Wenn eine ParseException auftritt, kann die Korrektheit
* bzw. die Inkorrektheit des Parsers nicht nachgewiesen werden.
*/
public static boolean isValid(InputStream input) throws ParseException {
// PrettyPrint aus Eingabestrom erzeugen.
Scanner scanner1 = new Scanner(input);
Parser<Visitable, Tinyray> parser1 =
new Parser<Visitable, Tinyray>(scanner1, new LanguageKit());
Tinyray tinyray1 = parser1.parse();
String prettyprint1 = tinyray1.accept(new PrettyPrint(), "");
// PrettyPrint aus PrettyPrint des Eingabestroms erzeugen.
Scanner scanner2 = new Scanner(prettyprint1);
Parser<Visitable, Tinyray> parser2 =
new Parser<Visitable, Tinyray>(scanner2, new LanguageKit());
Tinyray tinyray2 = parser2.parse();
String prettyprint2 = tinyray2.accept(new PrettyPrint(), "");
// Prüfen, ob das erste PrettyPrint exakt dem zweiten PrettyPrint
// gleicht.
return prettyprint1.equals(prettyprint2);
}
}
Tinyray {
Camera {
[0.0, 0.0, 10.0]; // Location
[0.0, 0.0, 0.0]; // Look At
[0.0, 1.0, 0.0] // Up
}
Ambience {
[1.0, 1.0, 1.0] // Color
}
Background {
[0.0, 0.0, 0.0] // Color
}
Fog {
[0.0, 0.0, 0.0]; // Color
0.0 // Density
}
Sun {
[1.0, 1.0, 1.0]; // Direction
[1.0, 1.0, 1.0] // Color
}
Sphere {
[0.0, 0.0, 0.0]; // Center
2.0 // Radius
}
}
// PrettyPrint-Test: OKAY.
package tinyray;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.LanguageKit;
import tinyray.language.DotCode;
import tinyray.language.Tinyray;
import tinyray.language.Visitable;
/**
* Die Klasse UseDotCode generiert aus einem Tinyray-Code
* einen Dot-Code (siehe http://www.graphviz.org/).
*/
public class UseDotCode {
/**
* Das Hauptprogramm, welches aus einem Tinyray-Code einen Dot-Code
* generiert. Das Ergebnis wird auf der Konsole ausgegeben (System.out).
* @param arguments Die Aufrufargumente.
* Das erste Argument gibt den Dateinamen der Tinyray-Datei an.
* Ist das erste Argument nicht gesetzt, erhält der Benutzer
* einen kurzen Hilfetext.
*/
public static void main(String[] arguments) {
// Mindestens ein Argument erforderlich: <Dateiname>
if (arguments.length > 0) {
try {
// Der Scanner erhält den Tinyray-Code als Stream.
Scanner scanner =
new Scanner(new FileInputStream(arguments[0]));
// Der Parser erhält den Scanner und eine konkreten Fabrik
// (hier LanguageKit).
Parser<Visitable, Tinyray> parser =
new Parser<Visitable, Tinyray>(scanner, new LanguageKit());
// Der Parse-Vorgang bringt einen Syntaxbaum hervor.
// Die einzelnen Knoten des Syntaxbaumes werden automatisch
// von der konkreten Fabrik "LanguageKit" erzeugt.
Tinyray tinyray = parser.parse();
// Der Syntaxbaum besteht aus besuchbaren Knoten (accept).
boolean compact = false;
if (arguments.length > 1) {
compact = "compact".equalsIgnoreCase(arguments[1]);
}
String dotcode = tinyray.accept(new DotCode(compact), "");
// Ausgabe des DotCode
System.out.println(dotcode);
} catch (ParseException e) {
// Fehlermeldung, falls gegebener Tinyray-Code fehlerhaft.
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
// Fehlermeldung, falls das erste Argument keine Datei benennt.
System.err.println(e.getMessage());
}
} else {
// Kurzhilfe, falls Aufruf ohne Argument.
System.out.println(usage());
}
}
public static String usage() {
String result = "";
result += "java tinyray/UseDotCode <TinyrayDatei> [compact]\r\n";
result += "\r\nBeispiele:\r\n";
result += " java tinyray/UseDotCode MyScene.tinyray\r\n";
result += " java tinyray/UseDotCode Test01.txt compact\r\n";
result += "\r\nHinweis:\r\n";
result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
return result;
}
}
// Automatisch generierter Dot-Code
// $ dot -Tpng mein.dot -o mein.png
// Herkunft: Tinyray (http://www.stefan-baur.de)
digraph TinyrayGraph {
graph[rankdir=LR];
graph[ranksep=0.3];
edge[fontname="Arial"];
edge[fontsize=11];
edge[fontcolor="#333333"];
edge[color="#333333"];
node[height=0.08];
node[fontname="Arial"];
node[fontsize=10];
node[fontcolor="#333333"];
node[color="#333333"];
node0[label="Tinyray"];
node0;
edge[label=""];
node1[label="Camera"];
node0 -> node1;
edge[label="location"];
node2[label="Vector"];
node1 -> node2;
edge[label="x"];
node3[shape=record];
node3[label="{ Real | 0.0 }"];
node2 -> node3;
edge[label="y"];
node4[shape=record];
node4[label="{ Real | 0.0 }"];
node2 -> node4;
edge[label="z"];
node5[shape=record];
node5[label="{ Real | 10.0 }"];
node2 -> node5;
edge[label="look at"];
node6[label="Vector"];
node1 -> node6;
edge[label="x"];
node7[shape=record];
node7[label="{ Real | 0.0 }"];
node6 -> node7;
edge[label="y"];
node8[shape=record];
node8[label="{ Real | 0.0 }"];
node6 -> node8;
edge[label="z"];
node9[shape=record];
node9[label="{ Real | 0.0 }"];
node6 -> node9;
edge[label="up"];
node10[label="Vector"];
node1 -> node10;
edge[label="x"];
node11[shape=record];
node11[label="{ Real | 0.0 }"];
node10 -> node11;
edge[label="y"];
node12[shape=record];
node12[label="{ Real | 1.0 }"];
node10 -> node12;
edge[label="z"];
node13[shape=record];
node13[label="{ Real | 0.0 }"];
node10 -> node13;
edge[label=""];
node14[label="Ambience"];
node0 -> node14;
edge[label="color"];
node15[style=filled];
node15[fillcolor="#ffffff"];
node15[color="#333333"];
node15[fontcolor="#333333"];
node15[label="Vector"];
node14 -> node15;
edge[label="x"];
node16[shape=record];
node16[label="{ Real | 1.0 }"];
node15 -> node16;
edge[label="y"];
node17[shape=record];
node17[label="{ Real | 1.0 }"];
node15 -> node17;
edge[label="z"];
node18[shape=record];
node18[label="{ Real | 1.0 }"];
node15 -> node18;
edge[label=""];
node19[label="Background"];
node0 -> node19;
edge[label="color"];
node20[style=filled];
node20[fillcolor="#000000"];
node20[color="#cccccc"];
node20[fontcolor="#cccccc"];
node20[label="Vector"];
node19 -> node20;
edge[label="x"];
node21[shape=record];
node21[label="{ Real | 0.0 }"];
node20 -> node21;
edge[label="y"];
node22[shape=record];
node22[label="{ Real | 0.0 }"];
node20 -> node22;
edge[label="z"];
node23[shape=record];
node23[label="{ Real | 0.0 }"];
node20 -> node23;
edge[label=""];
node24[label="Fog"];
node0 -> node24;
edge[label="color"];
node25[style=filled];
node25[fillcolor="#000000"];
node25[color="#cccccc"];
node25[fontcolor="#cccccc"];
node25[label="Vector"];
node24 -> node25;
edge[label="x"];
node26[shape=record];
node26[label="{ Real | 0.0 }"];
node25 -> node26;
edge[label="y"];
node27[shape=record];
node27[label="{ Real | 0.0 }"];
node25 -> node27;
edge[label="z"];
node28[shape=record];
node28[label="{ Real | 0.0 }"];
node25 -> node28;
edge[label="density"];
node29[shape=record];
node29[label="{ Real | 0.0 }"];
node24 -> node29;
edge[label=""];
node30[label="Sun"];
node0 -> node30;
edge[label="direction"];
node31[label="Vector"];
node30 -> node31;
edge[label="x"];
node32[shape=record];
node32[label="{ Real | 1.0 }"];
node31 -> node32;
edge[label="y"];
node33[shape=record];
node33[label="{ Real | 1.0 }"];
node31 -> node33;
edge[label="z"];
node34[shape=record];
node34[label="{ Real | 1.0 }"];
node31 -> node34;
edge[label="color"];
node35[style=filled];
node35[fillcolor="#ffffff"];
node35[color="#333333"];
node35[fontcolor="#333333"];
node35[label="Vector"];
node30 -> node35;
edge[label="x"];
node36[shape=record];
node36[label="{ Real | 1.0 }"];
node35 -> node36;
edge[label="y"];
node37[shape=record];
node37[label="{ Real | 1.0 }"];
node35 -> node37;
edge[label="z"];
node38[shape=record];
node38[label="{ Real | 1.0 }"];
node35 -> node38;
edge[label=""];
node39[label="Sphere"];
node0 -> node39;
edge[label="center"];
node40[label="Vector"];
node39 -> node40;
edge[label="x"];
node41[shape=record];
node41[label="{ Real | 0.0 }"];
node40 -> node41;
edge[label="y"];
node42[shape=record];
node42[label="{ Real | 0.0 }"];
node40 -> node42;
edge[label="z"];
node43[shape=record];
node43[label="{ Real | 0.0 }"];
node40 -> node43;
edge[label="radius"];
node44[shape=record];
node44[label="{ Real | 2.0 }"];
node39 -> node44;
}
// Quelle: Tinyray-Code
//
// Tinyray {
// Camera {
// [0.0, 0.0, 10.0]; // Location
// [0.0, 0.0, 0.0]; // Look At
// [0.0, 1.0, 0.0] // Up
// }
// Ambience {
// [1.0, 1.0, 1.0] // Color
// }
// Background {
// [0.0, 0.0, 0.0] // Color
// }
// Fog {
// [0.0, 0.0, 0.0]; // Color
// 0.0 // Density
// }
// Sun {
// [1.0, 1.0, 1.0]; // Direction
// [1.0, 1.0, 1.0] // Color
// }
// Sphere {
// [0.0, 0.0, 0.0]; // Center
// 2.0 // Radius
// }
// }
// Automatisch generierter Dot-Code
// $ dot -Tpng mein.dot -o mein.png
// Herkunft: Tinyray (http://www.stefan-baur.de)
digraph TinyrayGraph {
graph[rankdir=LR];
graph[ranksep=0.3];
edge[fontname="Arial"];
edge[fontsize=11];
edge[fontcolor="#333333"];
edge[color="#333333"];
node[height=0.08];
node[fontname="Arial"];
node[fontsize=10];
node[fontcolor="#333333"];
node[color="#333333"];
node0[label="Tinyray"];
node0;
edge[label=""];
node1[label="Camera"];
node0 -> node1;
edge[label="location"];
node2[shape=record];
node2[label="{ Vector | { 0.0 | 0.0 | 10.0 } }"];
node1 -> node2;
edge[label="look at"];
node3[shape=record];
node3[label="{ Vector | { 0.0 | 0.0 | 0.0 } }"];
node1 -> node3;
edge[label="up"];
node4[shape=record];
node4[label="{ Vector | { 0.0 | 1.0 | 0.0 } }"];
node1 -> node4;
edge[label=""];
node5[label="Ambience"];
node0 -> node5;
edge[label="color"];
node6[style=filled];
node6[fillcolor="#ffffff"];
node6[color="#333333"];
node6[fontcolor="#333333"];
node6[shape=record];
node6[label="{ Vector | { 1.0 | 1.0 | 1.0 } }"];
node5 -> node6;
edge[label=""];
node7[label="Background"];
node0 -> node7;
edge[label="color"];
node8[style=filled];
node8[fillcolor="#000000"];
node8[color="#cccccc"];
node8[fontcolor="#cccccc"];
node8[shape=record];
node8[label="{ Vector | { 0.0 | 0.0 | 0.0 } }"];
node7 -> node8;
edge[label=""];
node9[label="Fog"];
node0 -> node9;
edge[label="color"];
node10[style=filled];
node10[fillcolor="#000000"];
node10[color="#cccccc"];
node10[fontcolor="#cccccc"];
node10[shape=record];
node10[label="{ Vector | { 0.0 | 0.0 | 0.0 } }"];
node9 -> node10;
edge[label="density"];
node11[shape=record];
node11[label="{ Real | 0.0 }"];
node9 -> node11;
edge[label=""];
node12[label="Sun"];
node0 -> node12;
edge[label="direction"];
node13[shape=record];
node13[label="{ Vector | { 1.0 | 1.0 | 1.0 } }"];
node12 -> node13;
edge[label="color"];
node14[style=filled];
node14[fillcolor="#ffffff"];
node14[color="#333333"];
node14[fontcolor="#333333"];
node14[shape=record];
node14[label="{ Vector | { 1.0 | 1.0 | 1.0 } }"];
node12 -> node14;
edge[label=""];
node15[label="Sphere"];
node0 -> node15;
edge[label="center"];
node16[shape=record];
node16[label="{ Vector | { 0.0 | 0.0 | 0.0 } }"];
node15 -> node16;
edge[label="radius"];
node17[shape=record];
node17[label="{ Real | 2.0 }"];
node15 -> node17;
}
// Quelle: Tinyray-Code
//
// Tinyray {
// Camera {
// [0.0, 0.0, 10.0]; // Location
// [0.0, 0.0, 0.0]; // Look At
// [0.0, 1.0, 0.0] // Up
// }
// Ambience {
// [1.0, 1.0, 1.0] // Color
// }
// Background {
// [0.0, 0.0, 0.0] // Color
// }
// Fog {
// [0.0, 0.0, 0.0]; // Color
// 0.0 // Density
// }
// Sun {
// [1.0, 1.0, 1.0]; // Direction
// [1.0, 1.0, 1.0] // Color
// }
// Sphere {
// [0.0, 0.0, 0.0]; // Center
// 2.0 // Radius
// }
// }
package tinyray;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.LanguageKit;
import tinyray.language.PovRayCode;
import tinyray.language.Tinyray;
import tinyray.language.Visitable;
/**
* Die Klasse UsePovRayCode generiert aus einem Tinyray-Code
* einen POV-Ray-Code (siehe http://www.povray.org/).
*/
public class UsePovRayCode {
/**
* Das Hauptprogramm, welches aus einem Tinyray-Code einen POV-Ray-Code
* generiert. Das Ergebnis wird auf der Konsole ausgegeben (System.out).
* @param arguments Die Aufrufargumente.
* Das erste Argument gibt den Dateinamen der Tinyray-Datei an.
* Ist das erste Argument nicht gesetzt, erhält der Benutzer
* einen kurzen Hilfetext.
*/
public static void main(String[] arguments) {
// Mindestens ein Argument erforderlich: <Dateiname>
if (arguments.length > 0) {
try {
// Der Scanner erhält den Tinyray-Code als Stream.
Scanner scanner =
new Scanner(new FileInputStream(arguments[0]));
// Der Parser erhält den Scanner und eine konkreten Fabrik
// (hier LanguageKit).
Parser<Visitable, Tinyray> parser =
new Parser<Visitable, Tinyray>(scanner, new LanguageKit());
// Der Parse-Vorgang bringt einen Syntaxbaum hervor.
// Die einzelnen Knoten des Syntaxbaumes werden automatisch
// von der konkreten Fabrik "LanguageKit" erzeugt.
Tinyray tinyray = parser.parse();
// Der Syntaxbaum besteht aus besuchbaren Knoten (accept).
// PovRayCode ist ein Besucher, der die Wurzel des
// Syntaxbaums besucht und dabei einen entsprechenden
// POV-Ray-Code (povraycode) generiert.
String povraycode = tinyray.accept(new PovRayCode(), "");
// Ausgabe des generierten POV-Ray-Codes.
System.out.println(povraycode);
} catch (ParseException e) {
// Fehlermeldung, falls gegebener Tinyray-Code fehlerhaft.
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
// Fehlermeldung, falls das erste Argument keine Datei benennt.
System.err.println(e.getMessage());
}
} else {
// Kurzhilfe, falls Aufruf ohne Argument.
System.out.println(usage());
}
}
/**
* Erläuterung zum korrekten Aufruf (Kurzhilfe).
* @return Die Kurzhilfe als Zeichenkette.
*/
public static String usage() {
String result = "";
result += "java tinyray/UsePovRayCode <TinyrayDatei>\r\n";
result += "\r\nBeispiele:\r\n";
result += " java tinyray/UsePovRayCode MyScene.tinyray\r\n";
result += " java tinyray/UsePovRayCode Test01.txt\r\n";
result += "\r\nHinweis:\r\n";
result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
return result;
}
}
// Automatisch generierter POV-Ray-Code (POV-Ray 3.6.1).
// Herkunft: Tinyray (http://www.stefan-baur.de)
global_settings {
ambient_light rgb <1.0, 1.0, 1.0>
}
camera {
perspective
location <0.0, 0.0, 10.0>
look_at <0.0, 0.0, 0.0>
up -y
sky <0.0, 1.0, 0.0>
angle 40.0 // eigentlich 30.0, aber 40.0 passt besser!?
}
background {
color rgb <0.0, 0.0, 0.0>
}
light_source {
<10000.0, 10000.0, 10000.0>, <1.0, 1.0, 1.0>
parallel
point_at <0.0, 0.0, 0.0>
}
sphere {
<0.0, 0.0, 0.0>, 2.0
texture {
pigment {
color rgb <0.5, 0.5, 0.5>
}
finish {
ambient rgb <0.1, 0.1, 0.1>
phong 0.5
phong_size 1000.0
reflection 0.4
}
}
}
// Quelle: Tinyray-Code
//
// Tinyray {
// Camera {
// [0.0, 0.0, 10.0]; // Location
// [0.0, 0.0, 0.0]; // Look At
// [0.0, 1.0, 0.0] // Up
// }
// Ambience {
// [1.0, 1.0, 1.0] // Color
// }
// Background {
// [0.0, 0.0, 0.0] // Color
// }
// Fog {
// [0.0, 0.0, 0.0]; // Color
// 0.0 // Density
// }
// Sun {
// [1.0, 1.0, 1.0]; // Direction
// [1.0, 1.0, 1.0] // Color
// }
// Sphere {
// [0.0, 0.0, 0.0]; // Center
// 2.0 // Radius
// }
// }
package tinyray;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.GlutCCode;
import tinyray.language.LanguageKit;
import tinyray.language.Tinyray;
import tinyray.language.Visitable;
/**
* Die Klasse UseGlutCCode generiert aus einem Tinyray-Code
* einen entsprechenden C-Code mit Hilfe der GLUT/OpenGL-Bibliothek
* (siehe http://www.opengl.org/).
*/
public class UseGlutCCode {
/**
* Das Hauptprogramm, welches aus einem Tinyray-Code einen entsprechenden
* Glut-C-Code generiert.
* Das Ergebnis wird auf der Konsole ausgegeben (System.out).
* @param arguments Die Aufrufargumente.
* Das erste Argument gibt den Dateinamen der Tinyray-Datei an.
* Ist das erste Argument nicht gesetzt, erhält der Benutzer
* einen kurzen Hilfetext.
*/
public static void main(String[] arguments) {
// Mindestens ein Argument erforderlich: <Dateiname>
if (arguments.length > 0) {
try {
// Der Scanner erhält den Tinyray-Code als Stream.
Scanner scanner =
new Scanner(new FileInputStream(arguments[0]));
// Der Parser erhält den Scanner und eine konkreten Fabrik
// (hier LanguageKit).
Parser<Visitable, Tinyray> parser =
new Parser<Visitable, Tinyray>(scanner, new LanguageKit());
// Der Parse-Vorgang bringt einen Syntaxbaum hervor.
// Die einzelnen Knoten des Syntaxbaumes werden automatisch
// von der konkreten Fabrik "LanguageKit" erzeugt.
Tinyray tinyray = parser.parse();
// Der Syntaxbaum besteht aus besuchbaren Knoten (accept).
// GlutCCode ist ein Besucher, der die Wurzel des
// Syntaxbaums besucht und dabei einen entsprechenden
// Glut/OpenGL-C-Code (glutccode) generiert.
String glutccode = tinyray.accept(new GlutCCode(), "");
// Ausgabe des generierten Glut-C-Codes.
System.out.println(glutccode);
} catch (ParseException e) {
// Fehlermeldung, falls gegebener Tinyray-Code fehlerhaft.
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
// Fehlermeldung, falls das erste Argument keine Datei benennt.
System.err.println(e.getMessage());
}
} else {
// Kurzhilfe, falls Aufruf ohne Argument.
System.out.println(usage());
}
}
/**
* Erläuterung zum korrekten Aufruf (Kurzhilfe).
* @return Die Kurzhilfe als Zeichenkette.
*/
public static String usage() {
String result = "";
result += "java tinyray/UseGlutCCode <TinyrayDatei>\r\n";
result += "\r\nBeispiele:\r\n";
result += " java tinyray/UseGlutCCode MyScene.tinyray\r\n";
result += " java tinyray/UseGlutCCode Test01.txt\r\n";
result += "\r\nHinweis:\r\n";
result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
return result;
}
}
/*
* Automatisch generierter Glut/OpenGL-C-Code.
* Kompilieren unter Linux: gcc -lglut <Dateiname>
* Herkunft: Tinyray (http://www.stefan-baur.de)
*/
#include <stdlib.h>
#include <GL/glut.h>
#define WIDTH 600
#define HEIGHT 400
// Globle Variablen für die Kamerabewegung
int mousemotion = 0;
int mousex = 0;
int mousey = 0;
GLfloat anglex = 0.0f;
GLfloat angley = 0.0f;
// Programm verlassen
void actionQuit()
{
exit(EXIT_SUCCESS);
}
// Initialisierung: Kameraposition
void actionInit()
{
mousex = 0;
mousey = 0;
anglex = 0.0f;
angley = 0.0f;
}
// Licht ein/aus
void actionToggleLighting()
{
if (glIsEnabled(GL_LIGHTING))
{
glDisable(GL_LIGHTING);
}
else
{
glEnable(GL_LIGHTING);
}
}
// Nebel ein/aus
void actionToggleFog()
{
if (glIsEnabled(GL_FOG))
{
glDisable(GL_FOG);
}
else
{
glEnable(GL_FOG);
}
}
// Shade flat/smooth
void actionToggleShadeModel()
{
int shadeModel;
glGetIntegerv(GL_SHADE_MODEL, &shadeModel);
if (shadeModel == GL_SMOOTH)
{
glShadeModel(GL_FLAT);
}
else
{
glShadeModel(GL_SMOOTH);
}
}
// Callback-Funktion: MouseFunc
void mouse(int button, int state, int x, int y)
{
mousemotion = (button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN);
if (mousemotion)
{
mousex = x;
mousey = y;
}
}
// Callback-Funktion: MotionFunc
void motion(int x, int y)
{
if (mousemotion)
{
anglex += (GLfloat)(y - mousey);
angley += (GLfloat)(x - mousex);
mousex = x;
mousey = y;
// Szene erneut zeichen
glutPostRedisplay();
}
}
// Callback-Funktion: KeyboardFunc
void keyboard(unsigned char keyPressed, int x, int y)
{
switch (keyPressed)
{
// Quit
case '0': case 'q': case 'Q': case 27:
actionQuit();
break;
// Init
case '1': case 'i': case 'I':
actionInit();
break;
// Toggle Lighting
case '2': case 'l': case 'L':
actionToggleLighting();
break;
// Toggle Fog
case '3': case 'f': case 'F': case 'n': case 'N':
actionToggleFog();
break;
// Toggle ShadeModel
case '4': case 's': case 'S':
actionToggleShadeModel();
break;
}
// Szene erneut zeichen
glutPostRedisplay();
}
// Menü-Handler
void menu(int menuItem)
{
switch (menuItem)
{
// Quit
case 0:
actionQuit();
break;
// Init
case 1:
actionInit();
break;
// Toggle Lighting
case 2:
actionToggleLighting();
break;
// Toggle Fog
case 3:
actionToggleFog();
break;
// Toggle ShadeModel
case 4:
actionToggleShadeModel();
break;
}
// Szene erneut zeichen
glutPostRedisplay();
}
// Callback-Funktion: ReshapeFunc
void reshape(int width, int height)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat aspect = (GLfloat)width / (GLfloat)height;
gluPerspective(30.0f, aspect, 0.1f, 1000.0f);
glViewport(0, 0, width, height);
}
// Callback-Funktion: DisplayFunc
void display(void)
{
// Initialisierungen vor dem Zeichen
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Hintergrundfarbe setzen
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Nebel
glFogi(GL_FOG_MODE, GL_EXP2);
glFogfv(
GL_FOG_COLOR,
(GLfloat[]) { 0.0f, 0.0f, 0.0f }
);
glFogf(
GL_FOG_DENSITY,
0.0f
);
// Kamera setzen
gluLookAt(
0.0f, 0.0f, 10.0f, // location
0.0f, 0.0f, 0.0f, // lookAt
0.0f, 1.0f, 0.0f // up
);
// Rundumbewegung mit Transformationen ermöglichen
glTranslatef(0.0f, 0.0f, 0.0f); // <- lookAt
glRotatef(anglex, 1.0f, 0.0f, 0.0f);
glRotatef(angley, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, 0.0f); // -> lookAt
// Globales, ambientes Umgebungslicht setzen
glLightModelfv(
GL_LIGHT_MODEL_AMBIENT,
(GLfloat[]) { 1.0f, 1.0f, 1.0f, 1.0f }
);
// Lichtquellen setzen
// Sonne 0 setzen
glLightfv(
GL_LIGHT0 + 0,
GL_AMBIENT,
(GLfloat[]) { 0.0f, 0.0f, 0.0f, 1.0f }
);
glLightfv(
GL_LIGHT0 + 0,
GL_DIFFUSE,
(GLfloat[]) { 1.0f, 1.0f, 1.0f, 1.0f }
);
glLightfv(
GL_LIGHT0 + 0,
GL_SPECULAR,
(GLfloat[]) { 1.0f, 1.0f, 1.0f, 1.0f }
);
glLightfv(
GL_LIGHT0 + 0,
GL_POSITION,
(GLfloat[]) { 1.0f, 1.0f, 1.0f, 0.0f }
);
glEnable(GL_LIGHT0 + 0);
// Basismaterial
// Defaults 5
glColor3f(0.5f, 0.5f, 0.5f); // Farbe, falls Licht deaktiviert
glMaterialfv(
GL_FRONT,
GL_DIFFUSE,
(GLfloat[]) { 0.5f, 0.5f, 0.5f, 1.0f }
);
glMaterialfv(
GL_FRONT,
GL_AMBIENT,
(GLfloat[]) { 0.1f, 0.1f, 0.1f, 1.0f }
);
glMaterialfv(
GL_FRONT,
GL_SPECULAR,
(GLfloat[]) { 0.5f, 0.5f, 0.5f, 1.0f }
);
glMaterialf(
GL_FRONT,
GL_SHININESS,
1000.0f
);
// Mirror = 0.4f wird nicht unterstützt!
// Geoobjekte setzen
/* > Sphere */
// Parameters 0
glPushMatrix();
glTranslatef(0.0f, 0.0f, 0.0f);
glutSolidSphere(2.0f, 30, 30);
glPopMatrix();
// Defaults 0
/* < Sphere */
glutSwapBuffers();
}
// Die Hauptfunktion
int main(int argc, char* argv[])
{
// Glut-Fenster
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WIDTH, HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
// Ein Popup-Menu anbinden
glutCreateMenu(menu);
glutAddMenuEntry("Startposition", 1);
glutAddMenuEntry("Lichter ein/aus", 2);
glutAddMenuEntry("Nebel ein/aus", 3);
glutAddMenuEntry("Shade flat/smooth", 4);
glutAddMenuEntry("Programm verlassen", 0);
glutAttachMenu(GLUT_RIGHT_BUTTON);
// OpenGL-Einstellungen
glEnable(GL_LIGHTING);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_FOG);
glShadeModel(GL_SMOOTH);
// Zunächst Szene darstellen
reshape(WIDTH, HEIGHT);
display();
// Callback-Funktionen integrieren
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return EXIT_SUCCESS;
}
/* Quelle: Tinyray-Code
Tinyray {
Camera {
[0.0, 0.0, 10.0]; // Location
[0.0, 0.0, 0.0]; // Look At
[0.0, 1.0, 0.0] // Up
}
Ambience {
[1.0, 1.0, 1.0] // Color
}
Background {
[0.0, 0.0, 0.0] // Color
}
Fog {
[0.0, 0.0, 0.0]; // Color
0.0 // Density
}
Sun {
[1.0, 1.0, 1.0]; // Direction
[1.0, 1.0, 1.0] // Color
}
Sphere {
[0.0, 0.0, 0.0]; // Center
2.0 // Radius
}
}
*/
package tinyray;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.LanguageKit;
import tinyray.language.Tinyray;
import tinyray.language.VRMLCode;
import tinyray.language.Visitable;
/**
* Die Klasse UseVRMLCode generiert aus einem Tinyray-Code
* einen entsprechenden VRML-Code
* (siehe http://www.web3d.org/x3d/specifications/#vrml97).
*/
public class UseVRMLCode {
/**
* Das Hauptprogramm, welches aus einem Tinyray-Code einen entsprechenden
* VRML-Code generiert.
* Das Ergebnis wird auf der Konsole ausgegeben (System.out).
* @param arguments Die Aufrufargumente.
* Das erste Argument gibt den Dateinamen der Tinyray-Datei an.
* Ist das erste Argument nicht gesetzt, erhält der Benutzer
* einen kurzen Hilfetext.
*/
public static void main(String[] arguments) {
// Mindestens ein Argument erforderlich: <Dateiname>
if (arguments.length > 0) {
try {
// Der Scanner erhält den Tinyray-Code als Stream.
Scanner scanner =
new Scanner(new FileInputStream(arguments[0]));
// Der Parser erhält den Scanner und eine konkreten Fabrik
// (hier LanguageKit).
Parser<Visitable, Tinyray> parser =
new Parser<Visitable, Tinyray>(scanner, new LanguageKit());
// Der Parse-Vorgang bringt einen Syntaxbaum hervor.
// Die einzelnen Knoten des Syntaxbaumes werden automatisch
// von der konkreten Fabrik "LanguageKit" erzeugt.
Tinyray tinyray = parser.parse();
// Der Syntaxbaum besteht aus besuchbaren Knoten (accept).
// VRMLCode ist ein Besucher, der die Wurzel des
// Syntaxbaums besucht und dabei einen entsprechenden
// VRML-Code generiert.
String vrmlcode = tinyray.accept(new VRMLCode(), "");
// Ausgabe des generierten VRML-Codes.
System.out.println(vrmlcode);
} catch (ParseException e) {
// Fehlermeldung, falls gegebener Tinyray-Code fehlerhaft.
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
// Fehlermeldung, falls das erste Argument keine Datei benennt.
System.err.println(e.getMessage());
}
} else {
// Kurzhilfe, falls Aufruf ohne Argument.
System.out.println(usage());
}
}
/**
* Erläuterung zum korrekten Aufruf (Kurzhilfe).
* @return Die Kurzhilfe als Zeichenkette.
*/
public static String usage() {
String result = "";
result += "java tinyray/UseVRMLCode <TinyrayDatei>\r\n";
result += "\r\nBeispiele:\r\n";
result += " java tinyray/UseVRMLCode MyScene.tinyray\r\n";
result += " java tinyray/UseVRMLCode Test01.txt\r\n";
result += "\r\nHinweis:\r\n";
result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
return result;
}
}
#VRML V2.0 utf8
# Automatisch generierter VRML-Code.
# Herkunft: Tinyray (http://www.stefan-baur.de)
Viewpoint {
fieldOfView 0.5235987755982988
position 0.0 0.0 10.0
orientation
0.0
1.0
0.0
0.0
}
Background { skyColor 0.0 0.0 0.0 }
# global ambience is ignored
DirectionalLight {
color 1.0 1.0 1.0
intensity 0.75
direction -1.0 -1.0 -1.0
}
Transform {
translation 0.0 0.0 0.0
children Shape {
appearance Appearance {
material Material {
diffuseColor 0.5 0.5 0.5
emissiveColor 0.1 0.1 0.1
specularColor 0.5 0.5 0.5
shininess 1000.0
# mirror/reflection is not supported by VRML
}
}
geometry Sphere { radius 2.0 }
}
}
# Quelle: Tinyray-Code
#
# Tinyray {
# Camera {
# [0.0, 0.0, 10.0]; // Location
# [0.0, 0.0, 0.0]; // Look At
# [0.0, 1.0, 0.0] // Up
# }
# Ambience {
# [1.0, 1.0, 1.0] // Color
# }
# Background {
# [0.0, 0.0, 0.0] // Color
# }
# Fog {
# [0.0, 0.0, 0.0]; // Color
# 0.0 // Density
# }
# Sun {
# [1.0, 1.0, 1.0]; // Direction
# [1.0, 1.0, 1.0] // Color
# }
# Sphere {
# [0.0, 0.0, 0.0]; // Center
# 2.0 // Radius
# }
# }