Grafikprogrammierung
Kameras: Perspektivische Projektion
Thorsten Thormählen
15. November 2024
Teil 6, Kapitel 1
Thorsten Thormählen
15. November 2024
Teil 6, Kapitel 1
Dies ist die Druck-Ansicht.
Weiterschalten der Folien durch die → Taste oder
durch das Klicken auf den rechten Folienrand.
Das Weiterschalten der Folien kann ebenfalls durch das Klicken auf den rechten bzw. linken Folienrand erfolgen.
| Typ | Schriftart | Beispiele |
|---|---|---|
| Variablen (Skalare) | kursiv | $a, b, x, y$ |
| Funktionen | aufrecht | $\mathrm{f}, \mathrm{g}(x), \mathrm{max}(x)$ |
| Vektoren | fett, Elemente zeilenweise | $\mathbf{a}, \mathbf{b}= \begin{pmatrix}x\\y\end{pmatrix} = (x, y)^\top,$ $\mathbf{B}=(x, y, z)^\top$ |
| Matrizen | Schreibmaschine | $\mathtt{A}, \mathtt{B}= \begin{bmatrix}a & b\\c & d\end{bmatrix}$ |
| Mengen | kalligrafisch | $\mathcal{A}, B=\{a, b\}, b \in \mathcal{B}$ |
| Zahlenbereiche, Koordinatenräume | doppelt gestrichen | $\mathbb{N}, \mathbb{Z}, \mathbb{R}^2, \mathbb{R}^3$ |
$\tilde{\mathbf{P}}= \left( f \frac{p_x}{p_z}, f \frac{p_y}{p_z}, f \right)^\top$
$\frac{\tilde{p}_x}{f} = \frac{p_x}{p_z}$ und $\frac{\tilde{p}_y}{f} = \frac{p_y}{p_z}$
$\tilde{\mathbf{P}}= \begin{pmatrix} \tilde{p}_x \\ \tilde{p}_y \\ \tilde{p}_z \end{pmatrix}= \begin{pmatrix} f \frac{p_x}{p_z}\\ f \frac{p_y}{p_z}\\ f \end{pmatrix} \in \mathbb{R}^3 \longmapsto \underline{\tilde{\mathbf{P}}}= \begin{pmatrix}f \, p_x \\f \, p_y \\ f \, p_z\\ p_z\end{pmatrix} \in \mathbb{H}^3$
$\begin{align}\underline{\tilde{\mathbf{P}}} & = \begin{pmatrix}f \, p_x \\f \, p_y \\ f \, p_z\\ p_z\end{pmatrix} = \underbrace{\begin{bmatrix} f & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & f & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}}_{\mathtt{A}} \begin{pmatrix}p_x \\p_y \\ p_z\\ 1\end{pmatrix}\\ \underline{\tilde{\mathbf{P}}} &=\mathtt{A}\, \underline{\mathbf{P}} \end{align}$
$\begin{align}\underline{\tilde{\mathbf{P}}} & = \begin{pmatrix}f \, p_x \\f \, p_y \\ f \, p_z\\ -p_z\end{pmatrix} = \underbrace{\begin{bmatrix} f & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & f & 0 \\ 0 & 0 & -1 & 0 \end{bmatrix}}_{\mathtt{A}} \begin{pmatrix}p_x \\p_y \\ p_z\\ 1\end{pmatrix}\\ \underline{\tilde{\mathbf{P}}} &=\mathtt{A}\, \underline{\mathbf{P}} \end{align}$
$p_z=-z_n \quad \mapsto \quad \tilde{p}_z=-1$
und für Punkte auf der Far-Ebene:
$p_z=-z_f \quad \mapsto \quad \tilde{p}_z=1$
$\underline{\tilde{\mathbf{P}}} = \begin{pmatrix}f \, p_x \\f \, p_y \\ \alpha \, p_z + \beta \\ -p_z\end{pmatrix} = \begin{bmatrix} f & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & \alpha & \beta \\ 0 & 0 & -1 & 0 \end{bmatrix} \begin{pmatrix}p_x \\p_y \\ p_z\\ 1\end{pmatrix} \in \mathbb{H}^3$
$\tilde{\mathbf{P}}=(\tilde{p}_x,\tilde{p}_y,\tilde{p}_z)^\top = \left( f \frac{p_x}{-p_z}, f \frac{p_y}{-p_z}, -\alpha \, + \frac{\beta}{-p_z} \right)^\top \in \mathbb{R}^3$
$\begin{align} \alpha &= \frac{z_f+z_n}{z_n-z_f}\\ \beta & = \frac{2 z_f \, z_n}{z_n-z_f}\end{align}$
$\begin{align} \underline{\tilde{\mathbf{P}}} & = \underbrace{\begin{bmatrix} f & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & \frac{z_f+z_n}{z_n-z_f} & \frac{2 z_f \, z_n}{z_n-z_f} \\ 0 & 0 & -1 & 0 \end{bmatrix}}_{\mathtt{A}} \begin{pmatrix}p_x \\p_y \\ p_z\\ 1\end{pmatrix}\\ \underline{\tilde{\mathbf{P}}} &=\mathtt{A}\, \underline{\mathbf{P}} \end{align}$
$\frac{f}{1} = \frac{\cos( 0.5 \, \Theta)}{\sin( 0.5 \, \Theta)} \Leftrightarrow f = \mathrm{cotan}( 0.5 \, \Theta)$
GL_PROJECTION Matrix verantwortlich.glMatrixMode(GL_PROJECTION);
glLoadIdentity, glLoadMatrix, glMultMatrix, glRotate, glScale, glTranslate, glPushMatrix, glPopMatrix, gluPerspective werden dann auf der GL_PROJECTION Matrix ausgeführt.
GL_PROJECTION Matrix beeinflusst die Transformation der Objekte nur dann,
wenn diese gezeichnet werden (OpenGL als Zustandsmaschine)Erzeugen einer perspektivischen Projektionsmatrix in OpenGL:
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(fovy, aspect, near, far);
$ \mathtt{A} = \begin{bmatrix} \frac{f}{\mathrm{aspect}} & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & \frac{\mathrm{far}+\mathrm{near}}{\mathrm{near}-\mathrm{far}} & \frac{2 \ast \mathrm{far} \ast \mathrm{near}}{\mathrm{near}-\mathrm{far}} \\ 0 & 0 & -1 & 0 \end{bmatrix}$
mit $f = \mathrm{cotan}( 0.5 \ast \mathrm{fovy})$
und $\mathrm{aspect}= \mathrm{w} / \mathrm{h}$
$\tilde{p}_y = f \frac{p_y}{-p_z}$
class Renderer {
public:
float t; //time
const float d0; // initial distance
public:
Renderer() : t(1.0), d0(3.0), width(0), height(0) {}
public:
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (dollyZoomFovy(),
(float)width/(float)height,
0.1, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// translate camera by 3 units
glTranslatef(0.0f, 0.0f, -t*d0);
// draw a cube in the local coordinate system
drawCube();
// draw random lines
drawRandomLines();
}
void init() {
glEnable(GL_DEPTH_TEST);
// create random values between -1.0 and 1.0
for(unsigned r=0; r < 1000; r++) {
int r = rand();
randVals.push_back(2.0*float(r)/float(RAND_MAX)-1.0f);
}
}
void resize(int w, int h) {
// ignore this for now
glViewport(0, 0, w, h);
width = w;
height = h;
}
float dollyZoomFovy() {
float fovyInit = 60.0f; // initial field of view
float theta = fovyInit / 180.0f * M_PI; // degree to rad
float f = 1.0f / tan(theta/2.0f);
float fNew = f * (d0*t-1) / (d0-1);
float thetaNew = atan(1.0f / fNew) * 2.0f;
float val = 180.0 * thetaNew / M_PI; //rad to degree
return val;
}
private:
int width;
int height;
std::vector<float> randVals;
private:
void drawCube() {
glColor3f(1.0f, 1.0f, 1.0f);
glLineWidth(3.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glEnd();
glLineWidth(1.0);
}
void drawRandomLines() {
if(randVals.size() % 5) return;
unsigned i = 0;
while(i < randVals.size()) {
glColor3f(fabs(randVals[i++]),
fabs(randVals[i++]),
fabs(randVals[i++]));
float x = randVals[i++];
float y = randVals[i++];
glBegin(GL_LINES);
glVertex3f(x, y, -1.0f);
glVertex3f(x, y, 1.0f);
glEnd();
}
}
};
$\underline{\tilde{\mathbf{P}}} = \mathtt{A} \, \mathtt{T}_{\mathrm{\small cam}}^{-1} \, \mathtt{T}_{\mathrm{\small obj}} \, \underline{\mathbf{P}}$
Abbildungsvorschrift für homogene Punkte:
$\underline{\tilde{\mathbf{P}}} = \mathtt{A} \, \mathtt{T}_{\mathrm{\small cam}}^{-1} \, \mathtt{T}_{\mathrm{\small obj}} \, \underline{\mathbf{P}}$
Dabei beschreibt die $4 \times 4$ Matrix
$ \mathtt{T}_{\mathrm{\small obj}} = \begin{bmatrix}\tilde{\mathbf{b}}_x & \tilde{\mathbf{b}}_y & \tilde{\mathbf{b}}_z & \mathbf{C}_b\\0 & 0 & 0 & 1\end{bmatrix}$
$\begin{align} \mathtt{T}_{\mathrm{\small cam}} & = \begin{bmatrix}\tilde{\mathbf{a}}_x & \tilde{\mathbf{a}}_y & \tilde{\mathbf{a}}_z & \mathbf{C}_a\\0 & 0 & 0 & 1\end{bmatrix} \\ & = \begin{bmatrix} \mathtt{R}_a & \mathbf{C}_a\\ \mathbf{0}^\top & 1\end{bmatrix} \end{align}$
$\mathtt{T}_{\mathrm{\small cam}}^{-1} = \begin{bmatrix} \mathtt{R}_a & \mathbf{C}_a\\ \mathbf{0}^\top & 1\end{bmatrix}^{-1} = \begin{bmatrix} \mathtt{R}_a^{\top} & -\mathtt{R}_a^{\top} \mathbf{C}_a\\ \mathbf{0}^\top & 1\end{bmatrix} $
Abbildungsvorschrift für homogene Punkte:
$\underline{\tilde{\mathbf{P}}} = \mathtt{A} \, \underbrace{\mathtt{T}_{\mathrm{\small cam}}^{-1} \, \mathtt{T}_{\mathrm{\small obj}}}_{\mathtt{T}_{\mathrm{\small modelview}}} \, \underline{\mathbf{P}}$
GL_MODELVIEW Matrix zusammengefasstGL_MODELVIEW Matrix beschreibt somit direkt die Transformation vom jeweiligen lokalen Koordinatensystem ins KamerakoordinatensystemGL_PROJECTION Matrix $\mathtt{A}$ beschreibt die Abbildung vom Kamerakoordinatensystem in die BildebenegluLookAt(eyex, eyey, eyez, refx, refy, refz, upx, upy, upz);
$\begin{align} \mathbf{d} & = \mathbf{C}_{\mathrm{\small eye}} - \mathbf{P}_{\mathrm{\small ref}}\\ \tilde{\mathbf{a}}_z &= \frac{\mathbf{d}}{|\mathbf{d}|}, \mathbf{v}' = \frac{\mathbf{v}_{\mathrm{\small up}}}{|\mathbf{v}_{\mathrm{\small up}}|} \\ \tilde{\mathbf{a}}_x &= \mathbf{v}'\times \tilde{\mathbf{a}}_z \\ \tilde{\mathbf{a}}_y &= \tilde{\mathbf{a}}_z \times \tilde{\mathbf{a}}_x\\ \mathtt{R}_{a} & = \begin{bmatrix}\tilde{\mathbf{a}}_x & \tilde{\mathbf{a}}_y & \tilde{\mathbf{a}}_z \end{bmatrix} \\ \end{align}$
class Renderer {
...
void resize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0, (float)w/(float)h, 2.0, 20.0);
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera orbits in the y=10 plane
// and looks at origin
double rad = M_PI / 180.0f * t;
gluLookAt(10.0*cos(rad), 10.0 , 10.0*sin(rad), // eye
0.0, 0.0, 0.0, // look at
0.0, 1.0, 0.0); // up
//draw cube at origin
drawCube();
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(2.5f, 0.0f, 0.0f );
glScalef(0.5f, 0.5f, 0.5f);
//draw transformed cube
drawCube();
}
...
}
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective (...); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(...); glRotatef(...); glTranslatef(...); glScalef(...);
$\mathtt{T}_{\mathrm{\small projection}}= \mathtt{I}$
$\mathtt{T}_{\mathrm{\small projection}}= \mathtt{I} \, \mathtt{A}$
$\mathtt{T}_{\mathrm{\small modelview}}= \mathtt{I}$
$\mathtt{T}_{\mathrm{\small modelview}}= \mathtt{I}\,\mathtt{T}_{\mathrm{\small cam}}^{-1}$
$\mathtt{T}_{\mathrm{\small modelview}}= \mathtt{I}\,\mathtt{T}_{\mathrm{\small cam}}^{-1} \,\mathtt{T}_r$
$\mathtt{T}_{\mathrm{\small modelview}}= \mathtt{I}\,\mathtt{T}_{\mathrm{\small cam}}^{-1} \,\mathtt{T}_r\,\mathtt{T}_t$
$\mathtt{T}_{\mathrm{\small modelview}}= \mathtt{I}\,\mathtt{T}_{\mathrm{\small cam}}^{-1} \,\mathtt{T}_r\,\mathtt{T}_t\,\mathtt{T}_s $
$\begin{align} \underline{\tilde{\mathbf{P}}} &= \mathtt{T}_{\mathrm{\small projection}} \mathtt{T}_{\mathrm{\small modelview}} \, \underline{\mathbf{P}}\\ &= \mathtt{A} \, \mathtt{T}_{\mathrm{\small cam}}^{-1} \,\mathtt{T}_r\,\mathtt{T}_t\,\mathtt{T}_s \,\underline{\mathbf{P}} \end{align}$
class Renderer {
public:
float t;
public:
Renderer() : t(0.0) {}
public:
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera orbits in the y=10 plane
// and looks at origin
double rad = M_PI / 180.0f * t;
gluLookAt(10.0*cos(rad), 10.0 , 10.0*sin(rad), // eye
0.0, 0.0, 0.0, // look at
0.0, 1.0, 0.0); // up
//draw model at origin
drawCubeHierarchy(0, 4);
}
void init() {
glEnable(GL_DEPTH_TEST);
}
void resize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0, (float)w/(float)h, 0.1, 50.0);
}
private:
void drawCube() {
...
}
void drawCubeHierarchy(int depth, int neighbors) {
drawCube(); // draw parent
depth +=1;
if (depth < 6){
for (int n = 0; n < neighbors; n++){
glPushMatrix();
glRotatef(n*90.0f-90.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(2.5f, 0.0f, 0.0f );
glScalef(0.5f, 0.5f, 0.5f);
drawCubeHierarchy(depth, 3); // draw children
glPopMatrix();
}
}
}
};
Bei Verwendung der Fixed-Function-Pipeline werden folgende Transformationen auf die Vertex Daten angewendet
$\underline{\mathbf{P}} = \begin{pmatrix}p_x\\p_y\\p_z\\p_w\end{pmatrix} \in \mathbb{H}^3 \quad \longmapsto \quad \mathbf{P}= \begin{pmatrix}\frac{p_x}{p_w}\\\frac{p_y}{p_w}\\\frac{p_z}{p_w} \end{pmatrix} \in \mathbb{R}^3 $
$-p_w < p_x < p_w \quad \longmapsto \quad -1 < \frac{p_x}{p_w} < 1$
glViewport(int ix, int iy, int width, int height)
ix und iy die linke untere Ecke des Viewports und width und height die Größe an (jeweils in der Einheit Pixel)
class Renderer {
public:
float t;
public:
Renderer() : t(0.0), width(0), height(0) {}
public:
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// top right viewport (look from front)
glViewport(width/2, height/2, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawFrame();
// set camera (look from positive x-direction)
gluLookAt(10.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 1.0);
// draw scene
drawSceneGrid();
drawRotatingPyramid();
// bottom left viewport (look from left)
glViewport(0, 0, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawFrame();
// set camera (look from negative y-direction)
gluLookAt(0.0, -10.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 1.0);
// draw scene
drawSceneGrid();
drawRotatingPyramid();
// top left viewport (look from top)
glViewport(0, height/2, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawFrame();
// set camera (look from positive z-direction)
gluLookAt(0.0, 0.0, 10.0,
0.0, 0.0, 0.0,
-1.0, 0.0, 0.0);
// draw scene
drawSceneGrid();
drawRotatingPyramid();
// bottom right viewport (perspective)
glViewport(width/2, 0, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawFrame();
// set camera
gluLookAt(8.0, -2.0, 5.0,
0.0, 0.0, 0.0,
0.0, 0.0, 1.0);
// draw scene
drawSceneGrid();
drawRotatingPyramid();
}
void init() {
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
}
void resize(int w, int h) {
width = w;
height = h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0,
(float)width/(float)height,
0.1, 50.0);
}
private:
int width;
int height;
private:
void drawFrame() {
glLineWidth(2.0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glLineWidth(1.0);
}
void drawSceneGrid() {
glColor3f(0.3f, 0.3f, 0.3f);
glBegin(GL_LINES);
for(unsigned i=0; i<=10; i++) {
glVertex3f(-5.0f+i, -5.0f, 0.0f);
glVertex3f(-5.0f+i, 5.0f, 0.0f);
glVertex3f(-5.0f, -5.0f+i, 0.0f);
glVertex3f( 5.0f, -5.0f+i, 0.0f);
}
glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
drawCoordinateAxisZ();
glColor3f(0.0f, 1.0f, 0.0f);
drawCoordinateAxisY();
glColor3f(1.0f, 0.0f, 0.0f);
drawCoordinateAxisX();
}
void drawCoordinateAxisZ() {
glLineWidth(2.0);
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f); // z-axis
glVertex3f(0.0f, 0.0f, 2.0f);
glEnd();
glLineWidth(1.0);
// z-axis tip
glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 0.0f, 2.0f);
glVertex3f(-0.05f, 0.05f, 1.9f);
glVertex3f( 0.05f, 0.05f, 1.9f);
glVertex3f( 0.0f, 0.0f, 2.0f);
glVertex3f( 0.05f, -0.05f, 1.9f);
glVertex3f(-0.05f, -0.05f, 1.9f);
glVertex3f( 0.0f, 0.0f, 2.0f);
glVertex3f( 0.05f, 0.05f, 1.9f);
glVertex3f( 0.05f, -0.05f, 1.9f);
glVertex3f( 0.0f, 0.0f, 2.0f);
glVertex3f(-0.05f, -0.05f, 1.9f);
glVertex3f(-0.05f, 0.05f, 1.9f);
glEnd();
glBegin(GL_POLYGON);
glVertex3f( 0.05f, -0.05f, 1.9f);
glVertex3f( 0.05f, 0.05f, 1.9f);
glVertex3f(-0.05f, 0.05f, 1.9f);
glVertex3f(-0.05f, -0.05f, 1.9f);
glEnd();
}
void drawCoordinateAxisX() {
glPushMatrix();
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
drawCoordinateAxisZ();
glPopMatrix();
}
void drawCoordinateAxisY() {
glPushMatrix();
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
drawCoordinateAxisZ();
glPopMatrix();
}
void drawRotatingPyramid() {
glRotatef(t, 0.0f, 0.0f, 1.0f);
drawPyramid();
}
void drawPyramid() {
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 0.0f, 1.5f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glEnd();
glColor3f(0.0,1.0,0.0);
glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 0.0f, 1.5f);
glVertex3f( 1.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();
glColor3f(0.0,0.0,1.0);
glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 0.0f, 1.5f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 0.0f);
glEnd();
glColor3f(1.0,1.0,0.0);
glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 0.0f, 1.5f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glColor3f(0.0,1.0,1.0);
glBegin(GL_POLYGON);
glVertex3f( 1.0f, -1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();
}
};
glEnable(GL_DEPTH_TEST)
und glClear(GL_DEPTH_BUFFER_BIT) verwendet, ohne dass deren Funktion
diskutiert wurde.glEnable(GL_DEPTH_TEST) dient dazu, den Tiefentest in OpenGL zu aktivierten
glClear(GL_DEPTH_BUFFER_BIT)FOR each primitiv
FOR each pixel of primitive at position (x,y) with colour c and depth d
IF d < depthbuffer(x,y)
framebuffer(x,y) = c
depthbuffer(x,y) = d
END IF
END FOR
END FOR
class Renderer {
public:
float t;
int width, height;
double nearPlane, farPlane;
int depthBits;
public:
Renderer() : t(0.0), nearPlane(2.0), farPlane(20.0) {}
public:
void resize(int w, int h) {
glViewport(0, 0, w, h);
width = w;
height = h;
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0, (float)width/(float)height, nearPlane, farPlane);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera orbits in the y=10 plane
// and looks at origin
double rad = M_PI / 180.0f * t;
gluLookAt(10.0*cos(rad), 10.0 , 10.0*sin(rad), // eye
0.0, 0.0, 0.0, // look at
0.0, 1.0, 0.0); // up
//draw cube at origin
drawCube();
}
void init() {
glEnable(GL_DEPTH_TEST);
glGetIntegerv (GL_DEPTH_BITS, &depthBits);
}
private:
void drawCube() {
...
}
};
Anregungen oder Verbesserungsvorschläge können auch gerne per E-mail an mich gesendet werden: Kontakt