In this recipe, we will learn how to transform our graphics using OpenGL transformations.
We will draw a unit cube at [0,0,0]
coordinates and then we will translate it to the center of the window, apply rotation, and scale it to a more visible size.
Include the necessary files to draw with OpenGL and add the helpful using
statements. Add the following code to the top of the source file:
#include "cinder/gl/gl.h" using namespace ci; using namespace ci::app; using namespace std;
We will apply rotation, translation, and scaling to alter the way our cube is rendered. We will use Cinder's wrappers for OpenGL.
Vec3f mTranslation; Vec3f mScale; Vec3f mRotation;
[0,0,0]
to the center of the window. Add the following code in the setup
method:mTranslation.x = getWindowWidth() / 2; mTranslation.y = getWindowHeight() / 2; mTranslation.z = 0.0f;
100
on the x axis, 200
on the y axis, and 100
on the z axis. Anything we draw will be 100 times bigger on the x and z axes and 200 times bigger on the y axis. Add the following code in the setup
method:mScale.x = 100.0f; mScale.y = 200.0f; mScale.z = 100.0f;
update
method, we will animate the rotation values by incrementing the rotation on the x and y axes.mRotation.x += 1.0f; mRotation.y += 1.0f;
draw
method, let's begin by clearing the background with black, setting the windows matrices to allow for drawing in 3D, and enabling OpenGL to read and write the depth buffer:gl::clear( Color( 0, 0, 0 ) ); gl::setMatricesWindowPersp( getWindowWidth(), getWindowHeight() ); gl::enableDepthRead(); gl::enableDepthWrite();
gl::pushMatrices(); gl::translate( mTranslation ); gl::scale( mScale ); gl::rotate( mRotation );
[0,0,0]
with a white fill and black stroke:gl::color( Color::white() ); gl::drawCube( Vec3f(), Vec3f( 1.0f, 1.0f, 1.0f ) ); gl::color( Color::black() ); gl::drawStrokedCube( Vec3f(), Vec3f( 1.0f, 1.0f, 1.0f ) );
gl::popMatrices();
The calls to ci::gl::enableDepthRead
and ci::gl::enableDepthWrite
respectively, enable reading and writing to the depth buffer. The depth buffer is where the depth information is stored.
When reading and writing to the depth buffer is enabled, OpenGL will sort objects so that closer objects are drawn in front of farther objects. When reading and writing to the depth buffer, the disabled objects will be drawn in the order they where created.
The methods ci::gl::translate
, ci::gl::rotate
, and ci::gl::scale
are wrappers of OpenGL commands for translating, rotating, and scaling, which allow you to pass Cinder types as parameters.
Transformations in OpenGL are applied by multiplying vertex coordinates with transformation matrices. When we call the method ci::gl::pushMatrices
, we add a copy of the current transformation matrix to the matrix stack. Calls to ci::gl::translate
, ci::gl::rotate
, or ci::gl::scale
will apply the correspondent transformations to the last matrix in the stack, which will be applied to whatever geometry is created after calling the transformation methods. A call to ci::gl::popMatrix
will remove the last transformation matrix in the stack so that transformations added to the last matrix will no longer affect our geometry.
18.216.96.94