Modeling with OpenGL
Intent
Learn OpenGL matrix operations Model a 3D world
◦ Use quads, lines, triangles,cubes, spheres and other primitives
◦ Apply Color
◦ Translation, Rotation, Scale
◦ OpenGL stae machine, saving state, restoring
Setting up OpenGL for MS VC++
Copy & Paste :
glut32.dll to %WinDir%\System,
glut32.lib to $(MSDevDir)\..\..\
VC98\lib, and
glut.h to $(MSDevDir)\..\..\VC98\
Setting up for MS VC++
2008
Copy & Paste :
glut32.dll to %WinDir%\System,
glut32.lib to
..\Program Files\Microsoft Visual Studio 9.0\VC\lib
and
glut.h to ..\Program Files\Microsoft
Visual Studio 9.0\include\GL.
Beginning
Open Visual Studio
Adding OpenGL Codes
#include<windows.h> #include<cstdio>
#include<cmath>
#include<GL/glut.h>
Adding OpenGL code
int main(int argc, char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (900,900);
glutInitWindowPosition (0, 0); glutCreateWindow("Hello 3D"); init(); // init display modes
glutDisplayFunc(display); // display update glutMainLoop();
Adding OpenGL code
Write init(), display() functions
void display() {
glClear(GL_COLOR_BUFFER_BIT);
// …..
// write display codes … // …….
glFlush(); // update display
Init()
void init(void) {
glClearColor(0.0,0.0,0.0,0.0); // black color
//set up projection mode
Now, what to do ?
Add some models Add Camera
Add Projection
Add some models
Hand-sketch or draw a story
Add some models
Add some models
Suppose this is our world
A field of 30X30
size
A cub e cen
tere d at (5,1
,5)
This structure
Add the field
void display() {
glClear(GL_COLOR_BUFFER_BIT); // …..
// write display codes …
glMatrixMode(GL_MODELVIEW); glColor3f(1.0,1.0,1.0); //white glBegin(GL_LINE_LOOP); glVertex3f(-15.0,0.0,15.0); glVertex3f(15.0,0.0,15.0); glVertex3f(15.0,0.0,-15.0); glVertex3f(-15.0,0.0,-15.0); glEnd(); // …….
Add the cube
void display(){
glClear(GL_COLOR_BUFFER_BIT); // …..
// write display codes … glMatrixMode(GL_MODELVIEW); glColor3f(1.0,1.0,1.0); //white glBegin(GL_LINE_LOOP); glVertex3f(-15.0,0.0,15.0); glVertex3f(15.0,0.0,15.0); glVertex3f(15.0,0.0,-15.0); glVertex3f(-15.0,0.0,-15.0); glEnd(); glTranslated(5.0,1.0,5.0); glutWireCube(1.0); // …….
What about viewing ?
Want to view what we have done
so far
Press Ctrl + F5
What about viewing ?
What do you find ?
◦ Nothing
◦ Whats the problem ?
No view !!
Add a view
Add a view
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
gluLookAt(
??
);
From where we are looking at ?
Add a view
It seems we are looking at the
origin (0,0,0) from a bit distant… and high
Say, eye position at
(25,25,-25)
Add a view
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
gluLookAt(
25.0,25.0,-25.0, 0.0,0.0,0.0,
0.0,1.0,0.0
);
Should we be able to get some output if we run
now ?
Add Projection
Add projection
Now Run
Ctrl + F5
Adding the axes
glColor3f(0.3,0.3,0.3); glBegin(GL_LINES);
glVertex3f(0.0,0.0,-15.0); glVertex3f(0.0,0.0,15.0); glEnd();
glBegin(GL_LINES);
glVertex3f(-15.0,0.0,0.0); glVertex3f(15.0,0.0,0.0);
glEnd();
Adding a grid
glMatrixMode(GL_MODELVIEW); glColor3f(0.3,0.3,0.3); #define EXTX 14
#define EXTZ 14
glBegin(GL_LINES);
double x = -(double)EXTX;
for(int i = 1; i<=2*EXTX+1; i++) glVertex3f(x,0.0,-15.0); glVertex3f(x,0.0,15.0); x += 1.0;
} glEnd();
glBegin(GL_LINES);
double z = -(double)EXTZ;
for(int i = 1; i<=2*EXTZ+1; i++) {
glVertex3f(-15.0,0.0,z); glVertex3f(15.0,0.0,z); z += 1.0;
} glEnd();
What about moving the
camera
;-)
It looks like a film storyboard Let us animate the camera
Moving the camera
Enable double buffer and add a mouse
function
int main(int argc, char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (900,900);
glutInitWindowPosition (0, 0); glutCreateWindow("Hello 3D"); init(); // init display modes
glutDisplayFunc(display); // display update glutMouseFunc(mouse);
glutMainLoop(); return 0;
Moving the camera
Moving the camera
SpinDisplay will be called whenever
idle
Add a global variable camera_angle
Write the spinDisplay() function to
update camera angle
void spinDisplay(void) {
camera_angle = camera_angle + 0.2; if(camera_angle > 360.0)
camera_angle = camera_angle - 360.0;
glutPostRedisplay();
Change the camera code
Add a circle equation for camera
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
#define PI 3.1415926535897932
double eyex = 25.0*cos(camera_angle*PI/180.0); double eyez = 25.0*sin(camera_angle*PI/180.0);
gluLookAt(
eyex,25.0,-eyez,
0.0,0.0,0.0, 0.0,1.0,0.0 );
Moving the camera
Run it …
Click the mouse
Check that the camera is moving
◦ Don’t be confused, here model is static
◦ Only camera is moving
Later we will do things, where
Adding one more model
Intent it
Adding one more model
void drawHighTriangle() {
glBegin(GL_LINE_LOOP); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glVertex3f(1.0,0.0,0.0); glEnd();
glBegin(GL_LINE_LOOP); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glVertex3f(0.0,0.0,1.0); glEnd();
Adding one more model
Now, we want to draw this model
at (-8,0,8) with 5X scaling
Should this work ?
glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
Adding one more model
Say we have one cube at (5,1,5)
Say we draw the cube by :
glTranslated(5.0,1.0,5.0); glutWireCube(1.0);
Now, how to draw the other model ??
glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
drawHighTriangle();
Order Matters ?
glColor3f(0.0,1.0,1.0);
glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
drawHighTriangle();
glColor3f(1.0,1.0,0.0);
Order Matters ?
glColor3f(1.0,1.0,0.0);
glTranslated(5.0,1.0,5.0); glutWireCube(5.0);
glColor3f(0.0,1.0,1.0);
glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
More..
And if there is rotation …
glColor3f(0.0,1.0,1.0);
glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
glRotatef(25.0,0.0,0.0,1.0); drawHighTriangle();
More..
And if there is rotation …
glColor3f(1.0,1.0,0.0); glTranslated(5.0,1.0,5.0); glRotatef(45.0,1.0,0.0,0.0); glutWireCube(5.0);
glColor3f(0.0,1.0,1.0);
glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
Why this happens ?
OpenGL is a state machine. Proper process ?
glPushMatrix();
glColor3f(1.0,1.0,0.0); glTranslated(5.0,1.0,5.0); glutWireCube(5.0);
glPopMatrix();
glPushMatrix();
glColor3f(0.0,1.0,1.0); glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
drawHighTriangle();
Transformation in OpenGL
OpenGL uses 3 stacks to maintain transformation matrices:
Model & View transformation matrix stack Projection matrix stack
Texture matrix stack
You can load, push and pop the stack
The top most matrix from each stack is applied to
all graphics primitive until it is changed
Translation – 2D
(4,5) (7,5) Y X Before Translation 1 * 1 0 0 1 0 0 1 1 y x d d y x T P P d d T y x P y x P y x y x Form s Homogenioux’ = x + dx y’ = y + dy
(7,1) (10,1)
X Y
Translation by (3,-4)
Transformations and OpenGL
® Each time an OpenGL transformation M is called the current MODELVIEW matrix
C is altered:
Cv
v v CMv
glTranslatef(1.5, 0.0, 0.0); glRotatef(45.0, 0.0, 0.0, 1.0);
CTRv v
Note: v is any vertex placed in rendering pipeline v’ is the transformed vertex from v.
Order of Transformations
T: Translate 20 unit along X
glTranslatef(20.0, 0.0, 0.0);
R1 : Rotate 90 degree around X
glRotatef(90,0, 1.0, 0.0, 0.0);
T2: Translate 10 unit along Y
glTranslatef(10.0,0.0,1.0, 0.0);
This translation is actually along the
Saving the state
Transformations have cumulative effect glPushMatrix() saves present state
So how to draw models
When we know the position of
things around a special
orientation/ reference point we
Thinking About Transformations
As a Global System
Objects moves but
coordinates stay the same
Think of
transformation in
reverse order as
they appear in code
As a Local System
Objects moves and
coordinates move with it
Think of
transformation in
same order as they
appear in code There is a World Coordinate System where:
All objects are defined
Transformations are in World Coordinate space
Two Different Views
Local View
Translate Object Then Rotate
Order of Transformation T•R
glLoadIdentity();
glMultiMatrixf( T);
glMultiMatrixf( R);
draw_ the_ object( v); v’ = ITRv
Global View
Rotate Object Then Translate
Effect is same, but perception is different
glLoadIdentity();
glMultiMatrixf( R);
glMultiMatrixf( T);
draw_ the_ object( v); v’ = ITRv
Local View
Rotate Object Then Translate
Global View
Translate Object Then Rotate
Effect is same, but perception is different
Animating Models
Previously we animated camera Now we animate models
Straight forward process
◦ Enable double buffering ◦ Keep an IdleFunction
◦ Update animation data inside idle function
Animating models
glPushMatrix();glColor3f(1.0,1.0,0.0); glTranslated(5.0,1.0,5.0);
glRotatef(angle_1,1.0,0.0,0.0); glutWireCube(5.0); glPopMatrix(); glPushMatrix(); glColor3f(0.0,1.0,1.0); glTranslated(-8.0,0.0,8.0); glScalef(5.0,5.0,5.0);
glRotatef(angle_2,0.0,0.0,1.0); drawHighTriangle();
Animating models
Inside the idleFunction (here spinDisplay) update
animation data
void spinDisplay(void) {
camera_angle = camera_angle + 1.0;
angle_1 += 2.0; angle_3 += 5.0;
if(camera_angle > 360.0)
camera_angle = camera_angle - 360.0;
if(angle_1 > 360.0)
angle_1 = angle_1 - 360.0; if(angle_2 > 360.0)
angle_2 = angle_2 - 360.0;