SPY HILL Research
Spy-Hill.net

Poughkeepsie, New York [DIR] [UP]

Cube - BOINC Graphics Demonstration

Topics
Graphics API
Animation
Unix Shared Library
Additional Notes
Release Notes

This is a simple demonstration of non-trivial screen-saver graphics in BOINC, including animation. It also shows how the graphics thread of a Unix application can be put into a separate shared library, so that the application can continue to run even if the graphics fails to start.

Last modified: 6 January 2011

Overview

This is a BOINC application which demonstrates the basics of how to write a graphics thread for a screensaver, including simple animations.

The previous example application (yello) showed how to get graphics output, but focused on all the libraries and linking commands necessary to do that. The actual graphics were overly simple and not very illustrative. Now we look at how to create more interesting graphics.

Unlike the more complicated example application which follows (lalanne), this app does a fixed amount of "work", regardless of whether or not the graphics are ever activiated, and then it exits.

In addition to demonstrating how to create a simple animated screensaver, this application will be used to test (and then demonstrate) a way to compile against dynamic libraries on Linux so that the application can run on a wide range of Linux installations. It will also eventually demonstrate how to compile on Windows against the BOINC libraries rather than the full source code. Eventually, the computation thread will also be upgraded to do something more interesting.

The BOINC API's are documented on the BOINC website:

For this example application the Graphics API is the most important one.

It is possible to compile and run this application without relying on GLUT by not setting the compiler macro USE_GLUT. In this case the floating text won't appear. It is also possible to compile and run the application without any graphics at all by not setting BOINC_APP_GRAPHICS (but why would you want to?)

Graphics API

This example application displays a simple OpenGL graphics animation, which provides a working example of how to do that. For your own application you can just take out my silly drawings and put in your own code.

Like many animated graphics programs, there are three routines ("callbacks") which you need to write:

The first routine needs to clear the screen and initialize the OpenGL viewpoint and modeling transformation. If you have previously used OpenGL with GLUT then you need to know that BOINC does not provide a useful default viewpoint.

The window change routine just needs to adjust the viewport to accomodate the change in window size. In Windows, when the graphics window is "put away" (on the task bar) the window size is changed to (0,0). It would be possible to use this information to bypass rendering the scene, which would give more cycles to the science thread. We have not done this here.

There are also a few other callbacks you can provide to BOINC, for mouse and keyboard input and in case user preferences have changed. At this point you can just leave these empty, though you do need to provide them. The examples here just print out which key or button was pressed, but do not do anything interesting.

Animation

Moving, animated graphics are created by having the rendering routine draw a slightly different picture each time it is called. There are two general ways to do this, "absolute" and "relative". In either case, the rendering routine is provided with the current time, in floating point seconds, so that it may know exactly what picture to draw.

An "absolute" rendering routine uses the current time t to determine exactly what image to show. In the case of this example the viewpoint is rotated around the cube (though it looks like the cube is rotating and the viewpoint is fixed). The amount of rotation is simply proportional to the time t according to the relation

theta = PI2/20.0 * t;
where PI2 is 2π, which is the number of radians in one revolution. Thus the cube will make a full rotation in 20 seconds.

It is not always possible, or at least not as easy, to compute the scene based on the exact time t. Instead, you compute the "relative" change in the parameters that specify the scene over the time interval dt since the last time the scene was rendered. The one complication to this is that you have to remember the time the routine was first called. Although the rendering routine used in this example application is "absolute", it also shows how to compute dt and how to get the process started. This makes it easy for you to insert "relative" rendering code if you like.

Unix Graphics in a shared library

THIS SECTION IS OLD. BOINC 6 DOES NOT USE DYNAMIC GRAPHICS LIBRARIES. The fact that there are so many different Linux distributions with so many different versions of graphics libraries adds some extra complexity to the task of getting a BOINC application to run with graphics on Linux. In the 'yello' example program we simply compiled the graphics routines in with the application, and that runs fine on machines that have the proper libraries. But if the client machine does not have the appropriate libraries then the application will fail just because of this relatively small problem.

The way around this is to compile the graphics routines into a separate shared object (or "dynamical") library. When the application goes to start the graphics it tries to load this library. If the library fails to load then it is assumed that the proper supporting graphics libraries are not available, and the application continues with the calculations but without displaying graphics. This is described on the BOINC web site as part of the BOINC graphics API.,

The Unix Makefile included with the source code for 'cube' demonstrates how to compile and link the code to produce both the main program and the separate shared library for the graphics code. The shared library is called cube.so.

When you "add" the application to your project, or more specifically when you udate a version of the application, you must package up both the executable and the shared library together, which is slightly more complicated than simply adding a single executable, as you did for the 'hello' and 'yello' examples. Instructions for doing this can be found here. One thing to note is that the shared object library needs a full name with a version number in it, but will be opened with a simple name like "cube.so". Thus you need to include a file_ref_info file containing a <file_ref> block which associates the physical name of the file (with version number) to the logical name (without version number).

The supporting script add_app.sh will take care of this for you if it finds a shared object library for your application. You can either run this script from the directory in which you built the application, or follow what the script does yourself 'by hand'.

Getting the code

You can get a tarball containing the source code and build scripts here.

Since BOINC v6 the screensaver graphics have been moved to a separate program (instead of just a separate thread). The code for the main graphics program is common to all of the example applications and can be downloaded here: graphics_app.C

On unix you can use CVS to get the code thus:

% cvs -d :pserver:anonymous@www.spy-hill.net:/usr/local/cvsroot/boinc checkout src/apps/cube.d
Then move the directory cube.d to wherever you want to use it. On Windows you need to put this in the boinc/apps folder so that the relative paths are correct in the MSVC++ project file.

Release Notes

Here are more specific notes for particular versions of cube as they are released:
cube 6.07   (31 December 2010)
The binaries for this version of the app are the exact same as cube 6.01 - they were just taken from backups from two years earlier.
cube 6.05   (14 February 2010)
The spinning cube graphic was replaced with concentric hearts, each spinning at a slightly different rate to give a mesmerizing effect. Built against the server_stable branch from SVN.
cube 6.04   (27 March 2009)
This was a test of static linking for Linux. It used the same source code as cube 6.03, but was linked statically against more libraries in an attempt to make it more portable. This fixed problems running the 32-bit version on 64-bit machines, but also broke the graphics for 64-bit machines.
cube 6.03   (12 February 2009)
Built with the SVN trunk, r17125 (labeled version 6.7.0), in anticipation of making it the newest "server_stable" release. The windows version was built with MSVC++ 2003 on Windows 2000.
cube 6.02   (23 December 2008)
The Linux version of this app was corrupted on the project (it was built on a Mac, but had a Linux name). A new version was released, but with no differences frm 6.01.
cube 6.01   (22 December 2008)
Built with the SVN branch "server_stable" (r16543), which was at the time labeled BOINC version 6.3.14. Linux and Mac makefiles adjusted accordingly. Windows version built using MSVC++ 2003. The source code of the application remains the same, but the Windows build configuration files have changed to account for the fact that BOINC source code now uses file extension .cpp rather than the .C extension.
cube 5.15   (24 January 2008)
No changes to the application code. Built with BOINC 5.10.32 from the 5.10 branch. Same issues with graphics on Windows as found for yello.
cube 5.14   (19 June 2007)
The exact same executable as version 5.13, but now with libstdc++.so.6 included in the application bundle.
cube 5.13   (17 June 2007)
Built with revision 121933 (BOINC 5.10.6), with no changes to the appllication code.
cube 5.12   (20 April 2007)
Built with boinc_core_release_5_9_3. No changes to the application code. The 32 bit versions are released for 64 bit platforms, and the PPC version for Mac is released for Intel Macs to run in "emulation" mode.
cube 5.11   (3 April 2007)
Built with CVS HEAD from 9 March 2007 (no tag, but the library build reported the version as 5.9.2). Several string functions, including parse_command_line(), have been moved to a new file str_util.C. Some windows-specific files have been put in win_util.C. Those files and their associated headers have been added to the Project.

The unix version does not have the graphics in a separate shared-object library. That will be part of a subsequent test.

cube 5.10   (24 December 2006)
Small changes to the graphics status reporting to limit the lenght of the error output log. For longer Workunits the error log was exceeding disk usage limits due to the output being too verbose.
cube 5.09   (24 December 2006)
Add a counter-rotating christmas tree inside the box, for the holiday. Report graphics status to stderr as frequently as we report MC progress, or when a key is pressed or window resized.
cube 5.08   (21 December 2006)
The cube edges are now different colors for easier identification. Released for all platforms, but the Linux version still fails and so was recalled. Anytime the window is resized, or at checkpointing, the frame rate and graphics cpu time fraction are written to the error log.
cube 5.06   (10 December 2006)
Built for Mac, using boinc_core_release_5_7_5 with a minor modification to graphics_lib.C to make it build on Mac, and the new (being tested) throttled_app_render().
cube 5.05   (28 November 2006)
This version was built with the latest tagged version in CVS, (boinc_core_release_5_7_5), with a modified version of the graphics rendering routine throttled_app_render().
cube 5.04   (13 November 2006)
This version was another attempt (failed) at having the graphics thread loaded from a dynamic library on Linux.
cube 5.03   (10 November 2006)
The application code was changed so that the graphics on Linux could be put entirely in a separate dynamic library, as described here. This required modifying the mechanism used to see if the graphics thread was ever started. A file "gfx_inited" is now created when the graphics are first initialized, and then the application looks for this file at the end of the run.

This version was built with the latest code (CVS HEAD, no tag) for 10Nov2006, with one small change, to comment out some new development code in boinc_graphics_possible() in the file graphics_api.C

cube 5.01   (18 August 2006)
Initial release. The graphics routines were simply trimmed down from the existing version of the Lalanne application. Built on Linux and Windows with BOINC 5.5.12
  Copyright © 2011 by Spy Hill Research http://www.Spy-Hill.net/~myers/help/boinc/cube.html (served by Islay.spy-hill.com) Last modified: 06 January 2011