Introduction to Modeling Transformations in OpenGL
CS 442/542
August 30,2012
1.Modeling transformations
When dening the geometry of an object,we typically use a coordinate system that is convenient
for describing its shape.This is often called the master or local coordinate system for that shape.
Many times we want to reuse that shape by placing new instances of the object in dierent areas,
with possibly dierent sizes and orientation.
The transformation that maps the object from its own local coordinates to world coordinates is
called a modeling transformation.
2.Example:Creating a\unit star"in its own local coordinate system.
(0,0)
x
y
0
1
2
3
4
5
6
7
8
9
unit circle
local coordinate
system
static GLfloat starVerts[10][2] = {
{-0.224513988,0.30901699},
{ 0.0,1.0},
{ 0.224513988,0.30901699},
{ 0.951056516,0.30901699},
{ 0.363271264,-0.118033989},
{ 0.587785252,-0.809016994},
{ 0.0,-0.381966011},
{-0.587785252,-0.809016994},
{-0.363271264,-0.118033989},
{-0.951056516,0.30901699}
};
GLushort starIndices[20] = {
0,1,2,//triangle 0
2,3,4,//triangle 1
4,5,6,//triangle 2
6,7,8,//triangle 3
8,9,0,//triangle 4
0,2,4,6,8//triangle fan
};
1
3.Transformation Matrices,Vertex Shader,Matrix Operations,and a Matrix Stack
Client matrices
GLfloat ModelView[4*4];
GLfloat Projection[4*4];
GL matrix
GLint ModelViewProjectionUniform;
Vertex Shader
const GLchar *vertexShaderSource = {
"attribute vec2 vertexPosition;"
"uniform mat4 ModelViewProjection;\n"
"void main() {\n"
"gl_Position = ModelViewProjection*vec4(vertexPosition,0.0,1.0);\n"
"}\n"
};
Loading GL matrix from client matrices
void loadUniforms() {
GLfloat ModelViewProjection[4*4];
matrixMultiply(ModelViewProjection,Projection,ModelView);
glUniformMatrix4fv(ModelViewProjectionUniform,1,GL_FALSE,
ModelViewProjection);
glUniform3fv(ColorUniform,1,Color);
}
Client matrix operations
void matrixIdentity(GLfloat M[4*4]) {...}
matrixOrtho(GLfloat M[4*4],
GLfloat left,GLfloat right,
GLfloat bottom,GLfloat top,
GLfloat hither,GLfloat yon) {...}
matrixScale(GLfloat M[4*4],GLfloat sx,GLfloat sy,GLfloat sz) {...}
void matrixTranslate(GLfloat M[4*4],GLfloat dx,GLfloat dy,GLfloat dz) {...}
void matrixRotate(GLfloat M[4*4],
GLfloat angle_degrees,GLfloat x,GLfloat y,GLfloat z) {...}
Matrix Stack
#define STACK_MAX 10
int matrixStackSize = 0;
GLfloat matrixStack[STACK_MAX][4*4];
void matrixPush(GLfloat M[4*4]) {
memcpy(matrixStack[matrixStackSize++],M,4*4*sizeof(GLfloat));
}
void matrixPop(GLfloat M[4*4]) {
memcpy(M,matrixStack[--matrixStackSize],4*4*sizeof(GLfloat));
}
2
4.OpenGL code to draw unit star
We create buer objects for both the triangle vertices and vertex indices on the rst invocation.
We use glDrawElements() to draw triangle tips and the triangle fan for the center pentagon.
void star(void) {
static GLuint vertBuffer;
static GLuint indexBuffer;
static GLboolean firstTime = GL_TRUE;
if (firstTime) {
glGenBuffers(1,&vertBuffer);
glBindBuffer(GL_ARRAY_BUFFER,vertBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(starVerts),
starVerts,GL_STATIC_DRAW);
glGenBuffers(1,&indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(starIndices),
starIndices,GL_STATIC_DRAW);
firstTime = GL_FALSE;
}
matrixPush(ModelView);
matrixRotate(ModelView,starAngle,0.0,0.0,1.0);
loadUniforms();
glEnableVertexAttribArray(vertexPositionAttr);
glBindBuffer(GL_ARRAY_BUFFER,vertBuffer);
glVertexAttribPointer(vertexPositionAttr,2,GL_FLOAT,
GL_FALSE,0,(GLvoid*) 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBuffer);
glDrawElements(GL_TRIANGLES,15,
GL_UNSIGNED_SHORT,(GLvoid*) 0);
glDrawElements(GL_TRIANGLE_FAN,5,
GL_UNSIGNED_SHORT,(GLvoid*) (15*sizeof(GLushort)));
matrixPop(ModelView);
}
5.The Modeling Matrix
Whenever we\send"a vertex to OpenGL,the vertex is transformed by the current Modeling
Matrix M:This matrix maps the vertex from its local coordinate system to the world coordinate
system.
M
modeling matrix
(x,y)
(x
w
,y
w
)
local
coordinates
world
coordinates
There is another matrix,called the View Matrix V;which maps points from the world coordinate
system to the\eye"or\view"coordinate system.(We will cover this in detail later).
3
M
modeling matrix
(x,y)
(x
w
,y
w
)
local
coordinates
world
coordinates
V
(x
e
,y
e
)
eye
coordinates
view matrix
We combine these two matrices into a single Model-View Matrix which is conceptually the product
V M:
VM
composite
model-view matrix
(x,y)
local
coordinates
(x
e
,y
e
)
eye
coordinates
For now,just assume that the view-matrix is the identity matrix.
matrixIdentity(ModelView);
M I
Subsequent calls to matrixRotate(),matrixTranslate(),matrixScale(),...concatenate
the specied matrix onto the specied matrix.For example,the following code snippet rst
concatenates a translation matrix onto the Model-View matrix and then concatenates a scale
matrix onto the result.
matrixTranslate(ModelView,0.0,0.75,0.0);
matrixScale(ModelView,0.15,0.15,1.0);
The concatenation replaces the current matrix with the product of the current matrix times the
specied matrix (i.e.,we multiply on the right).
M M T
M M S
It is important to note that,since we multiply on the right,the last transformation specied has
the rst eect on the vertices being transformed.In the above example M = T S;so the scale
occurs before the translation:
Mx = (TS)x = (T(Sx))
We can preserve and restore the current matrix using a matrix stack via matrixPush() and
matrixPop():
matrixPush(ModelView);//save model-view matrix
matrixTranslate(ModelView,0.0,0.75,0.0);
matrixScale(ModelView,0.15,0.15,1.0);
/* draw some primitives here */
matrixPop(ModelView);//resore model-view matrix
This allows us to temporarily modify the Model-View matrix.
4
6.Example:Create ring of stars
(a) Create\pole star"by rst scaling the unit star by 0.1 in both x and y and then translating it in
the y direction by 0.75.The composite transformation becomes
M
0
= T
0;:75
S
:1;:1
void poleStar(void) {
matrixPush(ModelView);
matrixTranslate(ModelView,0.0,0.75,0.0);
matrixScale(ModelView,0.15,0.15,1.0);
star();
matrixPop(ModelView);
}
(b) We then create our ring of 13 stars by continually rotating the pole star by = 360=13:
M
1
= R
M
0
M
2
= R
R
M
0
.
.
.
M
12
= R
:::R
R
|
{z
}
12
M
0
void starRing(void) {
matrixPush(ModelView);
matrixRotate(ModelView,ringAngle,0.0,0.0,1.0);
poleStar();
for (int i = 0;i < 12;i++) {
matrixRotate(ModelView,360.0/13,0.0,0.0,1.0);
poleStar();
}
matrixPop(ModelView);
}
The matrixTranslate(ModelMatrix,0.0,0.75,0.0) creates a new translation matrix T
0;:75
and concatenates it onto the right of the current modeling matrix:
M M T
0;:75
5
The call the matrixPush(ModelMatrix) preserves the state of the current modeling matrix.Later,
a symmetric call to matrixPop(ModelMatrix) restores the modeling matrix to its value at the
time of the corresponding push.
How transformation matrices are composed in starRing() (M = current modeling matrix,T =
translation,S = scale,R = rotate):
M = I
push entering starRing()
push entering poleStar()
M = T
M = T S
unit star
pop leaving poleStar()
M = I
M = R
push
M = R T
M = R T S
unit star
pop
M = R
M = R R
push
M = R R T
M = R R T S
unit star
pop
M = R R
.
.
.
pop leaving starRing()
M = I
6
Enter the password to open this PDF file:
File name:
-
File size:
-
Title:
-
Author:
-
Subject:
-
Keywords:
-
Creation Date:
-
Modification Date:
-
Creator:
-
PDF Producer:
-
PDF Version:
-
Page Count:
-
Preparing document for printing…
0%
Σχόλια 0
Συνδεθείτε για να κοινοποιήσετε σχόλιο