Draw your first Triangle in IOS OpenGL
OpenGL is low level computer graphic API, it powers most of graphic intensive games and softwares in the world.
Ok, it is enough talk!, let's get into action and show some stuff!
Generally, there are two types of coordinates systems in computer graphic.
1. Right Hand System
2. Left Hand System
OpenGL use Right Hand System
Direct3D use Left Hand System
We set z-axis=0 anyway since we only draw two dim triangle
1. Create an array with three vertices p=[x, y, z]
static const GLfloat triangle[] = {
0, 0, 0,
1, 0, 0,
0, 1, 0,
};
glVertexAttribPointer - define an array of generic vertex attribute data
glEnableVertexAttribArray - enable a generic vertex attribute array
glDiableVertexAttribArray - diable a generic vertex attribute array
glDrawArrays - render primitive from array data
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, triangle);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
$\alpha$ What is
GL_LINES
Given 2 or more vertices, draw segments from the $(n_0, n_1), (n_2, n_3), (n_4, n_5) \dots (n_{k-1}, n_k)$
$\beta$ What is
GL_LINE_STRIP
Adjacent vertices forms a line. $k - 1$ lines are drawn if $k$ vertices are given.
$(n_0, n_1), (n_1, n_2), (n_2, n_3) \dots (n_{k-1}, n_k)$ in $k$ vertices
$\gamma$ What is
GL_LINE_LOOP
Same as GL_LINE_STRIP except that first and last vertices also form a line.
Given $k$ vertices, lines are $(n_0, n_1), (n_1, n_2), (n_2, n_3) \dots (n_{k-2}, n_{k-1}), (n_{k-1}, n_0)$
There are three functions that you need to called to draw a triangle in OpenGL
When a triangle is drawn, there are three options can be used:
$\delta$ What is
GL_TRIANGLE_STRIP
Let assume we have four points p0=[0,0,0] p1=[1,0,1] p2=[1,1,0] p3=[0,1,0] in order.
First three points: {p0, p1, p2} forms a triangle, easy!
Second triangle is formed from $\{p_1, p_2, p_3\}$
So each consecutive pair of triangle shares two vertices
Each new vertex is added, a new triangle is formed
The numbers of triangle can be formed in n vertices is n-2
$\epsilon$ What is
GL_TRIANGLE_FAN
GL_TRIANGLE_FAN use the first vertex and last two vertices to form a triangle
The numbers of triangle can be formed in n vertices is n-2
$\zeta$ What is
GL_TRIANGLES
GL_TRIANGLES treats each triple of vertices as independent triangle.
If there are 3*n vertices, then there are n triangle can be drawn
Let draw some real stuff!
static const GLfloat triangle[] = {
0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
};
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, triangle);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
static const GLfloat triangle[] = {
0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
};
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, triangle);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
static const GLfloat triangle[] = {
0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
0, 2, 0,
1, 1.5, 0
};
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, triangle);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLES, 0, 6);
static const GLfloat triangle[] = {
0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
};
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, triangle);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_LINE_LOOP, 0, 4);
static const GLfloat triangle[] = {
0, 0, 0,
1, 0, 0,
0, 1, 0,
1, 1, 0,
};
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, triangle);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
static const GLfloat box[] = {
0, 0, 0,
1, 0, 0,
0, 1, 0,
1, 1, 0,
0, 1, -1,
1, 1, -1,
0, 0, -1,
1, 0, -1,
1, 1, 0,
1, 0, 0,
0, 0, -1,
0, 0, 0,
0, 1, -1,
0, 1, 0,
};
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, box);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 14);
Understand View Matrix in OpenGL
\begin{aligned}
\vec{f} \otimes \overrightarrow{up} &= \vec{s} \quad \mbox{Right-handed rule} \\
\vec{s} \otimes \vec{f} &= \vec{u} \quad \mbox{Right-handed rule} \\
&\mbox{mapping } \vec{s}, \vec{u}, \vec{f} \mbox{ to } x, y, z \\
&\vec{s} \rightarrow +x \\
&\vec{u} \rightarrow +y \\
&\vec{f} \rightarrow -z \\
\end{aligned}
View Matrix can be constructed with gluLookAt in OpenGL
Specify the eye poistion, lookat position, and up Vector.
In OpenGL Code:
1. Specify Mode
2. Create View Matrix with
gluLookAt Code Example
glMatrixMode(GL_MODELVIEW)
gluLookAt()
gluLookAt function
gluLookAt(
Eyex
Eyey
Eyez
Atx
Aty
Atz
Upx
Upy
Upz)
For example, if you want to change the eye position to $(0, 0, -2)$, two units away from the screen.
loadIdentity()
gluLookAt(0 0 -2, ...)
View Matrix is essential the orthonormal matrix for the camera or eye.
1. Given up direction $up=(0, 1, 0)$ and lookAt direction[e.g. from eye to center]
2. $\vec{s}$ can be computed with cross product
3. With $\vec{s}$ and lookAt direciton, $\vec{u}$ can be computed with cross product again
Once $\text{side} = \vec{s}, \text{up}=\vec{u}, \text{forward}=\vec{f}$ are known, the View Matrix can be constructed
We use the above example, and compute the View Matrix.
$\vec{up} = (0, 1, 0)$
the vector from eye to center is $\vec{f} = (0, 0, 0) - (0, 2, 3) = (0, -2, -3) $
$\vec{s} = \vec{f} \times \vec{up} = (0, -2, -3) \times (0, 1, 0)$ [Since $\vec{up} \text{ and } \vec{u}$ are same direction]
\begin{align*}
\vec{s} &= \vec{s} \times -\vec{f} = \vec{f} \times \vec{up} = \left| \begin{array}{ccc}
i & j & k \\
0 & -2 & -3 \\
0 & 1 & 0 \end{array} \right| \\
&=
\left| \begin{array}{cc}
-2 & -3 \\
1 & 0 \end{array} \right|i(-1)^{1+1}
+
\left| \begin{array}{cc}
0 & -3 \\
0 & 0 \end{array} \right|j(-1)^{1+2}
+
\left| \begin{array}{cc}
0 & -2 \\
0 & 1 \end{array} \right|k(-1)^{1+3} \quad \text{Cofactor Expension} \\
&= 3i + 0j + 0k = 3i
\end{align*}
Since we want to map $\vec{u}$ to
$
y = \left[ \begin{array}{c}
0 \\
1 \\
0 \\
\end{array}
\right]
$
and one axis to
$
z = \left[ \begin{array}{c}
0 \\
0 \\
1 \\
\end{array}
\right]
$
and $\vec{s}$ to
$
x = \left[ \begin{array}{c}
1 \\
0 \\
0 \\
\end{array}
\right]
$
$f$ point to the screen, and $+z$ is point outside of the screen in OpenGL.
$f$ changes to $-f$ so that $\vec{s}, \vec{u}, -\vec{f}$ map to $x, y, z$
From the picture above,
$\vec{s} = \vec{u} \times - \vec{f} = \vec{f} \times \vec{u}$
$\vec{u} = -\vec{f} \times \vec{s} = \vec{s} \times \vec{f}$
$\vec{s} = (3, 0, 0) \quad \vec{f} = (0, -2, -3)$
\begin{align*}
\vec{u} &= \vec{s} \times \vec{f}
=
\left| \begin{array}{ccc}
i & j & k \\
3 & 0 & 0 \\
0 & -2 & -3 \end{array} \right| \\
&=
\left| \begin{array}{cc}
0 & 0 \\
-2 & -3 \end{array} \right|i(-1)^{1+1}
+
\left| \begin{array}{cc}
3 & 0 \\
0 & -3 \end{array} \right|j(-1)^{1+2}
+
\left| \begin{array}{cc}
3 & 0 \\
0 & -2 \end{array} \right|k(-1)^{1+3} \quad \text{Cofactor Expension} \\
&= 0i + 9j - 6k
\end{align*}
$\vec{s} = (3, 0, 0) \quad \vec{u} = (0, 9, -6) \quad \vec{f} = (0, -2, -3) $
normalize three vectors
\begin{align*}
\begin{split}
\vec{s}_{n} &= \frac{(3, 0, 0)}{\sqrt{\|\vec{s}\|}} &= (1, 0, 0) \\
\vec{u}_{n} &= \frac{(0, 9, -6)}{\sqrt{\|\vec{u}\|}} &= (0, \frac{3}{\sqrt{13}}, \frac{-2}{\sqrt{13}}) \\
\vec{f}_{n} &= \frac{(0, -2, -3)}{\sqrt{\|\vec{f}\|}} &= (0, \frac{-2}{\sqrt{13}}, \frac{-3}{\sqrt{13}}) \\
\end{split}
\end{align*}
Since three $\vec{s}, \vec{u}, -\vec{f}$ are orthonormal vectors and they can forms a rotation matrix.
\begin{align*}
\begin{split}
\mathbf{R} &= \begin{bmatrix}
s_{n_x} & u_{n_x} & -f_{n_x} & 0 \\
s_{n_y} & u_{n_y} & -f_{n_y} & 0 \\
s_{n_z} & u_{n_z} & -f_{n_z} & 0 \\
0 & 0 & 0 & 1 \\
\end{bmatrix} \\
\mathbf{R} &= \begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & \frac{3}{\sqrt{13}} & \frac{2}{\sqrt{13}} & 0 \\
0 & \frac{-2}{\sqrt{13}} & \frac{3}{\sqrt{13}} & 0 \\
0 & 0 & 0 & 1 \\
\end{bmatrix}
\end{split}
\end{align*}
We also translate the camera from center to
\[
\vec{v} = \left[ \begin{array}{c}
0 \\
2 \\
3 \\
1 \\
\end{array} \right] \\
\]
The translation matrix is
\[
\mathbf{T} = \begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & 1 & 0 & 2 \\
0 & 0 & 1 & 3 \\
0 & 0 & 0 & 1 \\
\end{bmatrix}
\]
Let $\mathbf{M}_{v} = \mathbf{RT}$
if we want to conver the points from World Coordinate to View Coordinates, we can multiply the point with $\mathbf{M}_{v}^{-1}$
\begin{align*}
\begin{split}
p_{view} &= \mathbf{M}_{v}^{-1}
\left[ \begin{array}{c}
x \\
y \\
z \\
1 \\
\end{array} \right] \\
\mathbf{M}_{v}^{-1} &= (\mathbf{TR})^{-1} \\
\mathbf{M}_{v}^{-1} &= \mathbf{R}^{-1} \mathbf{T}^{-1} \\
\mathbf{M}_{v}^{-1} &= \mathbf{R}^{T} \mathbf{T}^{-1} \qquad \because \mathbf{R} \text{ is orthonormal matrix}\\
% invert of rotation matrix
\mathbf{R}^{T} &= \begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & \frac{3}{\sqrt{13}} & \frac{-2}{\sqrt{13}} & 0 \\
0 & \frac{2}{\sqrt{13}} & \frac{3}{\sqrt{13}} & 0 \\
0 & 0 & 0 & 1 \\
\end{bmatrix} \\
% invert of translation matrx
\mathbf{T}^{-1} &= \begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & 1 & 0 & -2 \\
0 & 0 & 1 & -3 \\
0 & 0 & 0 & 1 \\
\end{bmatrix} \\
% View matrix
\mathbf{M}_{v}^{-1} &= \begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & \frac{3}{\sqrt{13}} & \frac{-2}{\sqrt{13}} & 0 \\
0 & \frac{2}{\sqrt{13}} & \frac{3}{\sqrt{13}} & -\sqrt{13} \\
0 & 0 & 0 & 1 \\
\end{bmatrix} \\
\text{The View Matrix is } \mathbf{M}_{v}^{-1}
\end{split}
\end{align*}
If column vectors are orthonormal, then they can form a rotation matrix. Why? let prove it
let matrix $A$ and two columns are orthonormal.
\[
A= \begin{bmatrix}
a & b\\
c & d
\end{bmatrix}
\]
we have following
$ a b + c d = 0 \quad a^2 + c^2 = 1 \text{ and } b^2 + d^2 = 1$, given a vector
\begin{align*}
\begin{split}
\vec{v} &= \left [ \begin{array}{c}
x \\
y \\
\end{array}\right] \\
\vec{u} &=
\left[ \begin{array}{c}
ax + by \\
cx + dy
\end{array} \right]
= \begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
\times
\left[
\begin{array}{c}
x \\
y
\end{array}
\right] \\
\| \vec{u} \| &= (ax + by)^2 + (cx + dy)^2 \\
&= a^2 x^2 + b^2 y^2 + 2abxy + c^2 x^2 + d^2 y^2 + 2cdxy \\
&= (a^2 + c^2) x^2 + (b^2 + d^2) y^2 + 2(ab + cd)xy \\
&= x^2 + y^2 \because a b + c d = 0 \quad a^2 + c^2 = 1 \quad b^2 + d^2 = 1 \\
&\Rightarrow \| \vec{u} \| = \| \vec{v} \| \\
&\Rightarrow A \text{ is rotation matrix}
\end{split}
\end{align*}
Projection Matrix in OpenGL.
What is Projection Matrix in OpenGL.
Projection matrix maps
frustum to cube[NDC] in
Perspective projection
OpenGL Code:
1. Specify Mode
2. Create projection matrix
glMatrixMode(GL_PROJECTION);
gluLoadIdentity();
+ ———— + -> positive
↓ ↓
gluPerspective(FOV in degree, x/y, znear, zfar)
gluPerspective( /* field of view in degree */ 40.0,
/* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 10.0);
OpenGL default Camera position
I just learned the default Camera position is in (0, 0, 0). lookAt direction is negative z [ look at inside the screen ]
The default view volumn is \( 2 \times 2 \times 2 \) cube which is centered in \( (0, 0, 0) \)
In other words, the Camera is inside the view volumn cube
perspective NDC width x height = 2 x 2
perspective 90 zf (zf + 4.0)
\begin{align*}
\frac{1}{1} &= \tan{\alpha} \\
\alpha &= \arctan 1 = 90
\end{align*}
perspective NDC width x height = 4 x 4
perspective 126.934 zf (zf + 4.0)
\begin{align*}
\frac{2}{1} &= \tan{\alpha} \\
\alpha &= \arctan 2 = 126.934
\end{align*}
Haskell code perspective matrix
perspective in Haskell
is from
gluPerspective in C
perspective :: GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
perspective = gluPerspective
There are two type of Projection Matrix in OpenGL.
Perspective Projection and
Orthogonal Projection
We will derived Perspective Projection.
What does Perspective Projection do in OpenGL.
It projects points in eye/camera space to
Normal Device Coordinates[NDC]
\begin{align*}
\frac{x_p}{x_e} &= \frac{-n}{z_e} \Rightarrow x_p = \frac{nx_e}{-z_e} \\
\frac{y_p}{y_e} &= \frac{-n}{z_e} \Rightarrow y_p = \frac{ny_e}{-z_e} \\
\left[ \begin{array}{c}
x_p \\
y_p \\
z_p \\
w_p \\
\end{array} \right]
&= \begin{bmatrix}
n & 0 & 0 & 0 \\
0 & n & 0 & 0 \\
0 & 0 & A & B \\
0 & 0 & 0 & 1 \\
\end{bmatrix} \times
\left[ \begin{array}{c}
x_e \\
y_e \\
z_e \\
w_e \\
\end{array} \right] \\
%
z_p &= Az_e + B w_e \\
\frac{z_p}{-z_e} &= -A + \frac{B w_e}{-z_e} \\
&\text{Since we want to have something like following form} \\
z_p &= \frac{\sigma}{-z_e} \\
-z_p z_e &= \sigma \\
\sigma &= A z_e + B w_e \\
z_p &= \frac{A z_e + B w_e}{-z_e} \\
w_e &= 1 \\
-n &= -A + \frac{B}{n} \quad \because z_e = -n \\
-f &= -A + \frac{B}{f} \quad \because z_e = -f \\
-n + f &= \frac{B}{n} - \frac{B}{f} \\
B &= nf \\
A &= n + f \\
z_p &= \frac{(n+f) z_e + nf}{-z_e} \\
\left[ \begin{array}{c}
x_p \\
y_p \\
z_p \\
w_p \\
\end{array} \right]
&= \begin{bmatrix}
n & 0 & 0 & 0 \\
0 & n & 0 & 0 \\
0 & 0 & n+f & nf \\
0 & 0 & -1 & 0 \\
\end{bmatrix}
\left[ \begin{array}{c}
x_e \\
y_e \\
z_e \\
w_e \\
\end{array} \right] \\
&\text{Map A} [x_p, y_p, z_p, w_p] [x_n, y_n, z_n, w_n]
\end{align*}
We try to map the near plane to font plane of NDC, they are linear relationship
\begin{align*}
\begin{split}
x_n &= \frac{1-(-1)}{r-l} x_p + \alpha \\
x_n &= \frac{2}{r - l} x_p + \alpha \\
1 &= \frac{2}{r - l} r + \alpha \\
\alpha &= 1 - \frac{2}{r - l} r \\
\alpha &= -\frac{r + l}{r - l} \\
x_n &= \frac{2}{r - l} x_p - \frac{r + l}{r - l} \\
x_n &= \frac{2}{r - l} \frac{nx_e}{-z_e} - \frac{r + l}{r - l} \quad \because x_p = \frac{nx_e}{-z_e} \\
x_n &= \frac{ \frac{2n}{r-l}x_e + \frac{r + l}{r - l}z_e }{-z_e} \\ \\
\end{split}
\end{align*}
\begin{align*}
\begin{split}
y_n &= \frac{1-(-1)}{t - b} y_p + \beta \\
y_n &= \frac{2}{t - b} y_p + \beta \\
1 &= \frac{2}{t - b} r + \beta \\
\beta &= -\frac{t + b}{t - b} \\
y_n &= \frac{2}{t - b} y_p - \frac{t + b}{t - b} \\
y_n &= \frac{2}{t - b} \frac{ny_e}{-z_e} - \frac{t + b}{t - b} \quad \because y_p = \frac{ny_e}{-z_e} \\
y_n &= \frac{ \frac{2n}{t - b}y_e + \frac{t + b}{t - b}z_e }{-z_e} \\ \\
\end{split}
\end{align*}
\begin{align*}
\begin{split}
\text{Similary} \\
z_n &= \frac{1-(-1)}{n - f} z_p + \gamma \\
z_n &= \frac{2}{n - f} z_p + \gamma \\
z_n &= -1 \quad z_p = -n \\
-1 &= \frac{2}{n-f} - n + \gamma \\
\gamma &= \frac{n + f}{n - f} \\
z_n &= \frac{2}{n-f} z_p + \frac{n+f}{n-f} \quad \because z_p = \frac{(n+f) z_e + nf}{-z_e} \\
z_n &= \frac{2}{n-f} \frac{[(n+f) z_e + nf]}{-z_e} + \frac{n+f}{n-f} \\
z_n &= \frac{2}{n-f} \frac{[(n+f) z_e + nf]}{-z_e} + \frac{(n+f)(-z_e)}{(n-f)(-z_e)} \\
z_n &= \frac{(n+f)z_e + 2nf}{(n-f)(-z_e)} \\
z_n &= \frac{\frac{n+f}{n-f}z_e}{-z_e} + \frac{ \frac{2nf}{n-f}}{-z_e} \\
\end{split}
\end{align*}
Projection matrix maps Frustum to View Volume, or map Frustum to Cube
\begin{align*}
\begin{split}
\left[ \begin{array}{c}
x_n \\
y_n \\
z_n \\
w_n \\
\end{array} \right]
&= \begin{bmatrix}
\frac{2n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\
0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\
0 & 0 & \frac{n+f}{n-f} & \frac{2nf}{n-f} \\
0 & 0 & -1 & 0 \\
\end{bmatrix}
\left[ \begin{array}{c}
x_e \\
y_e \\
z_e \\
w_e \\
\end{array} \right] \\
\end{split}
\end{align*}
glFrustum(left, right, bottom, top, near, far)
glFrustum(l, r, b, t, n, f)
Orthogonal Matrix
gluOrtho2D[left, right, bottom, top];
Lighting in OpenGL
$\alpha$. Enable Lighting in OpenGL
glEnable(GL_LIGHTING);
$\beta$ Setup Light position in OpenGL
Use GL_LIGHT0 $\Rightarrow$ set light0
glEnable(GL_LIGHT0); // enable light0
$\gamma$ Setup Normal for Light in OpenGL
Compute the normal of vertex, OpenGL uses normal to compute the light
$\epsilon$ Setup material for Light in OpenGL
In OpenGL, there are something call "Material Properties"
GL_DIFFUSE - there are two characteristics: Diffuse reflection and Specular reflection.
- Diffuse reflection reflects light in different directions.
- Specular reflection reflects more light in mirror direction.
GL_AMBIENT - Ambient light is the light come from different direction.
GL_SPECULAR - The property sets the specular color. Note that the specular color for most surface is white, event if the surface is a different color.
GL_EMISSION - The emission property is how much the surface generates its own light
GL_SHININESS - This determine how much shiny a surface is. Values from 0 to 128
// enable light
glEnable(GL_LIGHTING)
// enable GL_LIGHT0
glEnable(GL_LIGHT0)
// setup normal
glNormal3d(0, 1, 0)
// setup material
glfloat cyan[] = {0.0f, 0.8f, 0.8f, 1.f}
glMaterialfv(GL_FRONT, GL_DIFFUSE, cyan);
OpenGL Code for lighting, color and material
Steps to use lighting in OpenGL
$\alpha \Rightarrow$ Enable lighting
$\beta \Rightarrow$ Choose light name such as GL_LIGHT0 or GL_LIGHT1 etc.
$\gamma \Rightarrow$ Set up Normal
$\delta \Rightarrow$ Set up Material
$\epsilon \Rightarrow$ Draw stuff
GLfloat cyan[] = {0.f, .8f, .8f, 1.f};
GLfloat light1_position[] = {1.0, 1.0, 1.0, 0.0};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light1_position);
glMaterialfv(GL_FRONT, GL_DIFFUSE, cyan);
glBegin(GL_QUADS);
glNormal3d(0, 1, 0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan);
glVertex3f(-1, 0, 1);
glVertex3f(1, 0, 1);
glVertex3f(1, 0, -1);
glVertex3f(-1, 0, -1);
glEnd();
Transparent or Blender
1. Enable Blender in OpenGL
2. Use glColor4f instead of glColor3f
3. set each vertex for different colors
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0, 0, 1, 0.5) // alpha = 0.5
GLSL and Vertex and Fragment Shader
Reference
What is GLSL programming language?
GLSL is C like programming language. It run in GPU.
Data type: Like C it has int, float, uint, bool, and vectors and matrices
NOTE: C does not have basic type vectors and matrices
What is Vertex Shader?
Handle Vertex attributes such as location.
What is Fragment Shader?
Fragment Shader is also called Pixel Shader.
A chunk of pixels is called fragment
Process attributes of pixels such as lightness, brightness and color. Not sure..
6. What is Geometry Shader?
Geometry shader is between Vertex shader and Fragment shader.
Vertexes forms point, line and triangle
Vector: a vector is 1, 2, 3 and 4 components container for any basic types just mentioned.
They can take the following form:
vecn ⇒ default vector of n floats
bvecn ⇒ a vector of n booleans
ivecn ⇒ a vector of n integers
uvecn ⇒ a vector of n unsigned integers
dvecn ⇒ a vector of n double components
4. Access vector components
vec2 v2 = vec2(0.1, 0.4)
v2.x ⇒ 0.1
v2.y ⇒ 0.4
vec4 v4 = vec4(v2, 0.3, 0.5)
vec4 v41 = vec4(v2.xy, 0.3, 0.5)
vec4 v42 = v4.xyzw + v4.xxxx
How to pass OpenGL variable to Shader variable
In Vertex Shader file:
uniform mat4 mymat;
In OpenGL code:
// get the mymat id from shader
GLunit mymat_id = glGetUniformLocation(shaderHandle, "mymat");
// Create a matrix in OpenGL, each row as column
float arr[] = {
1.0, 0.0, 0.0, 0.0, // column 1
0.0, 1.0, 0.0, 0.0, // column 2
0.0, 0.0, 1.0, 0.0, // column 3
0.1, 0.2, 0.0, 1.0 // column 3
};
// arr becomes the following matrix
// Assign the OpenGL arr to shader mymat
glUniformMatrix4fv(mymat_id, 1, GL_FALSE, arr);
\[
M = \begin{pmatrix}
1.0 & 0.0 & 0.0 & 1.0 \\
0.0 & 1.0 & 0.0 & 2.0 \\
0.0 & 0.0 & 1.0 & 0.0 \\
0.0 & 0.0 & 0.0 & 1.0 \\
\end{pmatrix}
\]
OpenGL default projection, default coordinate system X and Y
If you do not set up the perspective(gluPerspective), frustum(glFrustrum) matrix or orthogonal matrix(glOrtho), what is the default matrix for in OpenGL?
The default one is orthogonal matrix.
OpenGL Coordinate system is [-x, +x] = [-1, 1], [-y, y] = [-1, 1]
How to map screen Coordinate System to OpenGL Coordinate System
Problem: How to check whether a mouse pointer is inside a triangle?
Problem: Mouse pointer is the screen coordinate system (800 pixel x 800 pixel)
Triangle is in [-x, +x] = [-1, +1], [-y, +y] = [-1, +1]
Screen Coordinate System ⇒ top left (0, 0), bottom right (800, 800)
OpenGL Coordinate System is:
[-x, +x] = [-1, +1]
[-y, +y] = [-1, +1]
(0, 0) is at the center of screen
(+1, 0) is the right most point on X-axis
(-1, 0) is the left most point on X-axis
(0, +1) is the top point on the Y-axis
(0, -1) is the bottom point on the Y-axis
How to map mouse pointer in screen coordinate to OpenGL coordinate
Width = 800 // screen width
Height = 800 // screen height
w = Width/2
h = Height/2
x = x0*w // x0 OpenGL Coordinate -1 <= x0 <= 1
y = y0*h // y0 OpenGL Coordinate -1 <= y0 <= 1
xx = w + x0*w
yy = h + y0*w
// (xx, yy) is the screen Coordinate in pixel