# What is the best way to rotate rectangles/images?

Hello,

I was wondering what the best method of drawing shapes or images that are rotated. Currently, the method I use is the following code:

``````// Translates the screen so that the point of rotation
// is at 0, 0 (pixel coordinates)
gl::translate(rotPt.x, rotPt.y);

// Rotates the screen to the specified amount, if the amount is non-zero
if(rotation != 0)
{
gl::rotate(-rotation);
}

// Draws the rectangle
gl::drawSolidRect(Rectf(pointA.x - rotPt.x, pointA.y - rotPt.y, pointB.x - rotPt.x, pointB.y - rotPt.y));

// Rotates the screen back so that the screen is now level,
// leaving the rectangle rotated to the specified angle,
// if the amount is non-zero
if(rotation != 0)
{
gl::rotate(rotation);
}

// Translates the screen back so that the origin
// is in the correct place again (undoes the above translation)
gl::translate((-rotPt.x), (-rotPt.y));
``````

However, I would think that this isn’t the best way to produce a rotated object, as it seems rather clunky, and the calculations for translations and rotations* would become very intensive once there are many objects on the screen. Is there a better way to do this?

*This is assuming that the gl::translate() and gl::rotate() functions translate and rotate the entire screen, not just the object. As far as I know, this is how they function, but I could be wrong, so let me know if I am.

Thanks, Zack

Hi,

there are a few improvements you can make, which I’ll address briefly:

• Instead of undoing your transformations by applying the reverse translation or rotation, use `gl::pushModelMatrix()` and `gl::popModelMatrix()`. See this article for more general information about the matrix stack. Note that Cinder uses slightly different function names, but the idea is the same.
``````{
gl::pushModelMatrix();
gl::translate( ... );
gl::rotate( ... );
gl::draw( ... );
gl::popModelMatrix();
}
``````
• If you don’t want to remember to call `gl::popModelMatrix()` for each `gl::pushModelMatrix()`, you can use the scoped version which will do it for you. In the following example, we will create a variable named `scpModel` which pushes the current matrix. When it goes out of scope, it automatically pops the matrix for you. Very powerful. There’s many more scoped functions for you to take advantage of. Learn to use them.
``````{
// #include "cinder/gl/scoped.h"
gl::ScopedModelMatrix scpModel;

gl::translate( ... );
gl::rotate( ... );
gl::draw( ... );
}
``````
• Store the combined transformations in a `ci::mat4` variable. That way you don’t have to recalculate them every frame. See e.g. `glm::translate()`, `glm::rotate()`, `glm::angleAxis()` and `glm::scale()`. You can then apply the transformation by calling `gl::setModelMatrix()`.
• Pushing and popping a matrix isn’t very expensive, but if you want to draw thousands of objects it’s better to avoid it. That’s another advantage of using a `ci::mat4` to store the matrix, as you can call `gl::pushModelMatrix()` once, then call `gl::setModelMatrix()` for each object and finally call `gl::popModelMatrix()` once you’re done.
``````{
gl::ScopedModelMatrix  scpModel;
// mMatrices is of type std::vector<ci::mat4>
for( auto &modelMatrix : mMatrices ) {
gl::setModelMatrix( modelMatrix );
gl::draw( ... );
}
}
``````
• The `gl::drawSolidRect()` function is slow. Consider creating a `gl::Batch` from a `geom::Rect` instead and use it over and over.
• Speaking of which: if you want to draw thousands of rectangles, you better use instanced rendering. This will greatly reduce the number of draw calls (from 1000’s to just 1), hugely increasing render performance. For each instance, you’d store a `mat4` in a `Vbo`, attach it to a `VboMesh`, store it in a `Batch` and render it by calling `Batch::drawInstanced()`. See the Cinder samples for more information. Or have a look at my Depth-Of-Field sample, which uses exactly this technique to render hundreds of teapots.

-Paul

1 Like

Thanks!

Does this still apply to things that change position/angle every frame?

Yes, just update its transformation matrix.