- We can move the camera by translatiing it in the positive z direction
- T = [[1 0 0 0][0 1 0 0][0 0 1 -d][0 0 0 1]] where d is the distance from the camera
- we're actually moving the whole universe and leaving the camera ? i thin kthats what he meant
- How do we do all this in openGL?
→ we can apply transformations to the camera LENS and the position
- Two matrix modes
→ model-view: objects and camera positions
→ projection: camera lens, viewing volume
- We are going to exclusively look at model view today and talk about moving stuff around

Model View Matrix
- 4x4 homogenous matrix affects vertex positions inteh scene
- part of the openGL state
- applied to all vertices at the time they are being drawn
- initially the transformation is the identity matrix, i.e. it has no effect
- model view matrix, C (current) can be altered by loading a new transofmraiton, or by multiplying the existing matrix. i.e. augmenting the existing transformation wiht sometihng else
- Loading a completely newmatrix:
→ Load an identiy marix: C ← I
→ load translation matrix: C ← T
→ C ← R, S (scaling or rotating)
→ C ← arbitrary matrix (e.g. do the matrix calcs urself and load them in)
- before a transformation is made, the current matrix may need to be set to the identiy matrix C = I with
→ glLoadIdentity()
- followed by glRotatef(args), glScalef(args) whatever.
- glLoadMatrix(A) loads arbitrary matrix (~too exotic~)
- When do you not want to load the idenity matrix?
→ if your're for example making a moon that goes around a planet, you want the transformations to start from where the planet already is.
→ also if youre applying multiple transformations at once
-


- tripel star warning
- rememner that we are dealign with matrixes under hte hood
- remember the order of operations of applying transformation matrices
- C = SRTp = S(R(Tp)))
-
glScalef(
glRotatef
glTranslatef
GlVERTEx...
TRANSLATE gets applied first because its closest to the points
then rotate,
then scale



2023/10/23 - 11:42 part 2

- still in model view matrix mode
- last transformation specified is the first to be applied!
- ** closer transofmeaitions to the vertices are applied first!!




void main(int argc, char** argv){
    //same as last example

}
GLFloat vertices[][3] = // same as last time


void polygon( //draws a side
//needs to be called 6 times
void colorCube(){
    polygon()
    polygon()
    polygon()
    ...
}//draws the cube

GLFloat theta = 0.0;
GLFloat axis = 0//x = 0; y = 1; z = 2

void myIdle(){
    theta += 2.0;
    glutPostRedisplay();
}

void myMouse(int button, int state, int x, int y){
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
        axis = 0
    }
    //same for y and z (middle and right mouse buttons)
}

void myDisplay(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity(); //clear out previous frame's transformation
    switch(axis){
        case 0:
            glRotatef(theta, 1,0,0);
            break;
        case 1:
            glRotatef(theta,0,1,0);
            break;
        case 2:
            glRotatef(theta,0,0,1);
            break;
    }
    
    colorCube();
    
    glutSwapBuffers();
}



- recall, by default the camera is pointed at the origin
- it points down the negative Z axis, and has an up vector of (0,1,0)
- if we are simply moving the camera backwards, we can just move it in the z direction.
- but we want to be able to point it wherever we want
- use gluLookAt
→ ititialize the model view matrix
→ pick camera location
→ pick viewing location
→ pick up direction
→ gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz)
⇒ eye = position of the center of the camera
⇒ at = the thing looking at
⇒ up = which direction is up for the camera
⇒ ex:
• glMatrixMode(GL_MODEL_VIEW)
• glLoadIdentity();
• gluLoookAt(1,0,0,0,0,0,0,1,0) //point camera a unit vector along x axis, towards the origin, with an up vector of the y axis



// start with a program that draws a 3d cube centered at the origin with the sides aligned with the axes.
//move the camera between (-1,0,3) and (1,0,3)

void main(){
    //same
}

void initializeGL(){
    glEnable(GL_DEPTH_TEST)
    //projection mode
    glMatrixMode(GL_PROJECTION)
    //rest is same i guess
}

//same functions to draw the face of the cube and stuff

GLFloat cameraPosition[0,0,3];
GLFloat interpDifference = 0.01;
myIdle(){
    if(cameraPosition[0] <= -3 || if cameraPosition[0] >= 3){
        interpDifferent = -interpDifference;
    }
    cameraPosition[0] += interpDifference;
}

void myDisplay(){
    glClear(<color> | <depth>)
    glLoadIdentity();
    gluLookAt(cameraPosition[0],cameraPosition[1],cameraPosition[2],
                000//look at origin
                0,1,0// positive y up for camera
    colorCube();
    glutSwapBuffers();
}

//look at before the transformations
// up does not have to be perpendicular but it can't be colinear


Matrix stacks
- in many situations we want to save transfoemation matrices for use later
- openGL maintains a stack for each type of matrix
- can access the current matrix as set by glMatrixMode
→ glPushMatrix() // push matrix onto stack
→ glPopMatrix() // pop matrix from stack
- lets say we've done a scale of an object, and rotated it, or whatever transformation
- we have 4x4 matrix of numbers thaat contain those transformations
- we can push that matrix onto a stack, create another transformation and push that onto the stack.. and so on
- it's almost like saving them for later.. this is the matrix i needed to get the object in the right orientation and scale, and i want to come back to it later.
- the transformations between a push and a pop have no effect elsewhere
- the easiest way to handle this is scoping the variables. we can use a push and a pop to do some transformations that basically “dont exist” outside the push and pop.
-
glPushMatrix();
    //do transformations
    //draw something
    //transformations in here are only in effect within the push and pop because after we pop, the original state is restored
glPopMatrix();
    //"i only want this transformation to be in effect between these two spots"


Example:
animating several transformation
- rotate the bully cube but protect the little cube from the bully's transformations
- even tho we draw the little one after the big one the transformations are not gonna affect it
- if we turn off the push and the pop the little cube orbits around the big cube because its translations are still in effect when we apply the tranformations that arte supposed to apply to the little cube
-
void main()//same
myIdle and myMouse // same as previous

void myDisplay(){
    glClear(color and depth)
    glLoadIdentity();
    glPushMatrix();
        //rotate depending on which axis is selected
        switch(axis){
            case 0:
                glRotatef(theta,1,0,0);
                break;
            case 1:
                glRotatef(theta,0,1,0);
                break;
            case 2:
                glRotatef(//z axis
        }
        //draw the cube
        colorCube();
    //could have just called load identity here to clear the transforamtion too
    glPopMatrix();
    
    //rotate it, always around x axis
    glRotatef(theta * 101,0,0);
    //move it
    glTranslatef(1.7,0,0);
    //scale it
    glScalef(0.20,0.2,0.2);
    colorCube();
    
    //even smaller cube:
    //will get its own transformations PLUS whatever the transformations were to the small cube
    glRotatef(theta *20,1,0,0);
    glTranslatef(0,2,0);
    glScalef(0.1,0.1,0.1);
    colorCube();
    
    glutSwapBuffers();

}



Index