Create new project - lab05a_transformations - in the usual way.
Rename the source to "translate.cpp", and replace code with the following:
#include "libopengl.h"
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//...
glutSwapBuffers();
}
void retupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glOrtho (-100.0f, 100.0f, -100.0f, 100.0f, -100.0f, 100.0f);
}
void specialKeys(int key, int x, int y)
{
int xRot=0,yRot=0;
xRot = (key == GLUT_KEY_UP)? -1 : xRot;
xRot = (key == GLUT_KEY_DOWN)? 1 : xRot;
yRot = (key == GLUT_KEY_LEFT)? -1 : yRot;
yRot = (key == GLUT_KEY_RIGHT)? 1 : yRot;
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Lab 08");
glutSpecialFunc(specialKeys);
glutDisplayFunc(renderScene);
retupRC();
glutMainLoop();
return 0;
}
Build and test
Glut has a small number shape drawing utility methods such as this one:
Draw a cube of size 50 as follows:
glutWireCube(50.0f);
The cube is currently drawn centered at the origin.
We can move this to another location using
This call is placed //before// the call to render the cube:
glTranslatef(0.0f, 10.0f, 0.0f);
glutWireCube(50.0f);
Build and test. You may notice that the cube is positioned a little higher than previously.
What happens when you press one of the arrow keys? Can you explain it?
In order to move the cube to a desired location - and to leave it there for subsequent rotation - we need to isolate its rendering matrix from the specialKeys rotation.
This can be done using these methods:
Now wrap the above calls in these operations:
glPushMatrix();
glTranslatef(0.0f, 30.0f, 0.0f);
glutWireCube(50.0f);
glPopMatrix();
Build and test. The cube should be half way up the screen, but can now be safely rotated.
We can also rotate this cube programmatically. This version here will draw a line through opposite ends of the cube - and then rotates the entire entity.
glBegin(GL_LINES);
glVertex3f(-100.0f, -100.0f, -100.0f);
glVertex3f(100.0f, 100.0f, 100.0f);
glEnd();
glRotatef(45.0f, 1.0f, 1.0f, 1.0f);
glutWireCube(50.0f);
Just as we can translate and rotate, we can also scale prior to rendering using glScale api call:
Experiment with this fragement:
glScalef(2.0f, 1.0f, 2.0f);
glutWireCube(50.0f);
We can also draw spheres using glut:
Where does the following code position the spheres?
glTranslatef(0.0f, 30.0f, 0.0f);
glutWireSphere(10.0f,15,15);
glTranslatef(30.0f, 0.0f, 0.0f);
glutWireSphere(10.0f,15,15);
The first sphere is moved up 30 units on the Y axis, the second sphere is move 30 unite across on the axis. However, when you run this its result may be suprpising.
Try this instead:
glTranslatef(0.0f, 30.0f, 0.0f);
glutWireSphere(10.0f,15,15);
glTranslatef(0.0f, -30.0f, 0.0f);
glTranslatef(30.0f, 0.0f, 0.0f);
glutWireSphere(10.0f,15,15);
Can you explain what is happening?
Now try this version:
void twoSpheresIdentity()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 30.0f, 0.0f);
glutWireSphere(10.0f,15,15);
glLoadIdentity();
glTranslatef(30.0f, 0.0f, 0.0f);
glutWireSphere(10.0f,15,15);
}
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(25, timer, 1);
}
timer(1);
In renderScene, display a rectangle:
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static float x = 0.4;
glPushMatrix();
glTranslatef(x, 0.0f, 0.0f);
glRectf(0,0,20,20);
glPopMatrix();
glutSwapBuffers();
}
Build and test.
Now animate, by incrementing x every time render scene is called:
x = x + 0.2;
Build and test
If the square goes of the screen at the right, recycle back to the left:
if (x>100)
x = -120;
Now place two rectangles on the screen, one 10 units above the other. Have them both animated.
Offset the top one by 20 units to the left.
Place another 20 units below, offset to the right.
Have each rectangle be a different colour
Place some Sheres on the screen, moving in the opposite direction.
Have the spheres different sizes.
Try to have the spheres moving along the Y-axis, instead of the X axis