package tinyray.language;
import java.util.Iterator;
/** * Die Klasse GlutCCode implementiert einen Besucher (Visitor), * der aus einem Syntaxbaum, der mit Hilfe von LanguageKit erzeugt ist, * einen Glut/OpenGL-Code in der Sprache C erzeugt. */ public class GlutCCode implements Visitor<String, String> {
// Der Zeilenumbruch. private final static String NEWLINE = "\r\n";
// Die Einrückung. private final static String INDENT = "\t";
// Zeigt an, ob die lokalen oder die globalen Parameter // ausgegeben werden sollen. private boolean localParameters;
// Die globalen Parameter. private Defaults defaults;
// Der aktuelle Index für das parallele Sonnenlicht. private int lightIndex;
/** * Initialisiert den GlutCCode-Besucher. * Die globalen Parameter werden eingestellt mit: * color = [0.5, 0.5, 0.5]; * ambient = [0.1, 0.1, 0.1]; * specular = 0.5; * shininess = 1000.0; * mirror = 0.4 (wird aber nicht benutzt). */ public GlutCCode() { this.localParameters = true; // Setzt globale Parameter this.defaults = new Defaults(); // color = [0.5, 0.5, 0.5] this.defaults.parameters.visitables.add(new Vector(0.5, 0.5, 0.5)); // ambient = [0.1, 0.1, 0.1] this.defaults.parameters.visitables.add(new Vector(0.1, 0.1, 0.1)); // specular = 0.5 this.defaults.parameters.visitables.add(new Real(0.5)); // shininess = 1000.0 this.defaults.parameters.visitables.add(new Real(1000.0)); // mirror = 0.4 this.defaults.parameters.visitables.add(new Real(0.4)); // Setzt den Sonnenlichtindex. this.lightIndex = 0; }
/** * Besucht einen besuchbaren Tinyray-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param tinyray Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Tinyray tinyray, String indent) { String result = "";
// Kommentar result += indent; result += "/*"; result += NEWLINE + indent; result += " * Automatisch generierter Glut/OpenGL-C-Code."; result += NEWLINE + indent; result += " * Kompilieren unter Linux: gcc -lglut <Dateiname>"; result += NEWLINE + indent; result += " * Herkunft: Tinyray (http://www.stefan-baur.de)"; result += NEWLINE + indent; result += " */"; result += NEWLINE;
// Includes und Makros result += NEWLINE + indent; result += "#include <stdlib.h>"; result += NEWLINE + indent; result += "#include <GL/glut.h>"; result += NEWLINE; result += NEWLINE + indent; result += "#define WIDTH 600"; result += NEWLINE + indent; result += "#define HEIGHT 400"; result += NEWLINE;
// Globale Variablen result += NEWLINE + indent; result += "// Globle Variablen für die Kamerabewegung"; result += NEWLINE + indent; result += "int mousemotion = 0;"; result += NEWLINE + indent; result += "int mousex = 0;"; result += NEWLINE + indent; result += "int mousey = 0;"; result += NEWLINE + indent; result += "GLfloat anglex = 0.0f;"; result += NEWLINE + indent; result += "GLfloat angley = 0.0f;"; result += NEWLINE;
// Aktion Quit result += NEWLINE + indent; result += "// Programm verlassen"; result += NEWLINE + indent; result += "void actionQuit()"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "exit(EXIT_SUCCESS);"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Aktion Init result += NEWLINE + indent; result += "// Initialisierung: Kameraposition"; result += NEWLINE + indent; result += "void actionInit()"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "mousex = 0;"; result += NEWLINE + indent + INDENT; result += "mousey = 0;"; result += NEWLINE + indent + INDENT; result += "anglex = 0.0f;"; result += NEWLINE + indent + INDENT; result += "angley = 0.0f;"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Aktion Licht ein/aus result += NEWLINE + indent; result += "// Licht ein/aus"; result += NEWLINE + indent; result += "void actionToggleLighting()"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "if (glIsEnabled(GL_LIGHTING))"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "glDisable(GL_LIGHTING);"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent + INDENT; result += "else"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "glEnable(GL_LIGHTING);"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Aktion Nebel ein/aus result += NEWLINE + indent; result += "// Nebel ein/aus"; result += NEWLINE + indent; result += "void actionToggleFog()"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "if (glIsEnabled(GL_FOG))"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "glDisable(GL_FOG);"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent + INDENT; result += "else"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "glEnable(GL_FOG);"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Aktion Shade flat/smooth result += NEWLINE + indent; result += "// Shade flat/smooth"; result += NEWLINE + indent; result += "void actionToggleShadeModel()"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "int shadeModel;"; result += NEWLINE + indent + INDENT; result += "glGetIntegerv(GL_SHADE_MODEL, &shadeModel);"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "if (shadeModel == GL_SMOOTH)"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "glShadeModel(GL_FLAT);"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent + INDENT; result += "else"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "glShadeModel(GL_SMOOTH);"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Mouse result += NEWLINE + indent; result += "// Callback-Funktion: MouseFunc"; result += NEWLINE + indent; result += "void mouse(int button, int state, int x, int y)"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "mousemotion = "; result += "(button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN);"; result += NEWLINE + indent + INDENT; result += "if (mousemotion)"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "mousex = x;"; result += NEWLINE + indent + INDENT + INDENT; result += "mousey = y;"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Motion result += NEWLINE + indent; result += "// Callback-Funktion: MotionFunc"; result += NEWLINE + indent; result += "void motion(int x, int y)"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "if (mousemotion)"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "anglex += (GLfloat)(y - mousey);"; result += NEWLINE + indent + INDENT + INDENT; result += "angley += (GLfloat)(x - mousex);"; result += NEWLINE + indent + INDENT + INDENT; result += "mousex = x;"; result += NEWLINE + indent + INDENT + INDENT; result += "mousey = y;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Szene erneut zeichen"; result += NEWLINE + indent + INDENT + INDENT; result += "glutPostRedisplay();"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Keyboard result += NEWLINE + indent; result += "// Callback-Funktion: KeyboardFunc"; result += NEWLINE + indent; result += "void keyboard(unsigned char keyPressed, int x, int y)"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "switch (keyPressed)"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "// Quit"; result += NEWLINE + indent + INDENT + INDENT; result += "case '0': case 'q': case 'Q': case 27:"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionQuit();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Init"; result += NEWLINE + indent + INDENT + INDENT; result += "case '1': case 'i': case 'I':"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionInit();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Toggle Lighting"; result += NEWLINE + indent + INDENT + INDENT; result += "case '2': case 'l': case 'L':"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionToggleLighting();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Toggle Fog"; result += NEWLINE + indent + INDENT + INDENT; result += "case '3': case 'f': case 'F': case 'n': case 'N':"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionToggleFog();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Toggle ShadeModel"; result += NEWLINE + indent + INDENT + INDENT; result += "case '4': case 's': case 'S':"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionToggleShadeModel();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent + INDENT; result += "// Szene erneut zeichen"; result += NEWLINE + indent + INDENT; result += "glutPostRedisplay();"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Menu result += NEWLINE + indent; result += "// Menü-Handler"; result += NEWLINE + indent; result += "void menu(int menuItem)"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "switch (menuItem)"; result += NEWLINE + indent + INDENT; result += "{"; result += NEWLINE + indent + INDENT + INDENT; result += "// Quit"; result += NEWLINE + indent + INDENT + INDENT; result += "case 0:"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionQuit();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Init"; result += NEWLINE + indent + INDENT + INDENT; result += "case 1:"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionInit();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Toggle Lighting"; result += NEWLINE + indent + INDENT + INDENT; result += "case 2:"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionToggleLighting();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Toggle Fog"; result += NEWLINE + indent + INDENT + INDENT; result += "case 3:"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionToggleFog();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT + INDENT; result += "// Toggle ShadeModel"; result += NEWLINE + indent + INDENT + INDENT; result += "case 4:"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "actionToggleShadeModel();"; result += NEWLINE + indent + INDENT + INDENT + INDENT; result += "break;"; result += NEWLINE + indent + INDENT; result += "}"; result += NEWLINE + indent + INDENT; result += "// Szene erneut zeichen"; result += NEWLINE + indent + INDENT; result += "glutPostRedisplay();"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Reshape result += NEWLINE + indent; result += "// Callback-Funktion: ReshapeFunc"; result += NEWLINE + indent; result += "void reshape(int width, int height)"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "glMatrixMode(GL_PROJECTION);"; result += NEWLINE + indent + INDENT; result += "glLoadIdentity();"; result += NEWLINE + indent + INDENT; result += "GLfloat aspect = (GLfloat)width / (GLfloat)height;"; result += NEWLINE + indent + INDENT; result += "gluPerspective(30.0f, aspect, 0.1f, 1000.0f);"; result += NEWLINE + indent + INDENT; result += "glViewport(0, 0, width, height);"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Display result += NEWLINE + indent; result += "// Callback-Funktion: DisplayFunc"; result += NEWLINE + indent; result += "void display(void)"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "// Initialisierungen vor dem Zeichen"; result += NEWLINE + indent + INDENT; result += "glMatrixMode(GL_MODELVIEW);"; result += NEWLINE + indent + INDENT; result += "glLoadIdentity();"; result += NEWLINE + indent + INDENT; result += "glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);"; result += NEWLINE; // Background result += NEWLINE; result += tinyray.background.accept(this, indent + INDENT); result += NEWLINE; // Fog result += NEWLINE; result += tinyray.fog.accept(this, indent + INDENT); result += NEWLINE; // Camera result += NEWLINE; result += tinyray.camera.accept(this, indent + INDENT); result += NEWLINE; result += NEWLINE + indent + INDENT; result += "// Rundumbewegung mit Transformationen ermöglichen"; result += NEWLINE + indent + INDENT; result += "glTranslatef("; result += tinyray.camera.lookAt.accept(this, ""); result += "); // <- lookAt"; result += NEWLINE + indent + INDENT; result += "glRotatef(anglex, 1.0f, 0.0f, 0.0f);"; result += NEWLINE + indent + INDENT; result += "glRotatef(angley, 0.0f, 1.0f, 0.0f);"; result += NEWLINE + indent + INDENT; result += "glTranslatef("; result += Vector.anti(tinyray.camera.lookAt).accept(this, ""); result += "); // -> lookAt"; result += NEWLINE; // Ambience result += NEWLINE; result += tinyray.ambience.accept(this, indent + INDENT); result += NEWLINE; // Suns result += NEWLINE + indent + INDENT; result += "// Lichtquellen setzen"; result += NEWLINE; Iterator<Sun> suns = tinyray.suns.iterator(); while (suns.hasNext()) { result += NEWLINE; result += suns.next().accept(this, indent + INDENT); result += NEWLINE; } // Materialinitialisierung mit Defaults result += NEWLINE + indent + INDENT; result += "// Basismaterial"; result += NEWLINE; result += this.defaults.accept(this, indent + INDENT); result += NEWLINE; // Visitables wie Geoobjekte und Defaults. result += NEWLINE + indent + INDENT; result += "// Geoobjekte setzen"; result += NEWLINE; Iterator<Visitable> visitables = tinyray.visitables.iterator(); while (visitables.hasNext()) { result += NEWLINE; result += visitables.next().accept(this, indent + INDENT); result += NEWLINE; } // Das neue Bild anzeigen result += NEWLINE + indent + INDENT; result += "glutSwapBuffers();"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
// Main-Methode result += NEWLINE + indent; result += "// Die Hauptfunktion"; result += NEWLINE + indent; result += "int main(int argc, char* argv[])"; result += NEWLINE + indent; result += "{"; result += NEWLINE + indent + INDENT; result += "// Glut-Fenster"; result += NEWLINE + indent + INDENT; result += "glutInit(&argc, argv);"; result += NEWLINE + indent + INDENT; result += "glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);"; result += NEWLINE + indent + INDENT; result += "glutInitWindowSize(WIDTH, HEIGHT);"; result += NEWLINE + indent + INDENT; result += "glutInitWindowPosition(100, 100);"; result += NEWLINE + indent + INDENT; result += "glutCreateWindow(argv[0]);"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "// Ein Popup-Menu anbinden"; result += NEWLINE + indent + INDENT; result += "glutCreateMenu(menu);"; result += NEWLINE + indent + INDENT; result += "glutAddMenuEntry(\"Startposition\", 1);"; result += NEWLINE + indent + INDENT; result += "glutAddMenuEntry(\"Lichter ein/aus\", 2);"; result += NEWLINE + indent + INDENT; result += "glutAddMenuEntry(\"Nebel ein/aus\", 3);"; result += NEWLINE + indent + INDENT; result += "glutAddMenuEntry(\"Shade flat/smooth\", 4);"; result += NEWLINE + indent + INDENT; result += "glutAddMenuEntry(\"Programm verlassen\", 0);"; result += NEWLINE + indent + INDENT; result += "glutAttachMenu(GLUT_RIGHT_BUTTON);"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "// OpenGL-Einstellungen"; result += NEWLINE + indent + INDENT; result += "glEnable(GL_LIGHTING);"; result += NEWLINE + indent + INDENT; result += "glDepthFunc(GL_LESS);"; result += NEWLINE + indent + INDENT; result += "glEnable(GL_DEPTH_TEST);"; result += NEWLINE + indent + INDENT; result += "glEnable(GL_NORMALIZE);"; result += NEWLINE + indent + INDENT; result += "glEnable(GL_FOG);"; result += NEWLINE + indent + INDENT; result += "glShadeModel(GL_SMOOTH);"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "// Zunächst Szene darstellen"; result += NEWLINE + indent + INDENT; result += "reshape(WIDTH, HEIGHT);"; result += NEWLINE + indent + INDENT; result += "display();"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "// Callback-Funktionen integrieren"; result += NEWLINE + indent + INDENT; result += "glutMouseFunc(mouse);"; result += NEWLINE + indent + INDENT; result += "glutMotionFunc(motion);"; result += NEWLINE + indent + INDENT; result += "glutKeyboardFunc(keyboard);"; result += NEWLINE + indent + INDENT; result += "glutReshapeFunc(reshape);"; result += NEWLINE + indent + INDENT; result += "glutDisplayFunc(display);"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "glutMainLoop();"; result += NEWLINE; result += NEWLINE + indent + INDENT; result += "return EXIT_SUCCESS;"; result += NEWLINE + indent; result += "}"; result += NEWLINE;
result += NEWLINE + indent; result += "/* Quelle: Tinyray-Code"; result += NEWLINE; result += NEWLINE; result += tinyray.accept(new PrettyPrint(), indent + INDENT); result += NEWLINE; result += NEWLINE + indent; result += "*/"; result += NEWLINE; return result; }
/** * Besucht einen besuchbaren Camera-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param camera Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Camera camera, String indent) { String result = ""; result += indent; result += "// Kamera setzen"; result += NEWLINE + indent; result += "gluLookAt("; result += NEWLINE + indent + INDENT; result += camera.location.accept(this, ""); result += ", // location"; result += NEWLINE + indent + INDENT; result += camera.lookAt.accept(this, ""); result += ", // lookAt"; result += NEWLINE + indent + INDENT; result += camera.up.accept(this, ""); result += " // up"; result += NEWLINE + indent; result += ");"; return result; }
/** * Besucht einen besuchbaren Background-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param background Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Background background, String indent) { String result = ""; result += indent; result += "// Hintergrundfarbe setzen"; result += NEWLINE + indent; result += "glClearColor("; result += background.color.accept(this, ""); result += ", 1.0f"; result += ");"; return result; }
/** * Besucht einen besuchbaren Ambience-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param ambience Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Ambience ambience, String indent) { String result = ""; result += indent; result += "// Globales, ambientes Umgebungslicht setzen"; result += NEWLINE + indent; result += "glLightModelfv("; result += NEWLINE + indent + INDENT; result += "GL_LIGHT_MODEL_AMBIENT,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += ambience.color.accept(this, ""); result += ", 1.0f }"; result += NEWLINE + indent; result += ");"; return result; }
/** * Besucht einen besuchbaren Fog-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param fog Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Fog fog, String indent) { String result = ""; result += indent; result += "// Nebel"; result += NEWLINE + indent; result += "glFogi(GL_FOG_MODE, GL_EXP2);"; result += NEWLINE + indent; result += "glFogfv("; result += NEWLINE + indent + INDENT; result += "GL_FOG_COLOR,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += fog.color.accept(this, ""); result += " }"; result += NEWLINE + indent; result += ");"; result += NEWLINE + indent; result += "glFogf("; result += NEWLINE + indent + INDENT; result += "GL_FOG_DENSITY,"; result += NEWLINE + indent + INDENT; result += fog.density.accept(this, ""); result += NEWLINE + indent; result += ");"; return result; }
/** * Besucht einen besuchbaren Sun-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param sun Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Sun sun, String indent) { String result = ""; result += indent; result += "// Sonne " + this.lightIndex + " setzen"; result += NEWLINE + indent; // Ambienter Anteil result += "glLightfv("; result += NEWLINE + indent + INDENT; result += "GL_LIGHT0 + " + this.lightIndex + ","; result += NEWLINE + indent + INDENT; result += "GL_AMBIENT,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { 0.0f, 0.0f, 0.0f, 1.0f }"; result += NEWLINE + indent; result += ");"; result += NEWLINE + indent; // Diffuser Anteil result += "glLightfv("; result += NEWLINE + indent + INDENT; result += "GL_LIGHT0 + " + this.lightIndex + ","; result += NEWLINE + indent + INDENT; result += "GL_DIFFUSE,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += sun.color.accept(this, ""); result += ", 1.0f }"; result += NEWLINE + indent; result += ");"; result += NEWLINE + indent; // Spekularer Anteil result += "glLightfv("; result += NEWLINE + indent + INDENT; result += "GL_LIGHT0 + " + this.lightIndex + ","; result += NEWLINE + indent + INDENT; result += "GL_SPECULAR,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += sun.color.accept(this, ""); result += ", 1.0f }"; result += NEWLINE + indent; result += ");"; result += NEWLINE + indent; // Paralleles Licht result += "glLightfv("; result += NEWLINE + indent + INDENT; result += "GL_LIGHT0 + " + this.lightIndex + ","; result += NEWLINE + indent + INDENT; result += "GL_POSITION,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += sun.direction.accept(this, ""); result += ", 0.0f }"; result += NEWLINE + indent; result += ");"; result += NEWLINE + indent; result += "glEnable(GL_LIGHT0 + " + this.lightIndex + ");"; this.lightIndex++; return result; }
/** * Besucht einen besuchbaren Bounding-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param bounding Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Bounding bounding, String indent) { String result = ""; result += indent; result += "/* > Bounding */"; result += NEWLINE; Iterator<Visitable> visitables = bounding.visitables.iterator(); while (visitables.hasNext()) { result += NEWLINE; result += visitables.next().accept(this, indent + INDENT); result += NEWLINE; } result += NEWLINE + indent; result += "/* < Bounding */"; return result; }
/** * Besucht einen besuchbaren Triangle-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param triangle Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Triangle triangle, String indent) { String result = ""; result += indent; result+= "/* > Triangle */"; result += NEWLINE; this.localParameters = true; result += triangle.parameters.accept(this, indent); result += NEWLINE + indent; result += "glBegin(GL_TRIANGLES);"; result += NEWLINE + indent + INDENT; result += "glNormal3f("; Vector normal = Vector.normal0(triangle.x, triangle.y, triangle.z); result += normal.accept(this, ""); result += ");"; result += NEWLINE + indent + INDENT; result += "glVertex3f("; result += triangle.x.accept(this, ""); result += ");"; result += NEWLINE + indent + INDENT; result += "glVertex3f("; result += triangle.y.accept(this, ""); result += ");"; result += NEWLINE + indent + INDENT; result += "glVertex3f("; result += triangle.z.accept(this, ""); result += ");"; result += NEWLINE + indent; result += "glEnd();"; result += NEWLINE; this.localParameters = false; result += triangle.parameters.accept(this, indent); result += NEWLINE + indent; result+= "/* < Triangle */"; return result; }
/** * Besucht einen besuchbaren Sphere-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param sphere Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Sphere sphere, String indent) { String result = ""; result += indent; result+= "/* > Sphere */"; result += NEWLINE; this.localParameters = true; result += sphere.parameters.accept(this, indent); result += NEWLINE + indent; result += "glPushMatrix();"; result += NEWLINE + indent; result += "glTranslatef("; result += sphere.center.accept(this, ""); result += ");"; result += NEWLINE + indent; result += "glutSolidSphere("; result += sphere.radius.accept(this, ""); result += ", 30, 30);"; result += NEWLINE + indent; result += "glPopMatrix();"; result += NEWLINE; this.localParameters = false; result += sphere.parameters.accept(this, indent); result += NEWLINE + indent; result += "/* < Sphere */"; return result; }
/** * Besucht einen besuchbaren Plane-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param plane Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Plane plane, String indent) { String result = ""; result += indent; result+= "/* > Plane */"; result += NEWLINE; this.localParameters = true; result += plane.parameters.accept(this, indent); result += NEWLINE + indent; result += "glPushMatrix();";
// center = (p.x + p.y + p.z) / 3.0 Vector center = new Vector(); center.x.value = plane.x.x.value; center.y.value = plane.x.y.value; center.z.value = plane.x.z.value; center.x.value += plane.y.x.value; center.y.value += plane.y.y.value; center.z.value += plane.y.z.value; center.x.value += plane.z.x.value; center.y.value += plane.z.y.value; center.z.value += plane.z.z.value; center.x.value /= 3.0; center.y.value /= 3.0; center.z.value /= 3.0;
result += NEWLINE + indent; result += "glTranslatef("; result += center.accept(this, ""); result += ");"; result += NEWLINE + indent; result += "glScalef(500.0f, 500.0f, 500.0f);"; result += NEWLINE + indent; result += "glTranslatef("; result += Vector.anti(center).accept(this, ""); result += ");";
result += NEWLINE + indent; result += "glBegin(GL_TRIANGLES);"; result += NEWLINE + indent + INDENT; result += "glNormal3f(0.0f, 0.0f, 1.0f);"; result += NEWLINE + indent + INDENT; result += "glVertex3f("; result += plane.x.accept(this, ""); result += ");"; result += NEWLINE + indent + INDENT; result += "glVertex3f("; result += plane.y.accept(this, ""); result += ");"; result += NEWLINE + indent + INDENT; result += "glVertex3f("; result += plane.z.accept(this, ""); result += ");"; result += NEWLINE + indent; result += "glEnd();";
result += NEWLINE + indent; result += "glPopMatrix();"; result += NEWLINE; this.localParameters = false; result += plane.parameters.accept(this, indent); result += NEWLINE + indent; result+= "/* < Plane */"; return result; }
/** * Besucht einen besuchbaren Defaults-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param defaults Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Defaults defaults, String indent) { String result = "";
int thisSize = this.defaults.parameters.visitables.size(); int size = defaults.parameters.visitables.size();
for (int i = 0; i < Math.min(thisSize, size); i++) { Visitable v = defaults.parameters.visitables.get(i); this.defaults.parameters.visitables.set(i, v); }
// Die Parameter werden wieder zurückgesetzt. this.localParameters = false; result += defaults.parameters.accept(this, indent); return result; }
/** * Besucht einen besuchbaren Parameters-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param parameters Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Parameters parameters, String indent) { String result = ""; int size = parameters.visitables.size(); result += indent; if (this.localParameters) { result += "// Parameters " + size; } else { result += "// Defaults " + size; } if (0 < size) { Visitable v0; if (this.localParameters) { v0 = parameters.visitables.get(0); } else { v0 = this.defaults.parameters.visitables.get(0); } result += NEWLINE + indent; result += "glColor3f("; result += v0.accept(this, ""); result += "); // Farbe, falls Licht deaktiviert"; result += NEWLINE + indent; result += "glMaterialfv("; result += NEWLINE + indent + INDENT; result += "GL_FRONT,"; result += NEWLINE + indent + INDENT; result += "GL_DIFFUSE,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += v0.accept(this, ""); result += ", 1.0f }"; result += NEWLINE + indent; result += ");"; } if (1 < size) { Visitable v1; if (this.localParameters) { v1 = parameters.visitables.get(1); } else { v1 = this.defaults.parameters.visitables.get(1); } result += NEWLINE + indent; result += "glMaterialfv("; result += NEWLINE + indent + INDENT; result += "GL_FRONT,"; result += NEWLINE + indent + INDENT; result += "GL_AMBIENT,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += v1.accept(this, ""); result += ", 1.0f }"; result += NEWLINE + indent; result += ");"; } if (2 < size) { Visitable v2; if (this.localParameters) { v2 = parameters.visitables.get(2); } else { v2 = this.defaults.parameters.visitables.get(2); } result += NEWLINE + indent; result += "glMaterialfv("; result += NEWLINE + indent + INDENT; result += "GL_FRONT,"; result += NEWLINE + indent + INDENT; result += "GL_SPECULAR,"; result += NEWLINE + indent + INDENT; result += "(GLfloat[]) { "; result += v2.accept(this, ""); result += ", "; result += v2.accept(this, ""); result += ", "; result += v2.accept(this, ""); result += ", 1.0f }"; result += NEWLINE + indent; result += ");"; } if (3 < size) { Visitable v3; if (this.localParameters) { v3 = parameters.visitables.get(3); } else { v3 = this.defaults.parameters.visitables.get(3); } result += NEWLINE + indent; result += "glMaterialf("; result += NEWLINE + indent + INDENT; result += "GL_FRONT,"; result += NEWLINE + indent + INDENT; result += "GL_SHININESS,"; result += NEWLINE + indent + INDENT; result += v3.accept(this, ""); result += NEWLINE + indent; result += ");"; } if (4 < size) { Visitable v4; if (this.localParameters) { v4 = parameters.visitables.get(4); } else { v4 = this.defaults.parameters.visitables.get(4); } result += NEWLINE + indent; result += "// Mirror = "; result += v4.accept(this, ""); result += " wird nicht unterstützt!"; } return result; }
/** * Besucht einen besuchbaren Vector-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param vector Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Vector vector, String indent) { String result = ""; result += vector.x.accept(this, indent); result += ", "; result += vector.y.accept(this, ""); result += ", "; result += vector.z.accept(this, ""); return result; }
/** * Besucht einen besuchbaren Real-Knoten und generiert einen * entsprechenden Glut/OpenGL-C-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param real Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte Glut/OpenGL-C-Code. */ public String visit(Real real, String indent) { String result = ""; result += indent; result += new Float(real.value).toString(); // downcast result += "f"; return result; } } | |