QGLViewer - Technical FAQ

See also the General FAQ
»»   The black screen is back !
»»   It still looks strange
»»   What is a ManipulatedFrame ?
»»   What are Frame hierarchies ?
»»   How can I use several ManipulatedFrame ?
»»   What are MouseGrabbers ?
»»   How are mouse events interpreted ?
»»   How can I redefine the mouse/keyboard behavior ?
»»   How can I select/move/edit several objects ?
»»   How can I use several viewers ?
»»   I use several viewers and textures/display lists are screwed up !
»»   How can I measure my application frame rate ?
»»   Why is there no FPS/text displayed ?
»»   My init() function is never called !
»»   What are these strange characters at the bottom of the screen ?
»»   How can I define a world positioned light ?

The black screen is back !

"I copy-pasted my code in your draw() function, and the screen remains black. I hate OpenGL !"
The classical OpenGL black screen is not supported by libQGLViewer. There are two possible reasons for your problem, as detailed in the introduction: Press 'A' to display the world axis and double click the mouse middle button to make the camera fit the scene. You should at least see the axis and can start debugging from there with basic drawing code.

It still looks strange

If your are still unable to get the results you had before porting to libQGLViewer, check that your init function sets the default OpenGL state with glEnable(GL_LIGHTING, GL_FOG, ...) as you did before.

Also note that libQGLViewer slightly changes the default OpenGL state (see the QGLViewer::initializeGL() documentation): GL_LIGHTING, GL_LIGHT0, GL_DEPTHTEST and GL_COLORMATERIAL are enabled. Disable them in your init() method if desired.

What is a ManipulatedFrame ?

A ManipulatedFrame is a Frame (position and orientation in 3D) that can directly be moved with the mouse. It is used to move objects in your scene, see the ManipulatedFrame example.

What are Frame hierarchies ?

The Frame class represents a position and orientation in 3D. These frames can be organized in a tree hierarchy and convenient conversion functions are provided. The OpenGL code should reflect this organization, as is detailed in the Frame detailed description.

How can I use several ManipulatedFrame ?

Simply create several ManipulatedFrame (typically stored in a vector) and use setManipulatedFrame() to decide which of them is active at a given time. See the Luxo example for an illustration.

What are MouseGrabbers ?

MouseGrabber is an empty interface for any object that may grab the mouse focus. They are usually 2D or 3D objects, located on screen and that react when the mouse hover over them. Being very generic, many usages are possible, opening the way to innovating reactive user interfaces. See the MouseGrabber documentation for an example.

Note that a ManipulatedFrame is actually a MouseGrabber: the frame can be directly manipulated when the mouse goes close to its origin. See the MouseGrabber example for an illustration.

How are mouse events interpreted ?

The mouse events are sent to three possible receivers: the camera, the manipulatedFrame or a MouseGrabber, depending on the context. By default, events are send to the camera. With a specific state key (default is the Control key), it is the manipulatedFrame that receives the mouse events. Finally, the mouseGrabber grabs mouse focus when its MouseGrabber::grabsMouse() method returns true (typically when the mouse hovers). All this can of course be customized (see the mouse page).

How can I redefine the mouse/keyboard behavior ?

See the mouse and keyboard pages. The keyboardAndMouse example illustrates this in details.

How can I select/move/edit several objects ?

See the multiSelect example for a multiple selection implementation. The selected objects can then be manipulated (or edited) as a group.

How can I use several viewers ?

Simply create them, as in the multiView example.

You may have to connect additional signals to synchronize viewers' displays. A ManipulatedFrame displayed by several viewers should typically have its manipulated signal connected to the other viewers' updateGL() slots.

The different viewers can share their OpenGL contexts. See the QGLViewer constructors' documentations and the multiView example.

I use several viewers and textures/display list are screwed up

If your viewers do not share their OpenGL context, you have to make sure that the appropriate context is active when a viewer is drawn: call makeCurrent() to do this. This is automatically done by the normal refresh loop.

How can I measure my application frame rate ?

Press the F key to toggle the frame rate display. It is computed as an average over 30 frames. Since the display is updated only when needed, the frame rate is valid only when you display in a loop (such as when you move the camera with the mouse).

If you want to know the maximum possible frame rate of your machine on a given scene, you should setAnimationPeriod(0) and turn on the animation (by pressing Enter). The display will then be updated as quickly as possible, and the frame rate will be meaningful.

Why is there no FPS/text displayed ?

Qt has problems to display text in OpenGL on some architectures. This has been solved in Qt 3.3 and there is a patch in the code for previous versions. However, disable font antialiasing using qtconfig to fix this if needed.

My init() function is never called !

First reason : you overloaded initializeGL(). Bad idea since it is this function that calls init() in QGLViewer. Move your code to init() and remove your initializeGL() overloading.

Second reason : you call updateGL() in your constructor, even indirectly. This calls init(), but at that point, virtual functions are not defined and it is the QGLViewer::init() that is called. Move all OpenGL specific code out of the constructor to put it in init().

What are these strange characters at the bottom of the screen ?

The renderText method uses display lists to display characters. If you use more than 2000 display lists, they may overlap. See the drawText documentation.

How can I define a world positioned light ?

A QGLViewer uses the default OpenGL light setup: GL_LIGHT0 is on and placed at (0,0,0) in the camera coordinate system. To place a light in your scene, use glLight as if you were drawing an object: the current modelView matrix is applied. The following code places a light in the world coordinate system:
void Viewer::draw()
{
  // ModelView represents the world coordinate system at the beginning of draw()
  static const GLfloat pos[4] = {1.5, 0.0, 0.0, 1.0};
  glLightfv(GL_LIGHT0, GL_POSITION, pos);
  static const GLfloat spotDir[3] = {-1.0, 0.0, 0.0};
  glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDir);

  // rest of the drawing code...
  }
See also the cameraLight example that makes the camera act as a spot light.

Other questions can be sent by e-mail and will be added to this page. See also the General FAQ.

Valid XHTML 1.0! Valid CSS! Last modified on Monday, November 13, 2017.