Recently I am working on a project which utilizes Qt5.3+OpenGL. I need to implement a function in which by spinning the mouse wheel, the 3D object in OpenGL view can be enlarged or shrunk. After some research, it is found that we can implement the function in two ways: glScaled or glOrthof.
Approach 1: glScaled
glScaled function scales the x, y, z by a factor. In my implementation, all three axis are scaled by the same factor.
First, the mouse wheel function is written in such a way that wheel rotation changes a zoom factor named
zoomScale. After that, it will call the paintGL() function where galScaled is embedded.
void GLWidget::wheelEvent(QWheelEvent *event)
{
QPoint numDegrees = event->angleDelta();
if (numDegrees.y() < 0) zoomScale = zoomScale/1.1;
if (numDegrees.y() > 0) zoomScale = zoomScale*1.1;
updateGL(); // call paintGL()
}
In paintGL() function, galScaled() is called and zoomScale is used to scale x, y, and z axis. We should note that in order to avoid unnecessary clipping, the near and far planes of OpenGL view need to be set with some redundancy.
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glScaled(zoomScale, zoomScale, zoomScale);
glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);
Approach 2: glOrthof
glOrthof function defines a box where the objects are shown in OpenGL. The box has left, right, up, down, near, far boundaries. Again, we starts from the wheelEvent function which calls resizeGL().
void GLWidget::wheelEvent(QWheelEvent *event)
{
QPoint numDegrees = event->angleDelta();
if (numDegrees.y() < 0) zoomScale = zoomScale/1.1;
if (numDegrees.y() > 0) zoomScale = zoomScale*1.1;
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
resizeGL(viewport[2], viewport[3]);
updateGL(); // call paintGL()
}
In resizeGL, zoomScale is used to adjust the boundaries in x and y directions. In this way, we can also implement the zoom in/out functions.
void GLWidget::resizeGL(int width, int height)
{
int side = qMin(width, height);
int range = 1000;
//glViewport((width - side) / 2, (height - side) / 2, side, side);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-0.5*range*zoomScale, +0.5*range*zoomScale, -0.5*height/width*range*zoomScale, +0.5*height/width*range*zoomScale, -5*range, +5*range);
glMatrixMode(GL_MODELVIEW);
}