4 | | A BOINC application may provide graphics (e.g. visualizations) to volunteers. |
5 | | These graphics are shown in two contexts: |
6 | | |
7 | | * As a screensaver, if selected by the user. |
8 | | * In a window, opened using the Show Graphics button in the BOINC Manager. |
9 | | |
10 | | == Graphics apps == |
11 | | |
12 | | Graphics are generated by a 'graphics app' program (separate from the main application). |
13 | | This graphics app must have the properties that: |
14 | | |
15 | | * If invoked with `--fullscreen`, it opens a full-screen borderless window. |
16 | | It must exit on mouse or keyboard input |
17 | | (if you use the [#api BOINC graphics API] library this is handled automatically). |
18 | | * Otherwise it opens a standard window, and may handle mouse/keyboard input. |
19 | | |
20 | | The logical name of the program must be 'graphics_app'. |
21 | | When you set up your [AppVersionNew application version directory], use an entry like |
22 | | {{{ |
23 | | <file> |
24 | | <physical_name>uppercase_graphics_6.14_windows_intelx86.exe</physical_name> |
25 | | <logical_name>graphics_app</logical_name> |
26 | | </file> |
27 | | }}} |
28 | | in your version.xml file. |
29 | | |
30 | | The graphics app is launched by the BOINC Manager and/or by the screensaver. |
31 | | It may be killed at any time. |
32 | | Multiple instances of the graphics app may run at the same time |
33 | | (e.g. if the user opens a graphics window via the Manager, |
34 | | and then the screensaver runs and launches another instance). |
| 3 | = Using OpenGL = |
94 | | The graphics app may want to get information from the main app. |
95 | | This can be done using either shared memory or a file. |
96 | | |
97 | | ==== Shared memory ==== |
98 | | |
99 | | Communicating large amounts of data |
100 | | can be done efficiently using shared memory. |
101 | | The BOINC library supplies the following functions to facilitate this: |
102 | | |
103 | | {{{ |
104 | | void* boinc_graphics_make_shmem(char* appname, int size); |
105 | | }}} |
106 | | Called from the main app. |
107 | | Creates a shared memory segment of the given size. |
108 | | 'appname' should be the name of this application (used to ensure uniqueness of the shared-memory segment name). |
109 | | |
110 | | {{{ |
111 | | void* boinc_graphics_get_shmem(char* appname); |
112 | | }}} |
113 | | Called from the graphics app. |
114 | | Attaches to an existing segment. |
115 | | It must be called AFTER boinc_parse_init_data_file(). |
116 | | |
117 | | The contents of the shared memory segment are application-dependent; |
118 | | typically it contains numeric information describing the state of the computation. |
119 | | |
120 | | You may want to include the following items: |
121 | | {{{ |
122 | | struct UC_SHMEM { |
123 | | double update_time; |
124 | | double fraction_done; |
125 | | double cpu_time; |
126 | | BOINC_STATUS status; |
127 | | int countdown; |
128 | | }; |
129 | | }}} |
130 | | |
131 | | These items should be updated by the main app once per second, |
132 | | using [BasicApi#timer boinc_set_timer_handler()]. |
133 | | The items are: |
134 | | update_time:: |
135 | | The current time (dtime()). |
136 | | The graphics app should exit if the current time exceeds this by 5 seconds or so, |
137 | | so that it exits if the main app exits. |
138 | | fraction_done:: |
139 | | The last fraction done reported by the main app. |
140 | | cpu_time:: |
141 | | The current CPU time, as returned by '''boinc_worker_thread_cpu_time()'''. |
142 | | status:: |
143 | | The BOINC status, as returned by '''boinc_get_status()'''. |
144 | | If the 'suspended' flag is set, |
145 | | the graphics app should stop changing its display, |
146 | | and instead show an "application suspended" message. |
147 | | countdown:: |
148 | | See below. |
149 | | |
150 | | Keep in mind that multiple instances of the graphics app may run simultaneously; |
151 | | avoid having the graphics app write to the shared memory. |
152 | | If you use shared memory to store a data structure, |
153 | | use a semaphore to synchronize access so that the graphics app |
154 | | doesn't see an inconsistent state. |
155 | | |
156 | | Updating the shared memory structure uses CPU time, |
157 | | and it's desirable to avoid this overhead if no graphics app is running. |
158 | | |
159 | | One way to do this is to include a '''countdown''' field in the shared memory structure, as above. |
160 | | * The graphics sets this to 5 (say) in its '''app_graphics_render()''' function. |
161 | | * The main app decrements this (if positive) once per second. |
162 | | * The main app updates the application-specific data in shared memory |
163 | | only when '''countdown''' is nonzero. |
164 | | |
165 | | See [ExampleApps the example application] for an example. |
166 | | |
167 | | ==== File ==== |
168 | | |
169 | | Alternatively, you can communicate data from main app to graphics app via a file. |
170 | | The BOINC library provides two functions for this purpose. |
171 | | The main program can call |
172 | | {{{ |
173 | | int boinc_write_graphics_status( |
174 | | const char* filename, double cpu_time, double elapsed_time, |
175 | | double fraction_done |
176 | | ); |
177 | | }}} |
178 | | to write a file containing its status in XML format. |
179 | | The graphics app can call |
180 | | {{{ |
181 | | int boinc_parse_graphics_status( |
182 | | const char* filename, double* update_time, double* cpu_time, |
183 | | double* elapsed_time, double* fraction_done, BOINC_STATUS* status |
184 | | ); |
185 | | }}} |
186 | | to read and parse this file. |
187 | | |
188 | | === Creating an icon for your applications === |
189 | | |
190 | | For Windows: |
191 | | |
192 | | * make Icons (there's a tool for this in Visual Studio), |
193 | | say "boincAppIcon16x16.ico", "boincAppIcon32x32.ico" and "boincAppIcon48x48.ico". |
194 | | * create a simple resource description file "boincAppIcon.rc" in the same directory |
195 | | as the icon files pointing to the icon filenames, |
196 | | the first entry is the resource name that is later passed to setWinIcon(): |
197 | | {{{ |
198 | | boinca16 ICON boincAppIcon16x16.ico |
199 | | boinca32 ICON boincAppIcon32x32.ico |
200 | | boinca48 ICON boincAppIcon48x48.ico |
201 | | }}} |
202 | | * compile the resource (I do this on a Visual Studio Command Prompt): |
203 | | {{{ |
204 | | rc.exe boincAppIcon.rc |
205 | | }}} |
206 | | * when linking the App, add the resulting file boincAppIcon.RES to the objects |
207 | | |
208 | | * we call setWinIcon("boinca16","boinca48") in app_graphics_init() |
209 | | |
210 | | === Support classes === |
| 62 | == Support classes == |