Teekanne

Beispiel

Visual Studio Projekt herunterladen

Um dieses Beispiel kurz und transparent zu halten, wurde es nicht objektorientiert, sondern wieder einmal nur durch verschiedene Funktionen in der Datei main.cpp gelöst.

Es gibt eine neue Funktion initGL, die umfangreichere Initialisierungen vornimmt und insbedondere Licht- und Materialeigenschaften setzt. Sehen wir uns die Funktion initLight genauer an.

void initLight()
{
    // Beleuchtung global einschalten
    glEnable(GL_LIGHTING);

    // Farben der Lichtquelle setzen (r,g,b,a)
    GLfloat ambient[4]  = { 0.1f, 0.0f, 0.0f, 1.0f };
    GLfloat diffuse[4]  = { 0.6f, 0.4f, 0.2f, 1.0f };
    GLfloat specular[4] = { 0.6f, 0.6f, 0.4f, 1.0f };

    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_AMBIENT,  ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);

} // initLight()

Der wichtigste Befehl ist glEnable(GL_LIGHTING), der unser Beleuchtungsmodell für alle zukünftig gesetzten Vektoren einschaltet. Er ist auch mit Vorsicht zu genießen, da wir nun Lichtquellen und Materialeigenschaften setzen müssen, um nicht nur einen schwarzen Bildschirm zu sehen. Mit glDisable(GL_LIGHTING) ließe sich die Beleuchtung auch wieder global abschalten.

Es gibt in OpenGL 8 Lichtquellen, durchnummeriert von GL_LIGHT0 bis GL_LIGHT7. Hier schalten wir die erste Lichtquelle an und setzen ihre Farbeigenschaften.

In der Funktion initMaterial werden danach die Materialeigenschaften auf ähnliche Art und Weise gesetzt:

void initMaterial()
{
    // Materialfarben setzen (r,g,b,a)
    GLfloat globalAmbient[4] = {0.0, 0.0, 0.0, 1.0};
    GLfloat ambient[4]       = {1.0, 1.0, 1.0, 1.0};
    GLfloat diffuse[4]       = {1.0, 1.0, 1.0, 1.0};
    GLfloat specular[4]      = {1.0, 1.0, 1.0, 1.0};

    // Globale ambiente Beleuchtung
    // komplett herunternehmen
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,
                   globalAmbient);

    // Materialparameter setzen
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);
    glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuse);
    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);
    glMaterialf (GL_FRONT_AND_BACK,GL_SHININESS,16.0f);

} // initMaterial()

In unserem Fall ist also die Lichtquelle farbig und das Material weiß. Bevor wir die Materialeigenschaften sezten, setzen wir noch die globale ambiente Beleuchtung auf schwarz. Sie ist standardmäßig auf ein dunkles Grau gesetzt (0.2, 0.2, 0.2, 1.0). Alle anderen Parameter der Lichtberechnung belassen wir in diesem Beispiel auf ihren Standardwerten.

Die einzige andere Funktion, die unsere Aufmerksamkeit verdient, ist die render Funktion, in der wir die Position unserer Lichtquelle setzen (OpenGL arbeitet standardmäßig mit Punktlichtquellen).

void render()
{
    // Lichtposition setzen (x,y,z,w)
    GLfloat position[4] =
        { cos(rotation), 0.5f, sin(rotation), 1.0f };
    glLightfv(GL_LIGHT0, GL_POSITION, position);

    // klein skalierte Teekanne zeichnen
    glutSolidTeapot(0.5);

} // render()

Die Position der Lichtquelle wird in sogenannten homogenen Koordinaten angegeben. Ihr werdet mit der letzten Koordinate w vermutlich nie arbeiten. Wenn sie auf Eins gesetzt wird, entspricht der Vektor genau der Position (x,y,z). Also: w immer auf Eins setzen.

In der update-Funtkion wird die globale Variable rotate weiterbewegt. Den Rest des Programms zu lesen sollte euch keine Probleme mehr bereiten.

Selbständige Programmierung

  • Fügt eine weitere Lichtquelle hinzu. Ändert hierzu die Funktionen initLight und render.
  • Warum zeichnet sich die Struktur der Teekanne ab? Welche Näherung ist hierfür verantwortlich - Beleuchtungsmodell oder Gouraud-Shading?

zurück