# 10. OpenGL Scaling (Version 2.0)

# Introduction

Scaling is the process of manipulating the physical dimensions of an object in relation to itself. For example, you can stretch or shrink an object along any of the 3 axis (x, y and z).

Scaling isn’t a difficult process in OpenGL 2.x and prior because you can use inbuilt functions and I won’t go into the matrix operations involved in scaling within a shader based environment as that’s not what this tutorial is for.

There’s not much else I can say to explain scaling. Scaling is stretching and shrinking, that’s it. The terminology comes from vector math, where it relates to the length of a vector and the manipulations you can perform on a vector.

## Usage

OpenGL comes with the function glScalef which we call before we draw our object and takes 3 values, X, Y and Z. These are all values between -XYZ and +XYZ with 1.0 being the original size of the object.

If we call glScalef(1.f, 1.f, 1.f); then our object is going to stay the exact same size and nothing is going to look different. However if we call glScalef(0.5f, 0.5f, 0.5f); then our object is going to be half of the original size along every axis.

For such a simple function, it is extremely useful, imagine a power-up in Mario where you get the mushroom and Mario grows. You can simply call glScalef(2.f, 2.f, 2.f); and Mario will be twice his original size while everything else stays the same size.

# Coding

Let’s get into it, this no matter how you look at it is a short tutorial.

We’re going to base this tutorial off of the double buffering tutorial as we don’t need the blending functionality.

What we are going to do is take our square as provided by GLUT and we are going to make it half as wide along the x-axis, the same height along the y-axis and twice as deep along the z-axis.

To do this, all we need is the following line of code, right above where we call glutWireCube:

glScalef(0.5f, 1.0f, 2.0f); // Make the shape half as wide, the same height and twice as deep

If you run this you will see the size of the cube has changed and you will get the full effect as it rotates. We started off with a cube and we now have a rectangle thanks to this nifty little call.

It’s important to note that because we call this right before we draw our cube, it is based around the cubes centre of origin, which is why it isn’t narrower on one half. I’ve tried to centre everything in these tutorials around the centre of the screen, to help emphasize this.

If you have any problems at all, email me at swiftless@gmail.com and happy coding!

# Tutorial Code

#include <GL/glew.h> // Include the GLEW header file #include <GL/glut.h> // Include the GLUT header file bool* keyStates = new bool[256]{0}; // Create an array of boolean values of length 256 (0-255) bool movingUp = false; // Whether or not we are moving up or down float yLocation = 0.0f; // Keep track of our position on the y axis. float yRotationAngle = 0.0f; // The angle of rotation for our object void keyOperations (void) { if (keyStates[GLUT_KEY_LEFT]) { // If the left arrow key has been pressed // Perform left arrow key operations } } void display (void) { keyOperations(); glClearColor(1.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on) glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations glTranslatef(0.0f, 0.0f, -5.0f); // Push eveything 5 units back into the scene, otherwise we won't see the primitive glTranslatef(0.0f, yLocation, 0.0f); // Translate our object along the y axis glRotatef(yRotationAngle, 0.0f, 1.0f, 0.0f); // Rotate our object around the y axis glScalef(0.5f, 1.0f, 2.0f); // Make the shape half as wide, the same height and twice as deep glutWireCube(2.0f); // Render the primitive glutSwapBuffers(); // Swap our buffers if (movingUp) // If we are moving up yLocation -= 0.05f; // Move up along our yLocation else // Otherwise yLocation += 0.05f; // Move down along our yLocation if (yLocation < -3.0f) // If we have gone up too far movingUp = false; // Reverse our direction so we are moving down else if (yLocation > 3.0f) // Else if we have gone down too far movingUp = true; // Reverse our direction so we are moving up yRotationAngle += 0.1f; // Increment our rotation value if (yRotationAngle > 360.0f) // If we have rotated beyond 360 degrees (a full rotation) yRotationAngle -= 360.0f; // Subtract 360 degrees off of our rotation } void reshape (int width, int height) { glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up) gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly } void keyPressed (unsigned char key, int x, int y) { keyStates[key] = true; // Set the state of the current key to pressed } void keyUp (unsigned char key, int x, int y) { keyStates[key] = false; // Set the state of the current key to not pressed } int main (int argc, char **argv) { glutInit(&argc, argv); // Initialize GLUT glutInitDisplayMode (GLUT_DOUBLE); // Set up a basic display buffer (now double buffered) glutInitWindowSize (500, 500); // Set the width and height of the window glutInitWindowPosition (100, 100); // Set the position of the window glutCreateWindow ("Your first OpenGL Window"); // Set the title for the window glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering glutIdleFunc(display); // Tell GLUT to use the method "display" as our idle method as well glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping glutKeyboardFunc(keyPressed); // Tell GLUT to use the method "keyPressed" for key presses glutKeyboardUpFunc(keyUp); // Tell GLUT to use the method "keyUp" for key up events glutMainLoop(); // Enter GLUT's main loop }