6/15/2015©Zachary Wartell 1 OpenGL Transforms with Object-Oriented Framework Revision 1.1 Copyright...
-
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