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
gluPerspective Example Cpp Code
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
Lighting Example Code
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