CGExercises

CG Exercise #05

Computergraphik ├ťbungsblatt #05


OpenGL Tutorial: Modeling & Viewing



OpenGL & MVP



glVertex Cheat Sheet

Aufgabe 5.1: Pr├Ąliminarien

Wir beginnen wieder mit der OpenGL-Programmiervorlage (qt_template), d.h. Sie laden und zeichnen wie in der vorherigen ├ťbung Ihr Blender Objekt. Sie sollten dazu aber eine Kopie des vorherigen Programms bzw. Quelltextes in einem neuen Verzeichnis anlegen (siehe Cheat-Sheet). Das ist die empfohlene Vorgehensweise f├╝r die weiteren Aufgaben.

Alternativ k├Ânnen wir auch einfach einen W├╝rfel wie in der Hausaufgabe zeichnen. Oder wir starten mit dem Quelltext cube.cpp, der bereits einen vorgefertigten W├╝rfel enth├Ąlt.

Aufgabe 5.2: GLM (bzw. GLSLMath)

Definieren Sie mit der GLM (siehe Cheat Sheet → GLSLmath) den homogenen 3D Punkt bzw. Vertex $v = (0,0,-1,1)$ und geben Sie ihn auf der Konsole aus (mit dem << operator).

Den Vertex $v$ kann man auch etwas h├╝bscher mit glslmath::print(...) ausgeben.

Berechnen Sie die sog. aspect-ratio, d.h. das Seitenverh├Ąltnis des Framebuffers (wie z.B. 16:9 bei FHD) und geben Sie dieses Verh├Ąltnis ebenfalls aus.

Tipp: Breite und H├Âhe des Framebuffers → width() bzw. height()

Materialien:

Aufgabe 5.3: Trackball mit dem Framework

Das Framework hat die M├Âglichkeit, einen Trackball zur Verf├╝gung zu stellen, bei dem man mit der Maus das dargestellte Objekt “greifen” und rotieren kann.

Dazu stellt das Framework eine Rotations- bzw. Modellierungsmatrix zur Verf├╝gung, die von der lglGetManip() Funktion zur├╝ck geliefert wird. Diese speichern wir uns in einer Variable ab:

mat4 M_manip = lglGetManip();

Nun multiplizieren wir den Vertex $v$ erstmal mit dieser Modellierungsmatrix und geben beides fortlaufend mit glslmath::print(...) aus.

Bauen Sie den Trackball nun in Ihr Programm ein, so dass Ihr Objekt mit dem Trackball rotiert wird. Dazu muss einfach die Matrix als aktuelle Modellierungsmatrix $M_M$ auf die Grafikkarte geladen werden. Dazu verwendet man den Befehl lglLoadMatrix(...). Dieser Befehl setzt die aktuelle Modelview-Matrix $M_MV$, wobei wir annehmen, dass die View-Matrix $M_V$ momentan noch die Einheitsmatrix ist.

Tipp: Der Trackball skaliert auch (mit dem Mausrad).

Aufgabe 5.4: MVP Berechnen mit der GLM


Strahlenverlauf einer Spiegelreflexkamera

Nun berechnen wir die restlichen Teilmatrizen der MVP-Matrix selber mit der GLM.

Berechnen Sie dazu die Matrizen $M_M$, $M_V$ und $M_P$ mit den konkreten Werten aus der Hausaufgabe. Verwenden Sie die daf├╝r die Funktionen mat4::perspective f├╝r $M_P$, mat4::lookat f├╝r $M_V$ und eine Kombination von mat4::translate und mat4::rotate f├╝r $M_M$. Beachten Sie au├čerdem, dass das korrekte Seitenverh├Ąltnis f├╝r $M_P$ verwendet wird!

Berechnen Sie die Gesamtmatrizen $M_{MV}$ und $M_{MVP}$ durch Multiplikation der entsprechenden Teilmatrizen und geben Sie das Resultat f├╝r beide Matrizen aus. Vergleichen Sie mit der Hausaufgabe!

Verwenden Sie au├čerdem wieder die Rotationsmatrix des Trackballs als zus├Ątzliche Modellierungsmatrix. An welcher Stelle muss diese Matrix eingef├╝gt werden, damit sie sich auf die Objektkoordinaten auswirkt, also das Objekt rotiert wird?

Aufgabe 5.5: MVP anwenden

Verwenden Sie nun die obige MVP-Matrix zur perspektivischen Darstellung des Ihres Objeckts bzw. W├╝rfels. Dabei teilen wir die Gesamtmatrix so auf, so dass $M_P$ mit lglProjection(...) geladen wird und $M_{MV}$ mit lglModelView(...) geladen wird. Der Grund daf├╝r ist, dass sich erstens die Projektionsmatrix f├╝r einen Frame nicht ├Ąndert und zweitens $M_{MV}$ sp├Ąter noch f├╝r Beleuchtungsberechnungen ben├Âtigt wird.

Wahrscheinlich sehen Sie nun zuerst einmal gar nichts, weil der W├╝rfel au├čerhalb des sichtbaren Bereichs liegt. Wo war dieser nochmal?

Welche Parameter kann man anpassen, damit der W├╝rfel sichtbar wird? Es gibt prinzipiell drei verschiedene M├Âglichkeiten.

Aufgabe 5.6: Meshes und Koordinatensysteme


OpenGL Koordinatensysteme

Das Framework bietet wie Blender vorgefertigte Meshes bzw. VBOs f├╝r die Darstellung von Kugeln, Pyramiden, Tori etc. (siehe Cheat Sheet → VBOs). Diese sind alle auf eine Einheitsgr├Â├če normiert, so dass sie sich mit einer Skalierungsmatrix S einfach auf eine bestimmte Gr├Â├če skalieren lassen.

Insbesondere bietet das Framework das Mesh lglCoordSys als Koordinatensystemkreuz mit drei verschiedenfarbigen Achsen. Stellen Sie damit das lokale Koordinatensystem Ihres Objektes dar, d.h. das Koordinatensystem, welches mit dem Trackball rotiert wird.

Verwenden Sie dieses Mesh ebenfalls, um das System der Weltkoordinaten darzustellen. Berechnen Sie dazu zuerst eine weitere entsprechende MVP-Matrix f├╝r dieses zus├Ątzliche Koordinatensystem. Da die Projektions-Matrix gleich bleibt, reicht es aus, nur eine weitere entsprechende Model-View-Matrix zu berechnen und auf die Graphikkarte zu laden.

Gehen Sie also nach folgendem Muster vor:

// projection matrix for all objects
lglProjection(P);

// modelview matrix for the first object
mat4 MV1 = ...
lglModelView(MV1 * S1);
lglRender(obj1);

// modelview matrix for the second object
mat4 MV2 = ...
lglModelView(MV2 * S2);
lglRender(obj2);

// and so on
...

Welche Parameteranpassungen am Frustum m├╝ssen vorgenommen werden, damit das Weltkoordinatenkreuz sichtbar wird?

Aufgabe 5.7: Weitere Meshes (Empfohlen)

Bauen Sie jetzt weitere Objekte bzw. Meshes in Ihr Programm ein. Zeichnen Sie z.B. ein paar Kugeln, Tori, Teapots etc. und f├Ąrben Sie diese Objekte unterschiedlich ein (via lglColor()).

Aufgabe 5.8: Experimentieren (Optional)

Experimentieren Sie mit der Reihenfolge der Rotationen und Translationen und der Skalierung verschiedener Meshes.

Lassen Sie ein Objekt um sich selber rotieren und lassen Sie ein Objekt um den Weltursprung rotieren.

Experimentieren Sie z.B. auch mit der nicht-uniformen Skalierung eines W├╝rfels zu einem Quader.

Aufgabe 5.9: MVP im Shader

Erg├Ąnzen Sie den Code um einen Shader bzw. bauen Sie in Ihren Code einen Shader-Editor ein. Dazu ben├Âtigen Sie die folgenden zus├Ątzliche Zeilen:

Im Globalen Namensraum:

GLuint prog_id;
const char shader[] = "";

In der Methode initializeOpenGL():

prog_id = lglCompileGLSLProgram(shader);
create_lgl_Qt_ShaderEditor("shader", &prog_id);

In der Methode renderOpenGL():

lglUseProgram(prog_id, false);

Der Shader Editor startet mit dem denkbar einfachsten Programm, dem sog. Plain-Shader.

├ťberlegen Sie Sich: Aus welchen zwei Bestandteilen besteht dieser Plain-Shader? Welche Stufe der Graphik-Pipeline repr├Ąsentieren diese und welche Stufe befindet sich dazwischen? In welcher Stufe wird mit der MVP multipliziert und wie h├Ąufig? Wie h├Ąufig wird der andere Bestandteil verwendet? Dies ist zum Verst├Ąndnis der weiteren ├ťbungen relevant!

Aufgabe 5.10: Sonnensystem (Optional)


Ein nettes Spielzeug

Versuchen Sie, mit geigneten Rotationen und Translationen die Objekte wie ein Planetensystem (Sonne/Erde/Mond/Satellit/Hai) umeinander rotieren zu lassen. Fangen Sie mit der Sonne an, d.h. platzieren Sie eine gelbe Kugel im Ursprung der Weltkoordinaten.

Tipp: Bei vielen Objekten bzw. bei vielen lokalen Koordinatensystemen kommt man schnell durcheinander. Speichern Sie Sich daher die jeweils letzte funktionierende Programmversion als Sicherheitskopie ab.


Hausaufgaben bis zum sechsten Praktikum



Ein netter Ausziehtisch

1. Hierarchische Modellierung / Theorie:
Ein Tisch besteht aus einer Arbeitsplatte und vier Beinen. Die Beine sind getrennt von der Tischplatte modelliert. Dabei sei $M_P$ die Projektion, $M_V$ die View-Transformation, $M_T$ die Modellierungstranformation, welche die Position (und Orientierung) des Tisches in der Welt beschreibt, und $M_{B_x}$ die vier Modellierungstransformationen, die beschreiben, wie man von der Tischposition zur Position des x-ten Beines kommt.

  1. Zeichnen Sie den dazugeh├Ârigen Szenengraphen!
  2. Und beschreiben Sie nun, wie die ModellViewProjection-Matrizen aufgebaut sind, um die einzelnen 5 Elemente zu rendern!

2. Hierarchische Modellierung / Coding:
Wie w├╝rde diese Aufgabe in der renderOpenGL() Methode des Frameworks aussehen? Nehmen Sie an, Sie haben die Funktionen zeichneTischplatte() und zeichneTischbein() zur Verf├╝gung und die ben├Âtigten Matrizen stehen schon in den Variablen $M_P$, $M_V$, $M_T$, $M_{B_1}$, $M_{B_2}$, $M_{B_3}$ und $M_{B_4}$.

  • Tipp: Sie m├╝ssen nur jeweils f├╝r jeden Zeichenvorgang die ensprechende MV- und P-Matrix setzen (via lglProjection() und lglModelView()) und dann die jeweilige Zeichenroutine aufrufen. Da sich die Projektionsmatrix nicht ├Ąndert, muss diese nicht mehrfach gesetzt werden.

Options: