Version 35 (modified by 12 years ago) (diff) | ,
---|
Providing graphics for BOINC applications
A BOINC application may provide graphics (e.g. visualizations) to volunteers. These graphics appear in two contexts:
- As a screensaver.
- In a window (opened using the Show Graphics button in the BOINC Manager).
Graphics apps
The most general way of providing graphics involves using a 'graphics app' program (separate from your main application). This graphics app must have the properties that:
- If invoked with
--fullscreen
, it opens a full-screen borderless window. It must exit on mouse or keyboard input; this is handled automatically byboinc_graphics_loop()
if you use the BOINC graphics API library. - Otherwise it opens a standard window, and may handle mouse/keyboard input.
The logical name of the program must be 'graphics_app'. When you set up your application version directory, use an entry like
<file> <physical_name>uppercase_graphics_6.14_windows_intelx86.exe</physical_name> <logical_name>graphics_app</logical_name> </file>
in your version.xml file.
The graphics app is launched by the BOINC Manager and by the screensaver. It may be killed at any time. Multiple instances of the graphics app may run at the same time (e.g. if the user opens a graphics window via the Manager, and then the screensaver runs and launches another instance).
The BOINC graphics API provides cross-platform support for developing graphics apps.
A complete example can be found in boinc/samples/example_app.
The BOINC Graphics API
BOINC supplies a library (libboinc_graphics2.a) that makes it easy to develop graphics apps. To use this library, the graphics app must call
boinc_graphics_loop(int argc, char** argv);
after its initialization. This function executes an event loop, and does not return.
The application must supply the following functions:
void app_graphics_init();
Called once, after the window has been created.
void app_graphics_render(int xs, ys, double time_of_day);
This will be called periodically.
It should generate the current graphic.
xs
and ys
are the X and Y sizes of the window, and time_of_day
is the relative time in seconds.
void app_graphics_resize(int x, int y);
Called when the window size changes.
void boinc_app_mouse_move( int x, int y, // new coords of cursor int left, // whether left mouse button is down int middle, int right ); void boinc_app_mouse_button( int x, int y, // coords of cursor int which, // which button (0/1/2) int is_down // true iff button is now down ); void boinc_app_key_press( int, int // system-specific key encodings ) void boinc_app_key_release( int, int // system-specific key encodings )
Communicating with the main application
The graphics app may want to get information from the main app. This can be done efficiently using shared memory. The BOINC library supplies the following functions to facilitate this:
void* boinc_graphics_make_shmem(char* appname, int size); void* boinc_graphics_get_shmem(char* appname);
boinc_graphics_make_shmem()
(called from the main app) creates a shared memory segment of the given size.
'appname' should be the name of this application (used to ensure uniqueness of the shared-memory segment name). boinc_graphics_get_shmem()
(called from the graphics app) attaches to an existing segment.
It must be called AFTER boinc_parse_init_data_file().
The contents of the shared memory segment are up to you. You may want to include the following items:
struct UC_SHMEM { double update_time; double fraction_done; double cpu_time; BOINC_STATUS status; };
This structure should be updated by the main app once per second, using boinc_set_timer_handler(). The items are:
- update_time
- The current time (dtime()). The graphics app should exit if the current time exceeds this by 5 seconds or so.
- fraction_done
- The last fraction done reported by the main app.
- cpu_time
- The current CPU time.
- status
- The BOINC status. If the 'suspended' flag is set, the graphics app should stop changing its display, and simply display an "application suspended" message.
Keep in mind that multiple instances of the graphics app may run simultaneously; avoid having the graphics app write to the shared memory. If you use shared memory to store a data structure, use a semaphore to synchronize access so that the graphics app doesn't see an inconsistent state.
Creating an icon for your applications
For Windows:
- make Icons (there's a tool for this in Visual Studio), say "boincAppIcon16x16.ico", "boincAppIcon32x32.ico" and "boincAppIcon48x48.ico".
- create a simple resource description file "boincAppIcon.rc" in the same directory
as the icon files pointing to the icon filenames,
the first entry is the resource name that is later passed to setWinIcon():
boinca16 ICON boincAppIcon16x16.ico boinca32 ICON boincAppIcon32x32.ico boinca48 ICON boincAppIcon48x48.ico
- compile the resource (I do this on a Visual Studio Command Prompt):
rc.exe boincAppIcon.rc
- when linking the App, add the resulting file boincAppIcon.RES to the objects
- we call setWinIcon("boinca16","boinca48") in app_graphics_init()
Support classes
Several graphics-related classes were developed for SETI@home. They may be of general utility.
TEXTURE_DESC
Represents a JPEG image displayed in 3 dimensions.
PROGRESS
and PROGRESS_2D
Represent progress bars, depicted in 3 or 2 dimensions.
REDUCED_ARRAY
Represents a two-dimensional array of data, which is reduced to a smaller dimension by averaging or taking extrema. Includes member functions for drawing the reduced data as a 3D graph in several ways (lines, rectangles, connected surface).
RIBBON_GRAPH
Represents of 3D graph of a function of 1 variable.
MOVING_TEXT_PANEL
Represents a flanged 3D panel, moving cyclically in 3 dimensions, on which text is displayed.
STARFIELD
Represents a set of randomly-generated stars that move forwards or backwards in 3 dimensions.
The file api/ttfont.cpp
has support functions from drawing nice-looking 3D text.
Displaying a static image
An application can display a pre-existing JPEG file as its graphic.
This is the simplest approach since you don't need to develop any code.
You must include the image file with each workunit.
To do this, link the application with api/static_graphics.cpp
(edit this file to use your filename).
You can change the image over time,
but you must change the (physical, not logical) name of the file each time.
Using Web graphics
You can also generate graphics using HTML. Note: this works for graphics windows created using the Manager's Show Graphics button; it doesn't provide a screensaver.
In this case your main program supplies a URL that supplies the HTML. This may be an external URL, or it may refer to a web server embedded in your main program (i.e. a URL of the form http://localhost:port). Your main program can call
boinc_web_graphics_url(char* url)
to register a URL to be used for graphics; in this case, the BOINC Manager's Show Graphics button will open a Web browser window to this URL.
Displaying text
Older versions of the BOINC graphics API library included functions for rendering texture fonts using font files of the form *.txf. These have been eliminated, and we have instead added support for displaying strings using TrueType fonts in BOINC graphics applications.
- Add the files
api/ttfont.cpp
andapi/ttfont.h
to your application (they are not included in any BOINC library.) - You will need to link with the FreeType2 and FTGL libraries. Depending on how you build the FreeType2 library, FreeType2 may require the libz and libbz2 libraries. For Windows, prebuilt libraries are available in the
boinc_depends_win_vs2005
repository. To build these libraries on the Mac, please see MacBuild. - We have put copies of the free Liberation fonts in the
api/ttf/
directory. If you wish to use other TrueType fonts, you will need to adjust the list of font names inttfont.cpp
. (Another source of free fonts is the GNU Freefont project.) - Download the desired TrueType fonts to the client where they are available to your graphics application.
For examples, please see the clientscr/ss_app.cpp
and samples/exampple_app/uc2_graphics.cpp
in the BOINC SVN trunk.
If your graphics application currently uses the older texture fonts, note that the ttf_load_fonts() and txf_render_string() APIs are slightly different from the old txf_load_fonts() and txf_render_string() APIs, which have been eliminated. Please see the ttfont.cpp
and ttfont.h
files for details.