-
Notifications
You must be signed in to change notification settings - Fork 514
API for graphics apps
BOINC supplies a library (libboinc_graphics2.a) with support for graphics apps using OpenGL, Glut, and TrueType. A complete example can be found in boinc/samples/example_app.
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 must generate the current graphic using OpenGL.
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
)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.
A graphics app can display a pre-existing JPEG file.
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.
BOINC supports the display of text using TrueType fonts.
- Add the files
api/ttfont.cppandapi/ttfont.hto your application (they are not included in any BOINC library.) - 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; see https://boinc.berkeley.edu/boinc_depends/. To build these libraries on the Mac, please see MacBuild.
- Include the desired TrueType fonts in your app versions.
The set of free Liberation fonts in included the
api/ttf/directory. If you wish to use other TrueType fonts, you'll need to adjust the list of font names inttfont.cpp. (Another source of free fonts is the GNU Freefont project.) - To display text, use the following API functions:
float white[4] = {1., 1., 1., 1.};
APP_INIT_DATA aid;
boinc_get_init_data(aid);
// read font files; they're in the project directory
//
ttf_load_fonts(aid.project_dir);
...
ttf_render_string(
x, y, z, // where to display string
500, // size
white, // color
"App suspended" // the text
0, // which font (see ttfont.cpp)
// default is Sans-Regular (0)
);Other parameters to ttf_render_string() let you specify rotation;
see ttfont.h.
For examples, see the clientscr/ss_app.cpp
and samples/example_app/uc2_graphics.cpp in the BOINC trunk.
The graphics app may want to get information from the main app. This can be done using either shared memory or a file.
Communicating large amounts of data 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);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).
void* boinc_graphics_get_shmem(char* appname);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 application-dependent; typically it contains numeric information describing the state of the computation.
You may want to include the following items:
struct UC_SHMEM {
double update_time;
double fraction_done;
double cpu_time;
BOINC_STATUS status;
int countdown;
};These items 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, so that it exits if the main app exits.
fraction_done
The last fraction done reported by the main app.
cpu_time
The current CPU time, as returned by boinc_worker_thread_cpu_time().
status
The BOINC status, as returned by `boinc_get_status()`.
If the 'suspended' flag is set,
the graphics app should stop changing its display,
and instead show an "application suspended" message.
countdown
See below.
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.
Updating the shared memory structure uses CPU time,
and it's desirable to avoid this overhead if no graphics app is running.
One way to do this is to include a `countdown` field in the shared memory structure, as above.
* The graphics sets this to 5 (say) in its `app_graphics_render()` function.
* The main app decrements this (if positive) once per second.
* The main app updates the application-specific data in shared memory
only when `countdown` is nonzero.
See [the example application](ExampleApps) for an example.
### File
Alternatively, you can communicate data from main app to graphics app via a file.
The BOINC library provides two functions for this purpose.
The main program can call
```c
int boinc_write_graphics_status(
const char* filename, double cpu_time, double elapsed_time,
double fraction_done
);
to write a file containing its status in XML format. The graphics app can call
int boinc_parse_graphics_status(
const char* filename, double* update_time, double* cpu_time,
double* elapsed_time, double* fraction_done, BOINC_STATUS* status
);to read and parse this file.
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 (e.g. on a Visual Studio Command Prompt):
rc.exe boincAppIcon.rc
-
When linking the App, add the resulting file boincAppIcon.RES to the objects
-
Call setWinIcon("boinca16","boinca48") in app_graphics_init()