6/15/2015©Zachary Wartell 1 OpenGL Transforms with Object-Oriented Framework Revision 1.1 Copyright...

17
03/27/22 ©Zachary Wartell 1 OpenGL Transforms with Object-Oriented Framework Revision 1.1 Copyright Zachary Wartell, University of North Carolina at Charlotte, 2008 All Rights Reserved Reading: - Hearn & Baker - Chapter 5 - OpenGL Programming Guide - Chapter 3 – emphasis on "Manipulating the Matrix Stacks" "Examples of Composing Several Transformations"
  • date post

    20-Dec-2015
  • Category

    Documents

  • view

    222
  • download

    0

Transcript of 6/15/2015©Zachary Wartell 1 OpenGL Transforms with Object-Oriented Framework Revision 1.1 Copyright...

04/18/23©Zachary Wartell 1

OpenGL Transforms with Object-Oriented Framework

Revision 1.1Copyright Zachary Wartell, University of North Carolina at Charlotte, 2008

All Rights Reserved

Reading:- Hearn & Baker - Chapter 5- OpenGL Programming Guide - Chapter 3 –

emphasis on "Manipulating the Matrix Stacks" "Examples of Composing Several Transformations"

OpenGL Modeling Transformations

04/18/23©Zachary Wartell 2

glBegin (GL_QUADS);glVertex2i(-0.5,-0.5);glVertex2i( 0.5,-0.5);glVertex2i( 0.5, 0.5);glVertex2i(-0.5, 0.5);glEnd();

coordinatesin

objectcoordinate space

coordinatesin eye

coordinate space

coordinatesin

windowcoordinate space

Vertex commands

GL_MODELVIEWmatrix

GL_PROJECTIONmatrix

+glViewport

matrix

MMV = Meye←object = Meye←world Mworld ← object

MP = Mclip←eye …other magic…MVP = Mwin←ndev

2D Example

04/18/23©Zachary Wartell 3

O

W=E

MMV = Meye←object = Meye←world Mworld ← object

= I · Mworld ← object

View Window (2.5,2.5)W

(-2.5,-2.5)W MP = Mclip←eye - gluOrtho2D

(1,1)Clip

(-1,-1)Clip

04/18/23©Zachary Wartell 4

Matrix Transform Functions

• glMatrixMode({GL_MODELVIEW,GL_PROJECTION});

• glLoadMatrix[fd] (…)• glLoadIdentity ()

• glTranslate[fd] (…)• glRotate[fd] (…)• glScale[fd] (…)• glMultMatrix[fd] (…)

04/18/23©Zachary Wartell 5

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

DrawUnitBox(RED);

glTranslatef(0,1.5,0);

DrawUnitBox(BLUE);

glLoadIdentity();

glTranslatef(0,2.5,0);

glRotatef(45,0,0,1);

DrawUnitBox(GREEN);

glLoadIdentity();

glTranslatef(1.5,2.5,0)

glScalef(0.5,2.0,1);

DrawUnitBox(ORANGE);

Matrix Example

x

y

MMV = I

MMV = MMV • T1

MMV = I

MMV = MMV ·T2

MMV = MMV ·R1

MMV = I

MMV = MMV ·T3

MMV = MMV·S1

I ·

T1 ·

(T2·R1) ·

(T3·S1) ·

(-0.5,-0.5)

( 0.5,0.5)W

04/18/23©Zachary Wartell 6

Matrix Stack

• OpenGL uses one stack for each matrix mode– all matrix operations alter the top matrix – vertex coordinates transformed by the top

stack – glPushMatrix – push a new matrix onto the

stack; the pushed matrix is a copy of previous stack top

– glPopMatrix – pop the stack

04/18/23©Zachary Wartell 7

Matrix Stack Operation

glLoadMatrixf (Q);

glTranslate3f(tx,ty,tz);

glScale3f(sx,sy,sz);

glPushMatrix();

glRotatef(90.0,0.0,0.0,1.0);

glPopMatrix();

glTranslate(tx2,ty2,tz2);M0MMV =Q=Q·T1=Q·T1·S1

=Q·T1·S1M1 =Q·T1·S1·R1MMV

=Q·T1·S1·T2

04/18/23©Zachary Wartell 8

glLoadIdentity();

glTranslatef(2,2,0);

DrawUnitBox(BLUE);

for (angle=0;angle < 360;angle += 90)

{

glPushMatrix();

glRotatef(angle,0,0,1);

glTranslatef(1,0,0);

glScalef(0.5,0.5,1);

DrawUnitBox(RED);

glPopMatrix();

}

Procedure Approach – Hierarchical Objects

x

y

(-0.5,-0.5)

( 0.5,0.5)

W

Object-Oriented Approach (Non-hierarchical)

04/18/23©Zachary Wartell 9

class PosableBox{Point2 origin;float orientation;float scale[2];

…};

void PosableBox::render() const{glPushMatrix();glTranslatef(origin[0],origin[1],0);glRotatef(orientation,0,0,1);glScalef(scale[0],scale[1],1);DrawUnitBox(BLUE);glPopMatrix();}

x

y

(-0.5,-0.5)

( 0.5,0.5)

W

MMV = TB·RB·SB

draw TB·RB·SB

B

( 0.5,0.5)B, (1.8,2.6)W `

Change of Coordinates – Collision/Boundary Violation

04/18/23©Zachary Wartell 10

class PosableBox{Point2 origin;float orientation;float scale[2];

…};

void PosableBox::render() const{glPushMatrix();glTranslatef(origin[0],origin[1],0);glRotatef(orientation,0,0,1);glScalef(scale[0],scale[1],1);DrawUnitBox(BLUE);glPopMatrix();}

x

y

(-0.5,-0.5)

( 0.5,0.5)

W

MMV = TB·RB·SB

draw TB·RB·SB

B

( 0.5,0.5)B,

MW←B = TB·RB·SB

(1.8,2.6)W

Change of Coordinates – Mouse Click

04/18/23©Zachary Wartell 11

class PosableBox{Point2 origin;float orientation;float scale[2];

…};

void PosableBox::render() const{glPushMatrix();glTranslatef(origin[0],origin[1],0);glRotatef(orientation,0,0,1);glScalef(scale[0],scale[1],1);DrawUnitBox(BLUE);glPopMatrix();}

x

y

(-0.5,-0.5)

( 0.5,0.5)

W

MMV = TB·RB·SB

draw TB·RB·SB

B

( 0.5,0.5)B,

MB←W = ?

MW←B = TB·RB·SB

MB←W = MW←B -1 = (TB·RB·SB) -1

= SB -1 ·RB

-1 ·TB -1

(1.8,2.6)W

(2.3,0.8)W

(0,-0.25)B

Object-Oriented – Hierarchical – Step #1

04/18/23©Zachary Wartell 12

class CoordinateSystem{Point2 origin;float orientation;float scale[2];

…};

class Shape{ …};

CS1

UB1 UD1 P1

class Polygon : Shape;

attachment

shapes (0..*)

parent (0..1)

class UnitBox : Shape;

class UnitDisc : Shape;

World Coordinates (W)

MW←CS1

Object-Oriented – Hierarchical – Step #1

04/18/23©Zachary Wartell 13

void CoordinateSystem::render(){glPushMatrix();…post multiply MWorld←Local onto MMV……call Shape::render on all attached Shapes…glPopMatrix();}

void UnitDisc::render (){…send GL the vertex coordinates describing a unit disc measured in local coordinates …}

CS1

UB1 UD1 P1

x

y

WMMV = MW←CS1=TCS1·RCS1·SCS1

render MW←CS1 ·render MW←CS1 ·render MW←CS1

Object-Oriented – Hierarchical – Step #2

04/18/23©Zachary Wartell 14

class CoordinateSystem{Point2 origin;float orientation;float scale[2];

…};

CS1

UB1 UD1 P1

Att

achm

ent

children (0..*)

parent (0..1)

CS2

UB2

MCS1←CS2

MW←CS1

Object-Oriented – Hierarchical – Step #2

04/18/23 15

void CoordinateSystem::render(){glPushMatrix();…post multiply MParent←Local onto MMV…for all attached Shapes

Shape::renderfor all attached CoordinateSystems

CoordinateSystem::render glPopMatrix();} CS1

UB1 UD1 P1 CS2

UB2

CS3

UD2

MCS1←CS3

MCS1←CS2

MW←CS1

W

Object-Oriented – Hierarchical – Step #2

04/18/23©Zachary Wartell 16

void CoordinateSystem::render(){glPushMatrix();…post multiply MParent←Local onto MMV…for all attached Shapes

Shape::renderfor all attached CoordinateSystems

CoordinateSystem::render glPopMatrix();}

MMV =IM0 =I

MMV =I

M0 =I

MMV =I · T CS1 ·R CS1 ·SCS1

MW←CS1M0 =I

M1 =I · T CS1 ·R CS1 ·SCS1

MW←CS1

MMV =I · T CS1 ·R CS1 ·SCS1

M0 =I

M1 =I · T CS1 ·R CS1 ·SCS1

MW←CS1

MMV =I · T CS1 ·R CS1 ·SCS1· T CS2 ·R CS2 ·SCS2

MCS1←CS2

MW←CS2

M0 =I

MMV =I · T CS1 ·R CS1 ·SCS1

MW←CS1M0 =I

M1 =I · T CS1 ·R CS1 ·SCS1

MW←CS1

MMV =I · T CS1 ·R CS1 ·SCS1

M0 =I

M1 =I · T CS1 ·R CS1 ·SCS1

MW←CS1

MMV =I · T CS1 ·R CS1 ·SCS1· T CS3·R CS3 ·SCS3

MCS1←CS3

MW←CS3

M0 =I

MMV =I · T CS1 ·R CS1 ·SCS1

MW←CS1MMV =I

CS1

UB1 UD1 P1 CS2

UB2

CS3

UD2

MCS1←CS3

MCS1←CS2

x

y

W

CS1

CS2

CS

3

MW←CS1

W

04/18/23©Zachary Wartell 17

Tricky BitOpenGL specifications and documents use column-vector notation:

But in C/C++, GL follows the row-major memory organization for matrices:

GLfloat translate[4][4] = {{1, 0, 0, 0}, {0, 1, 0, 0},

{0, 0, 1, 0}, {tx,ty,tz,1}};

When building matrices to transfer to GL or examining matrices retrieved from GL, you must remember the array layout is the transpose of the mathematical convention.

Alternatively, you can use the “transpose” versions of GL matrix routines which accept and return matrix arrays organized using the conventional mathematical layout (see glLoadTransposeMatrix, etc.)

1 0 0

0 1 0

0 0 1

0 0 0 1 1

tx x

ty y

tz z

row column