1 /* Steven Andrews, started 10/22/2001.
2 This is a library of functions for the Smoldyn program.
3 See documentation called SmoldynManual.pdf and SmoldynCodeDoc.pdf, and the Smoldyn
4 website, which is at www.smoldyn.org.
5 Copyright 2003-2016 by Steven Andrews. This work is distributed under the terms
6 of the Gnu Lesser General Public License (LGPL). */
7
8 #include <float.h>
9 #include <math.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "Geometry.h"
13 #include "math2.h"
14 #include "opengl2.h"
15 #include "Rn.h"
16 #include "string2.h"
17 #include "../libSteve/SimCommand.h"
18
19 #ifdef OPTION_NSV
20 #include "nsvc.h"
21 #endif
22
23 #include "smoldyn.h"
24 #include "smoldynfuncs.h"
25 #include "smoldynconfigure.h"
26
27 /******************************************************************************/
28 /*********************************** Graphics *********************************/
29 /******************************************************************************/
30
31
32 /******************************************************************************/
33 /****************************** Local declarations ****************************/
34 /******************************************************************************/
35
36 // enumerated types
37 char *graphicslp2string(enum LightParam lp,char *string);
38
39 // low level utilities
40
41 // memory management
42 graphicsssptr graphssalloc(void);
43
44 // data structure output
45
46 // structure setup
47
48 // structure update functions
49 int graphicsupdateinit(simptr sim);
50 int graphicsupdatelists(simptr sim);
51 int graphicsupdateparams(simptr sim);
52
53 // core simulation functions
54 void RenderSurfaces(simptr sim);
55 void RenderMolecs(simptr sim);
56 void RenderText(simptr sim);
57 void RenderSim(simptr sim);
58
59 // top level OpenGL functions
60
61 /******************************************************************************/
62 /******************************* enumerated types *****************************/
63 /******************************************************************************/
64
65 /* graphicsstring2lp */
graphicsstring2lp(char * string)66 enum LightParam graphicsstring2lp(char *string) {
67 enum LightParam ans;
68
69 if(strbegin(string,"ambient",0)) ans=LPambient;
70 else if(strbegin(string,"diffuse",0)) ans=LPdiffuse;
71 else if(strbegin(string,"specular",0)) ans=LPspecular;
72 else if(strbegin(string,"position",0)) ans=LPposition;
73 else if(strbegin(string,"on",0)) ans=LPon;
74 else if(strbegin(string,"off",0)) ans=LPoff;
75 else if(strbegin(string,"auto",0)) ans=LPauto;
76 else ans=LPnone;
77 return ans; }
78
79
80 /* graphicslp2string */
graphicslp2string(enum LightParam lp,char * string)81 char *graphicslp2string(enum LightParam lp,char *string) {
82 if(lp==LPambient) strcpy(string,"ambient");
83 else if(lp==LPdiffuse) strcpy(string,"diffuse");
84 else if(lp==LPspecular) strcpy(string,"specular");
85 else if(lp==LPposition) strcpy(string,"position");
86 else if(lp==LPon) strcpy(string,"on");
87 else if(lp==LPoff) strcpy(string,"off");
88 else if(lp==LPauto) strcpy(string,"auto");
89 else strcpy(string,"none");
90 return string; }
91
92
93 /******************************************************************************/
94 /****************************** low level utilities ***************************/
95 /******************************************************************************/
96
97 /* graphicsreadcolor */
graphicsreadcolor(char ** stringptr,double * rgba)98 int graphicsreadcolor(char **stringptr,double *rgba) {
99 char *string,name[STRCHAR];
100 double r,g,b,a;
101 int itct,er;
102
103 if(!stringptr) return 1;
104 string=*stringptr;
105 if(!string) return 1;
106 itct=sscanf(string,"%s",name);
107 if(itct!=1) return 1;
108
109 er=0;
110 r=g=b=0;
111 a=1;
112 if((name[0]>='0' && name[0]<='9') || name[0]=='.') { // numbers
113 itct=sscanf(string,"%lg %lg %lg",&r,&g,&b);
114 if(itct!=3) er=2;
115 else {
116 if(r<0 || r>1 || g<0 ||g>1 || b<0 || b>1) er=3;
117 string=strnword(string,4); }}
118 else { // word
119 if(!strcmp(name,"maroon")) {r=0.5;g=0;b=0;}
120 else if(!strcmp(name,"red")) {r=1;g=0;b=0;}
121 else if(!strcmp(name,"scarlet")) {r=1;g=0.14;b=0;}
122 else if(!strcmp(name,"rose")) {r=1;g=0;b=0.5;}
123 else if(!strcmp(name,"brick")) {r=0.7;g=0.13;b=0.13;}
124 else if(!strcmp(name,"pink")) {r=1;g=0.08;b=0.58;}
125 else if(!strcmp(name,"brown")) {r=0.54;g=0.27;b=0.07;}
126 else if(!strcmp(name,"tan")) {r=0.86;g=0.58;b=0.44;}
127 else if(!strcmp(name,"sienna")) {r=0.56;g=0.42;b=0.14;}
128 else if(!strcmp(name,"orange")) {r=1;g=0.65;b=0;}
129 else if(!strcmp(name,"salmon")) {r=0.91;g=0.59;b=0.48;}
130 else if(!strcmp(name,"coral")) {r=0.94;g=0.42;b=0.31;}
131 else if(!strcmp(name,"yellow")) {r=1;g=1;b=0;}
132 else if(!strcmp(name,"gold")) {r=1;g=0.84;b=0;}
133 else if(!strcmp(name,"olive")) {r=0.5;g=0.5;b=0;}
134 else if(!strcmp(name,"green")) {r=0;g=0.5;b=0;}
135 else if(!strcmp(name,"chartrouse")) {r=0.5;g=1;b=0;}
136 else if(!strcmp(name,"khaki")) {r=0.8;g=0.77;b=0.45;}
137 else if(!strcmp(name,"purple")) {r=0.5;g=0;b=0.5;}
138 else if(!strcmp(name,"magenta")) {r=1;g=0;b=1;}
139 else if(!strcmp(name,"fuchsia")) {r=1;g=0;b=1;}
140 else if(!strcmp(name,"lime")) {r=0;g=1;b=0;}
141 else if(!strcmp(name,"teal")) {r=0;g=0.5;b=0.5;}
142 else if(!strcmp(name,"aqua")) {r=0;g=1;b=1;}
143 else if(!strcmp(name,"cyan")) {r=0;g=1;b=1;}
144 else if(!strcmp(name,"blue")) {r=0;g=0;b=1;}
145 else if(!strcmp(name,"navy")) {r=0;g=0;b=0.5;}
146 else if(!strcmp(name,"turquoise")) {r=0.25;g=0.88;b=0.82;}
147 else if(!strcmp(name,"royal")) {r=0;g=0.14;b=0.4;}
148 else if(!strcmp(name,"sky")) {r=0.53;g=0.81;b=0.92;}
149 else if(!strcmp(name,"aquamarine")) {r=0.5;g=1;b=0.83;}
150 else if(!strcmp(name,"indigo")) {r=0.29;g=0;b=0.51;}
151 else if(!strcmp(name,"violet")) {r=0.58;g=0;b=0.83;}
152 else if(!strcmp(name,"mauve")) {r=0.88;g=0.69;b=1;}
153 else if(!strcmp(name,"orchid")) {r=0.73;g=0.33;b=0.83;}
154 else if(!strcmp(name,"plum")) {r=0.6;g=0.12;b=0.5;}
155 else if(!strcmp(name,"azure")) {r=0;g=0.5;b=1;}
156 else if(!strcmp(name,"black")) {r=0;g=0;b=0;}
157 else if(!strcmp(name,"gray")) {r=0.5;g=0.5;b=0.5;}
158 else if(!strcmp(name,"grey")) {r=0.5;g=0.5;b=0.5;}
159 else if(!strcmp(name,"silver")) {r=0.75;g=0.75;b=0.75;}
160 else if(!strcmp(name,"slate")) {r=0.44;g=0.5;b=0.56;}
161 else if(!strcmp(name,"white")) {r=1;g=1;b=1;}
162
163 else if(!strcmp(name,"darkred")) {r=0.55;g=0;b=0;}
164 else if(!strcmp(name,"darkorange")) {r=1;g=0.55;b=0;}
165 else if(!strcmp(name,"darkyellow")) {r=1;g=0.84;b=0;}
166 else if(!strcmp(name,"darkgreen")) {r=0;g=0.39;b=0;}
167 else if(!strcmp(name,"darkblue")) {r=0;g=0;b=0.55;}
168 else if(!strcmp(name,"darkviolet")) {r=0.29;g=0;b=0.51;}
169 else if(!strcmp(name,"darkgrey")) {r=0.25;g=0.25;b=0.25;}
170 else if(!strcmp(name,"darkgray")) {r=0.25;g=0.25;b=0.25;}
171 else if(!strcmp(name,"lightred")) {r=1;g=0.39;b=0.28;}
172 else if(!strcmp(name,"lightorange")) {r=1;g=0.75;b=0.2;}
173 else if(!strcmp(name,"lightyellow")) {r=1;g=1;b=0.5;}
174 else if(!strcmp(name,"lightgreen")) {r=0.56;g=1;b=0.5;}
175 else if(!strcmp(name,"lightblue")) {r=0.53;g=0.81;b=0.98;}
176 else if(!strcmp(name,"lightviolet")) {r=0.68;g=0.1;b=1;}
177 else if(!strcmp(name,"lightgrey")) {r=0.75;g=0.75;b=0.75;}
178 else if(!strcmp(name,"lightgray")) {r=0.75;g=0.75;b=0.75;}
179
180 else er=4;
181 string=strnword(string,2); }
182
183 if(string) {
184 itct=sscanf(string,"%lg",&a);
185 if(itct!=1) er=5;
186 if(a<0 || a>1) er=6;
187 string=strnword(string,2); }
188
189 if(rgba) {
190 rgba[0]=r;
191 rgba[1]=g;
192 rgba[2]=b;
193 rgba[3]=a; }
194 *stringptr=string;
195 return er; }
196
197
198 /******************************************************************************/
199 /******************************* memory management ****************************/
200 /******************************************************************************/
201
202 /* graphssalloc */
graphssalloc(void)203 graphicsssptr graphssalloc(void) {
204 graphicsssptr graphss;
205 int lt;
206
207 graphss=NULL;
208 CHECKMEM(graphss=(graphicsssptr) malloc(sizeof(struct graphicssuperstruct)));
209
210 graphss->condition=SCinit;
211 graphss->sim=NULL;
212 graphss->graphics=0;
213 graphss->currentit=0;
214 graphss->graphicit=20;
215 graphss->graphicdelay=0;
216 graphss->tiffit=0;
217 graphss->framepts=2;
218 graphss->gridpts=0;
219
220 graphss->framecolor[0]=0; // black frame
221 graphss->framecolor[1]=0;
222 graphss->framecolor[2]=0;
223 graphss->framecolor[3]=1;
224
225 graphss->gridcolor[0]=0; // black grid
226 graphss->gridcolor[1]=0;
227 graphss->gridcolor[2]=0;
228 graphss->gridcolor[3]=1;
229
230 graphss->backcolor[0]=1; // white background
231 graphss->backcolor[1]=1;
232 graphss->backcolor[2]=1;
233 graphss->backcolor[3]=1;
234
235 graphss->textcolor[0]=0; // black text
236 graphss->textcolor[1]=0;
237 graphss->textcolor[2]=0;
238 graphss->textcolor[3]=0;
239
240 graphss->maxtextitems=0;
241 graphss->ntextitems=0;
242 graphss->textitems=NULL;
243
244 graphicssetlight(NULL,graphss,-1,LPauto,NULL);
245 for(lt=0;lt<MAXLIGHTS;lt++) graphicssetlight(NULL,graphss,lt,LPauto,NULL);
246
247 return graphss;
248
249 failure:
250 graphssfree(graphss);
251 simLog(NULL,10,"Failed to allocate memory in graphssalloc");
252 return NULL; }
253
254
255 /* graphssfree */
graphssfree(graphicsssptr graphss)256 void graphssfree(graphicsssptr graphss) {
257 int item;
258
259 if(!graphss) return;
260 for(item=0;item<graphss->maxtextitems;item++) free(graphss->textitems[item]);
261 free(graphss->textitems);
262 free(graphss);
263 return; }
264
265
266 /******************************************************************************/
267 /***************************** data structure output **************************/
268 /******************************************************************************/
269
270
271 /* graphssoutput */
graphssoutput(simptr sim)272 void graphssoutput(simptr sim) {
273 graphicsssptr graphss;
274 char string1[STRCHAR],string2[STRCHAR];
275 int i1,i2,lt;
276
277 graphss=sim->graphss;
278 simLog(sim,2,"GRAPHICS PARAMETERS\n");
279 if(!graphss || graphss->graphics==0) {
280 simLog(sim,2," No graphical output\n\n");
281 return; }
282
283 simLog(sim,2," display: ");
284 if(graphss->graphics==1) simLog(sim,2,"OpenGL");
285 else if(graphss->graphics==2) simLog(sim,2,"OpenGL_good");
286 else if(graphss->graphics==3) simLog(sim,2,"OpenGL_better");
287 simLog(sim,2,", every %i iterations\n",graphss->graphicit);
288 if(graphss->graphicdelay>0) simLog(sim,2," delay per frame: %ui ms\n",graphss->graphicdelay);
289
290 simLog(sim,2," frame thickness: %g",graphss->framepts);
291 if(graphss->gridpts) simLog(sim,2,", grid thickness: %g",graphss->gridpts);
292 simLog(sim,2,"\n");
293 if(graphss->framepts) simLog(sim,2," frame color: %g,%g,%g,%g\n",graphss->framecolor[0],graphss->framecolor[1],graphss->framecolor[2],graphss->framecolor[3]);
294 if(graphss->gridpts) simLog(sim,2," grid color: %g,%g,%g,%g\n",graphss->gridcolor[0],graphss->gridcolor[1],graphss->gridcolor[2],graphss->gridcolor[3]);
295 simLog(sim,2," background color: %g,%g,%g,%g\n",graphss->backcolor[0],graphss->backcolor[1],graphss->backcolor[2],graphss->backcolor[3]);
296
297 if(graphss->ntextitems) {
298 simLog(sim,2," text color: %g,%g,%g,%g\n",graphss->textcolor[0],graphss->textcolor[1],graphss->textcolor[2],graphss->textcolor[3]);
299 simLog(sim,2," text items:");
300 for(i1=0;i1<graphss->ntextitems;i1++)
301 simLog(sim,2," %s",graphss->textitems[i1]);
302 simLog(sim,2,"\n"); }
303
304 if(graphss->graphics>=3)
305 simLog(sim,2," ambient light (%s): %g %g %g %g\n",graphicslp2string(graphss->roomstate,string1),graphss->ambiroom[0],graphss->ambiroom[1],graphss->ambiroom[2],graphss->ambiroom[3]);
306 for(lt=0;lt<MAXLIGHTS;lt++)
307 if(graphss->lightstate[lt]!=LPauto) {
308 simLog(sim,2," light %i: %s\n",lt,graphicslp2string(graphss->lightstate[lt],string1));
309 simLog(sim,2," position: %g %g %g %g\n",graphss->lightpos[lt][0],graphss->lightpos[lt][1],graphss->lightpos[lt][2],graphss->lightpos[lt][3]);
310 simLog(sim,2," ambient: %g %g %g %g\n",graphss->ambilight[lt][0],graphss->ambilight[lt][1],graphss->ambilight[lt][2],graphss->ambilight[lt][3]);
311 simLog(sim,2," diffuse: %g %g %g %g\n",graphss->difflight[lt][0],graphss->difflight[lt][1],graphss->difflight[lt][2],graphss->difflight[lt][3]);
312 simLog(sim,2," specular: %g %g %g %g\n",graphss->speclight[lt][0],graphss->speclight[lt][1],graphss->speclight[lt][2],graphss->speclight[lt][3]); }
313
314 gl2GetString("TiffName",string1);
315 gl2GetString("TiffNameDefault",string2);
316 i1=(int)gl2GetNumber("TiffNumber");
317 i2=(int)gl2GetNumber("TiffNumMax");
318 if(strcmp(string1,string2)) simLog(sim,2," TIFF name: %s\n",string1);
319 if(i1!=(int)gl2GetNumber("TiffNumberDefault") || i2!=(int)gl2GetNumber("TiffNumMaxDefault"))
320 simLog(sim,2," TIFFs numbered from %i to %i\n",i1,i2);
321 simLog(sim,2,"\n");
322 return; }
323
324
325 /* writegraphss */
writegraphss(simptr sim,FILE * fptr)326 void writegraphss(simptr sim,FILE *fptr) {
327 graphicsssptr graphss;
328 char string[STRCHAR];
329 int lt,item;
330
331 graphss=sim->graphss;
332 if(!graphss) return;
333
334 fprintf(fptr,"# Graphics parameters\n");
335 if(graphss->graphics==0) fprintf(fptr,"graphics none\n");
336 else if(graphss->graphics==1) fprintf(fptr,"graphics opengl\n");
337 else if(graphss->graphics==2) fprintf(fptr,"graphics opengl_good\n");
338 else if(graphss->graphics==3) fprintf(fptr,"graphics opengl_better\n");
339 if(graphss->graphicit>1) fprintf(fptr,"graphic_iter %i\n",graphss->graphicit);
340 if(graphss->graphicdelay>0) fprintf(fptr,"graphic_delay %ui\n",graphss->graphicdelay);
341
342 if(graphss->tiffit>0) fprintf(fptr,"tiff_iter %i\n",graphss->tiffit);
343 fprintf(fptr,"tiff_name %s\n",gl2GetString("TiffName",string));
344 fprintf(fptr,"tiff_min %i\n",gl2SetOptionInt("TiffNumber",-1));
345 fprintf(fptr,"tiff_max %i\n",gl2SetOptionInt("TiffNumMax",-1));
346
347 fprintf(fptr,"frame_thickness %g\n",graphss->framepts);
348 fprintf(fptr,"frame_color %g %g %g %g\n",graphss->framecolor[0],graphss->framecolor[1],graphss->framecolor[2],graphss->framecolor[3]);
349 fprintf(fptr,"grid_thickness %g\n",graphss->gridpts);
350 fprintf(fptr,"grid_color %g %g %g %g\n",graphss->gridcolor[0],graphss->gridcolor[1],graphss->gridcolor[2],graphss->gridcolor[3]);
351 fprintf(fptr,"background_color %g %g %g %g\n",graphss->backcolor[0],graphss->backcolor[1],graphss->backcolor[2],graphss->backcolor[3]);
352 fprintf(fptr,"text_color %g %g %g %g\n",graphss->textcolor[0],graphss->textcolor[1],graphss->textcolor[2],graphss->textcolor[3]);
353
354 for(item=0;item<graphss->ntextitems;item++)
355 fprintf(fptr,"text_display %s\n",graphss->textitems[item]);
356
357 if(graphss->roomstate!=LPauto) {
358 fprintf(fptr,"light global ambient %g %g %g %g\n",graphss->ambiroom[0],graphss->ambiroom[1],graphss->ambiroom[2],graphss->ambiroom[3]);
359 fprintf(fptr,"light global %s\n",graphicslp2string(graphss->roomstate,string)); }
360 for(lt=0;lt<MAXLIGHTS;lt++)
361 if(graphss->lightstate[lt]!=LPauto) {
362 fprintf(fptr,"light %i position %g %g %g\n",lt,graphss->lightpos[lt][0],graphss->lightpos[lt][1],graphss->lightpos[lt][2]);
363 fprintf(fptr,"light %i ambient %g %g %g %g\n",lt,graphss->ambilight[lt][0],graphss->ambilight[lt][1],graphss->ambilight[lt][2],graphss->ambilight[lt][3]);
364 fprintf(fptr,"light %i diffuse %g %g %g %g\n",lt,graphss->difflight[lt][0],graphss->difflight[lt][1],graphss->difflight[lt][2],graphss->difflight[lt][3]);
365 fprintf(fptr,"light %i specular %g %g %g %g\n",lt,graphss->speclight[lt][0],graphss->speclight[lt][1],graphss->speclight[lt][2],graphss->speclight[lt][3]);
366 fprintf(fptr,"light %i %s\n",lt,graphicslp2string(graphss->lightstate[lt],string)); }
367
368 fprintf(fptr,"\n");
369 return; }
370
371
372 /* checkgraphicsparams */
checkgraphicsparams(simptr sim,int * warnptr)373 int checkgraphicsparams(simptr sim,int *warnptr) {
374 int error,warn;
375 graphicsssptr graphss;
376 char string[STRCHAR];
377
378 error=warn=0;
379 graphss=sim->graphss;
380 if(!graphss) {
381 if(warnptr) *warnptr=warn;
382 return 0; }
383
384 if(graphss->condition!=SCok) {
385 warn++;
386 simLog(sim,7," WARNING: graphics structure %s\n",simsc2string(graphss->condition,string)); }
387
388 if(warnptr) *warnptr=warn;
389 return error; }
390
391 /******************************************************************************/
392 /******************************* structure setup ******************************/
393 /******************************************************************************/
394
395
396 /* graphicssetcondition */
graphicssetcondition(graphicsssptr graphss,enum StructCond cond,int upgrade)397 void graphicssetcondition(graphicsssptr graphss,enum StructCond cond,int upgrade) {
398 if(!graphss) return;
399 if(upgrade==0 && graphss->condition>cond) graphss->condition=cond;
400 else if(upgrade==1 && graphss->condition<cond) graphss->condition=cond;
401 else if(upgrade==2) graphss->condition=cond;
402 if(graphss->sim && graphss->condition<graphss->sim->condition) {
403 cond=graphss->condition;
404 simsetcondition(graphss->sim,cond==SCinit?SClists:cond,0); }
405 return; }
406
407
408 /* graphicsenablegraphics */
graphicsenablegraphics(simptr sim,const char * type)409 int graphicsenablegraphics(simptr sim,const char *type) {
410 graphicsssptr graphss;
411 int code;
412
413 if(!sim) return 2;
414
415 if(type) {
416 if(!strcmp(type,"none")) code=0;
417 else if(!strcmp(type,"opengl")) code=1;
418 else if(!strcmp(type,"opengl_good")) code=2;
419 else if(!strcmp(type,"opengl_better")) code=3;
420 else return 3; }
421 else code=-1;
422
423 if(sim->graphss && (code==-1 || sim->graphss->graphics==code)) return 0;
424 if(!sim->graphss && code==0) return 0;
425
426 if(!sim->graphss) {
427 graphss=graphssalloc();
428 if(!graphss) return 1;
429 sim->graphss=graphss;
430 graphss->sim=sim; }
431 else graphss=sim->graphss;
432 if(code>=0) graphss->graphics=code;
433 graphicssetcondition(graphss,SClists,0);
434 return 0; }
435
436
437 /* graphicssetiter */
graphicssetiter(simptr sim,int iter)438 int graphicssetiter(simptr sim,int iter) {
439 int er;
440
441 er=graphicsenablegraphics(sim,NULL);
442 if(er) return er;
443 if(iter<1) return 3;
444 sim->graphss->graphicit=iter;
445 return 0; }
446
447
448 /* graphicssettiffiter */
graphicssettiffiter(simptr sim,int iter)449 int graphicssettiffiter(simptr sim,int iter) {
450 int er;
451
452 er=graphicsenablegraphics(sim,NULL);
453 if(er) return er;
454 if(iter<1) return 3;
455 sim->graphss->tiffit=iter;
456 return 0; }
457
458
459 /* graphicssetdelay */
graphicssetdelay(simptr sim,int delay)460 int graphicssetdelay(simptr sim,int delay) {
461 int er;
462
463 er=graphicsenablegraphics(sim,NULL);
464 if(er) return er;
465 if(delay<0) return 3;
466 sim->graphss->graphicdelay=delay;
467 return 0; }
468
469
470 /* graphicssetframethickness */
graphicssetframethickness(simptr sim,double thickness)471 int graphicssetframethickness(simptr sim,double thickness) {
472 int er;
473
474 er=graphicsenablegraphics(sim,NULL);
475 if(er) return er;
476 if(thickness<0) return 3;
477 sim->graphss->framepts=thickness;
478 return 0; }
479
480
481 /* graphicssetframecolor */
graphicssetframecolor(simptr sim,double * color)482 int graphicssetframecolor(simptr sim,double *color) {
483 int er;
484
485 er=graphicsenablegraphics(sim,NULL);
486 if(er) return er;
487 if(color[0]<0 || color[0]>1) return 3;
488 if(color[1]<0 || color[1]>1) return 3;
489 if(color[2]<0 || color[2]>1) return 3;
490 if(color[3]<0 || color[3]>1) return 3;
491 sim->graphss->framecolor[0]=color[0];
492 sim->graphss->framecolor[1]=color[1];
493 sim->graphss->framecolor[2]=color[2];
494 sim->graphss->framecolor[3]=color[3];
495 return 0; }
496
497
498 /* graphicssetgridthickness */
graphicssetgridthickness(simptr sim,double thickness)499 int graphicssetgridthickness(simptr sim,double thickness) {
500 int er;
501
502 er=graphicsenablegraphics(sim,NULL);
503 if(er) return er;
504 if(thickness<0) return 3;
505 sim->graphss->gridpts=thickness;
506 return 0; }
507
508
509 /* graphicssetgridcolor */
graphicssetgridcolor(simptr sim,double * color)510 int graphicssetgridcolor(simptr sim,double *color) {
511 int er;
512
513 er=graphicsenablegraphics(sim,NULL);
514 if(er) return er;
515 if(color[0]<0 || color[0]>1) return 3;
516 if(color[1]<0 || color[1]>1) return 3;
517 if(color[2]<0 || color[2]>1) return 3;
518 if(color[3]<0 || color[3]>1) return 3;
519 sim->graphss->gridcolor[0]=color[0];
520 sim->graphss->gridcolor[1]=color[1];
521 sim->graphss->gridcolor[2]=color[2];
522 sim->graphss->gridcolor[3]=color[3];
523 return 0; }
524
525
526 /* graphicssetbackcolor */
graphicssetbackcolor(simptr sim,double * color)527 int graphicssetbackcolor(simptr sim,double *color) {
528 int er;
529
530 er=graphicsenablegraphics(sim,NULL);
531 if(er) return er;
532 if(color[0]<0 || color[0]>1) return 3;
533 if(color[1]<0 || color[1]>1) return 3;
534 if(color[2]<0 || color[2]>1) return 3;
535 if(color[3]<0 || color[3]>1) return 3;
536 sim->graphss->backcolor[0]=color[0];
537 sim->graphss->backcolor[1]=color[1];
538 sim->graphss->backcolor[2]=color[2];
539 sim->graphss->backcolor[3]=color[3];
540
541 graphicssetcondition(sim->graphss,SCparams,0);
542 return 0; }
543
544
545 /* graphicssettextcolor */
graphicssettextcolor(simptr sim,double * color)546 int graphicssettextcolor(simptr sim,double *color) {
547 int er;
548
549 er=graphicsenablegraphics(sim,NULL);
550 if(er) return er;
551 if(color[0]<0 || color[0]>1) return 3;
552 if(color[1]<0 || color[1]>1) return 3;
553 if(color[2]<0 || color[2]>1) return 3;
554 if(color[3]<0 || color[3]>1) return 3;
555 sim->graphss->textcolor[0]=color[0];
556 sim->graphss->textcolor[1]=color[1];
557 sim->graphss->textcolor[2]=color[2];
558 sim->graphss->textcolor[3]=color[3];
559 return 0; }
560
561
562 /* graphicssettextitem */
graphicssettextitem(simptr sim,char * itemname)563 int graphicssettextitem(simptr sim,char *itemname) {
564 graphicsssptr graphss;
565 int er,i,newmaxtextitems,item;
566 char **newtextitems;
567 enum MolecState ms;
568
569 er=graphicsenablegraphics(sim,NULL);
570 if(er) return er;
571 graphss=sim->graphss;
572
573 if(graphss->ntextitems==graphss->maxtextitems) {
574 newmaxtextitems=2*graphss->maxtextitems+1;
575 newtextitems=(char **) calloc(newmaxtextitems,sizeof(char *));
576 if(!newtextitems) return 1;
577 for(item=0;item<graphss->maxtextitems;item++)
578 newtextitems[item]=graphss->textitems[item];
579 for(;item<newmaxtextitems;item++) {
580 newtextitems[item]=EmptyString();
581 if(!newtextitems[item]) return 1; }
582
583 free(graphss->textitems);
584 graphss->maxtextitems=newmaxtextitems;
585 graphss->textitems=newtextitems; }
586
587 if(!strcmp(itemname,"time")); // supported items
588 else if(((sim->mols && ((i=molstring2index1(sim,itemname,&ms,NULL))>=0 || i==-5)) || sim->ruless) && ms!=MSbsoln);
589 else return 2; // unrecognized item name
590
591 for(item=0;item<graphss->ntextitems;item++)
592 if(!strcmp(itemname,graphss->textitems[item])) return 3;
593 strncpy(graphss->textitems[graphss->ntextitems++],itemname,STRCHAR);
594 return 0; }
595
596 /* graphicssetlight */
graphicssetlight(simptr sim,graphicsssptr graphss,int lt,enum LightParam ltparam,double * value)597 int graphicssetlight(simptr sim,graphicsssptr graphss,int lt,enum LightParam ltparam,double *value) {
598 int i,er;
599
600 if(!graphss) {
601 er=graphicsenablegraphics(sim,NULL);
602 if(er) return er;
603 graphss=sim->graphss; }
604
605 if(lt==-1) { // room lights
606 if(ltparam==LPambient) {
607 if(graphss->roomstate==LPauto) graphss->roomstate=LPon;
608 for(i=0;i<4;i++) graphss->ambiroom[i]=value[i]; }
609 else if(ltparam==LPon)
610 graphss->roomstate=LPon;
611 else if(ltparam==LPoff)
612 graphss->roomstate=LPoff;
613 else if(ltparam==LPauto) {
614 graphss->roomstate=LPauto;
615 graphss->ambiroom[0]=0.2; // low white ambient light
616 graphss->ambiroom[1]=0.2;
617 graphss->ambiroom[2]=0.2;
618 graphss->ambiroom[3]=1; }}
619
620 else if(ltparam==LPambient) {
621 if(graphss->lightstate[lt]==LPauto) graphss->lightstate[lt]=LPon;
622 for(i=0;i<4;i++) graphss->ambilight[lt][i]=value[i]; }
623 else if(ltparam==LPdiffuse) {
624 if(graphss->lightstate[lt]==LPauto) graphss->lightstate[lt]=LPon;
625 for(i=0;i<4;i++) graphss->difflight[lt][i]=value[i]; }
626 else if(ltparam==LPspecular) {
627 if(graphss->lightstate[lt]==LPauto) graphss->lightstate[lt]=LPon;
628 for(i=0;i<4;i++) graphss->speclight[lt][i]=value[i]; }
629 else if(ltparam==LPposition) {
630 if(graphss->lightstate[lt]==LPauto) graphss->lightstate[lt]=LPon;
631 for(i=0;i<4;i++) graphss->lightpos[lt][i]=value[i]; }
632 else if(ltparam==LPon)
633 graphss->lightstate[lt]=LPon;
634 else if(ltparam==LPoff)
635 graphss->lightstate[lt]=LPoff;
636 else if(ltparam==LPauto) {
637 graphss->lightstate[lt]=LPauto;
638 graphss->ambilight[lt][0]=0; // no ambient lightsource light
639 graphss->ambilight[lt][1]=0;
640 graphss->ambilight[lt][2]=0;
641 graphss->ambilight[lt][3]=1;
642 graphss->difflight[lt][0]=1; // white diffuse lightsource light
643 graphss->difflight[lt][1]=1;
644 graphss->difflight[lt][2]=1;
645 graphss->difflight[lt][3]=1;
646 graphss->speclight[lt][0]=1; // white specular lightsource light
647 graphss->speclight[lt][1]=1;
648 graphss->speclight[lt][2]=1;
649 graphss->speclight[lt][3]=1;
650 graphss->lightpos[lt][0]=1; // lightsource at (1,1,0)
651 graphss->lightpos[lt][1]=1;
652 graphss->lightpos[lt][2]=0;
653 graphss->lightpos[lt][3]=0; }
654
655 graphicssetcondition(graphss,SCparams,0);
656 return 0; }
657
658
659 /******************************************************************************/
660 /************************** structure update functions ************************/
661 /******************************************************************************/
662
663
664 /* graphicsupdateinit */
graphicsupdateinit(simptr sim)665 int graphicsupdateinit(simptr sim) {
666 #ifdef __gl_h_
667 graphicsssptr graphss;
668 int qflag,tflag,dim;
669 wallptr *wlist;
670
671 graphss=sim->graphss;
672 tflag=strchr(sim->flags,'t')?1:0;
673 if(tflag || graphss->graphics==0) return 0;
674
675 qflag=strchr(sim->flags,'q')?1:0;
676 gl2glutInit(NULL,NULL);
677 gl2SetOptionInt("Fix2DAspect",1);
678 gl2SetOptionVoid("FreeFunc",(void*) &simfree);
679 gl2SetOptionVoid("FreePointer",(void*)sim);
680 if(!qflag) simLog(sim,2,"Starting simulation\n");
681 dim=sim->dim;
682 wlist=sim->wlist;
683 if(dim==1) gl2Initialize(sim->filename,(float)wlist[0]->pos,(float)wlist[1]->pos,0,0,0,0);
684 else if(dim==2) gl2Initialize(sim->filename,(float)wlist[0]->pos,(float)wlist[1]->pos,(float)wlist[2]->pos,(float)wlist[3]->pos,0,0);
685 else {
686 gl2Initialize(sim->filename,(float)wlist[0]->pos,(float)wlist[1]->pos,(float)wlist[2]->pos,(float)wlist[3]->pos,(float)wlist[4]->pos,(float)wlist[5]->pos);
687 if(sim->srfss) {
688 glEnable(GL_BLEND);
689 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}}
690 #endif
691 return 0; }
692
693
694 /* graphicsupdatelists */
graphicsupdatelists(simptr sim)695 int graphicsupdatelists(simptr sim) {
696 #ifdef __gl_h_
697 graphicsssptr graphss;
698 int tflag;
699 GLfloat f1[4];
700
701 graphss=sim->graphss;
702 tflag=strchr(sim->flags,'t')?1:0;
703 if(tflag || graphss->graphics==0) return 0;
704
705 if(graphss->graphics>=3) {
706 glEnable(GL_LIGHTING);
707 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,gl2Double2GLfloat(graphss->ambiroom,f1,4));
708 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1);
709 glEnable(GL_COLOR_MATERIAL);
710 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); }
711 #endif
712 return 0; }
713
714
715 /* graphicsupdateparams */
graphicsupdateparams(simptr sim)716 int graphicsupdateparams(simptr sim) {
717 #ifdef __gl_h_
718 graphicsssptr graphss;
719 int lt,tflag;
720 GLenum gllightnum;
721 GLfloat glf1[4];
722
723 graphss=sim->graphss;
724 tflag=strchr(sim->flags,'t')?1:0;
725 if(tflag || graphss->graphics==0) return 0;
726
727 glClearColor((GLclampf)graphss->backcolor[0],(GLclampf)graphss->backcolor[1],(GLclampf)graphss->backcolor[2],(GLclampf)graphss->backcolor[3]);
728 if(graphss->graphics>=3) {
729 for(lt=0;lt<MAXLIGHTS;lt++)
730 if(graphss->lightstate[lt]==LPon) {
731 if(lt==0) gllightnum=GL_LIGHT0;
732 else if(lt==1) gllightnum=GL_LIGHT1;
733 else if(lt==2) gllightnum=GL_LIGHT2;
734 else if(lt==3) gllightnum=GL_LIGHT3;
735 else if(lt==4) gllightnum=GL_LIGHT4;
736 else if(lt==5) gllightnum=GL_LIGHT5;
737 else if(lt==6) gllightnum=GL_LIGHT6;
738 else gllightnum=GL_LIGHT7;
739 glLightfv(gllightnum,GL_AMBIENT,gl2Double2GLfloat(graphss->ambilight[lt],glf1,4));
740 glLightfv(gllightnum,GL_DIFFUSE,gl2Double2GLfloat(graphss->difflight[lt],glf1,4));
741 glLightfv(gllightnum,GL_SPECULAR,gl2Double2GLfloat(graphss->speclight[lt],glf1,4));
742 glLightfv(gllightnum,GL_POSITION,gl2Double2GLfloat(graphss->lightpos[lt],glf1,4));
743 glEnable(gllightnum); }}
744 #endif
745 return 0; }
746
747
748 /* graphicsupdate */
graphicsupdate(simptr sim)749 int graphicsupdate(simptr sim) {
750 int er;
751 graphicsssptr graphss;
752
753 graphss=sim->graphss;
754 if(graphss) {
755 if(graphss->condition==SCinit) {
756 er=graphicsupdateinit(sim);
757 if(er) return er;
758 graphicssetcondition(graphss,SClists,1); }
759 if(graphss->condition==SClists) {
760 er=graphicsupdatelists(sim);
761 if(er) return er;
762 graphicssetcondition(graphss,SCparams,1); }
763 if(graphss->condition==SCparams) {
764 er=graphicsupdateparams(sim);
765 if(er) return er;
766 graphicssetcondition(graphss,SCok,1); }}
767 return 0; }
768
769
770 /******************************************************************************/
771 /*************************** core simulation functions ************************/
772 /******************************************************************************/
773
774
775 /* RenderSurfaces */
RenderSurfaces(simptr sim)776 void RenderSurfaces(simptr sim) {
777 #ifdef __gl_h_
778 surfacessptr srfss;
779 surfaceptr srf;
780 int s,p,graphics,fdone,bdone,c;
781 double **point,*front;
782 double xlo,xhi,ylo,yhi,xpix,ypix,ymid,zmid;
783 double delta,deltax,deltay,theta,vect[3],vect2[3],axis[3],height;
784 double flcolor[4],blcolor[4];
785 enum DrawMode fdrawmode,bdrawmode,fdm,bdm;
786 GLdouble gldvect[3];
787 GLfloat glfvect[4];
788
789 srfss=sim->srfss;
790 graphics=sim->graphss->graphics;
791 if(!srfss) return;
792 xlo=gl2GetNumber("ClipLeft");
793 xhi=gl2GetNumber("ClipRight");
794 ylo=gl2GetNumber("ClipBot");
795 yhi=gl2GetNumber("ClipTop");
796 xpix=gl2GetNumber("PixWide");
797 ypix=gl2GetNumber("PixHigh");
798 ymid=gl2GetNumber("ClipMidy");
799 zmid=gl2GetNumber("ClipMidz");
800
801 if(sim->dim==1) {
802 for(s=0;s<srfss->nsrf;s++) {
803 srf=srfss->srflist[s];
804 if(srf->fdrawmode!=DMno) {
805 glLineWidth((GLfloat)srf->edgepts);
806 delta=srf->edgepts*(xhi-xlo)/xpix/2;
807 glColor4fv(gl2Double2GLfloat(srf->fcolor,glfvect,4));
808 glBegin(GL_LINES);
809 for(p=0;p<srf->npanel[0];p++) { // 1-D rectangles front
810 point=srf->panels[0][p]->point;
811 front=srf->panels[0][p]->front;
812 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
813 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid); }
814 for(p=0;p<srf->npanel[1];p++) { // 1-D triangles front
815 point=srf->panels[1][p]->point;
816 front=srf->panels[1][p]->front;
817 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
818 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid); }
819 for(p=0;p<srf->npanel[2];p++) { // 1-D spheres front
820 point=srf->panels[2][p]->point;
821 front=srf->panels[2][p]->front;
822 glVertex3d((GLdouble)(point[0][0]+point[1][0]+front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
823 glVertex3d((GLdouble)(point[0][0]+point[1][0]+front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid);
824 glVertex3d((GLdouble)(point[0][0]-point[1][0]-front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
825 glVertex3d((GLdouble)(point[0][0]-point[1][0]-front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid); }
826 glEnd();
827
828 delta*=-1;
829 glColor4fv(gl2Double2GLfloat(srf->bcolor,glfvect,4));
830 glBegin(GL_LINES);
831 for(p=0;p<srf->npanel[0];p++) { // 1-D rectangles back
832 point=srf->panels[0][p]->point;
833 front=srf->panels[0][p]->front;
834 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
835 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid); }
836 for(p=0;p<srf->npanel[1];p++) { // 1-D triangles back
837 point=srf->panels[1][p]->point;
838 front=srf->panels[1][p]->front;
839 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
840 glVertex3d((GLdouble)(point[0][0]+front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid); }
841 for(p=0;p<srf->npanel[2];p++) { // 1-D spheres back
842 point=srf->panels[2][p]->point;
843 front=srf->panels[2][p]->front;
844 glVertex3d((GLdouble)(point[0][0]+point[1][0]+front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
845 glVertex3d((GLdouble)(point[0][0]+point[1][0]+front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid);
846 glVertex3d((GLdouble)(point[0][0]-point[1][0]-front[0]*delta),(GLdouble)(ymid-(yhi-ylo)/20),(GLdouble)zmid);
847 glVertex3d((GLdouble)(point[0][0]-point[1][0]-front[0]*delta),(GLdouble)(ymid+(yhi-ylo)/20),(GLdouble)zmid); }
848 glEnd(); }}}
849
850 else if(sim->dim==2) {
851 for(s=0;s<srfss->nsrf;s++) {
852 srf=srfss->srflist[s];
853 fdrawmode=srf->fdrawmode;
854 bdrawmode=srf->bdrawmode;
855 if(fdrawmode!=DMno) {
856 glColor4fv(gl2Double2GLfloat(srf->fcolor,glfvect,4));
857 if(fdrawmode&DMedge || fdrawmode&DMface) {
858 glLineWidth((GLfloat)srf->edgepts);
859 deltax=srf->edgepts*(xhi-xlo)/xpix/2.5;
860 deltay=srf->edgepts*(yhi-ylo)/ypix/2.5;
861 glBegin(GL_LINES); }
862 else {
863 glPointSize((GLfloat)srf->edgepts);
864 deltax=deltay=0;
865 glBegin(GL_POINTS); }
866
867 for(p=0;p<srf->npanel[0];p++) { // 2-D rectangles front
868 point=srf->panels[0][p]->point;
869 front=srf->panels[0][p]->front;
870 if(front[1]==0) {
871 glVertex3d((GLdouble)(point[0][0]+front[0]*deltax),(GLdouble)(point[0][1]),(GLdouble)zmid);
872 glVertex3d((GLdouble)(point[1][0]+front[0]*deltax),(GLdouble)(point[1][1]),(GLdouble)zmid); }
873 else {
874 glVertex3d((GLdouble)(point[0][0]),(GLdouble)(point[0][1]+front[0]*deltay),(GLdouble)zmid);
875 glVertex3d((GLdouble)(point[1][0]),(GLdouble)(point[1][1]+front[0]*deltay),(GLdouble)zmid); }}
876 for(p=0;p<srf->npanel[1];p++) { // 2-D triangles front
877 point=srf->panels[1][p]->point;
878 front=srf->panels[1][p]->front;
879 glVertex3d((GLdouble)(point[0][0]+front[0]*deltax),(GLdouble)(point[0][1]+front[1]*deltay),(GLdouble)zmid);
880 glVertex3d((GLdouble)(point[1][0]+front[0]*deltax),(GLdouble)(point[1][1]+front[1]*deltay),(GLdouble)zmid); }
881 for(p=0;p<srf->npanel[3];p++) { // 2-D cylinders front
882 point=srf->panels[3][p]->point;
883 front=srf->panels[3][p]->front;
884 glVertex3d((GLdouble)(point[0][0]+front[0]*point[2][0]+front[2]*front[0]*deltax),(GLdouble)(point[0][1]+front[1]*point[2][0]+front[2]*front[1]*deltay),(GLdouble)zmid);
885 glVertex3d((GLdouble)(point[1][0]+front[0]*point[2][0]+front[2]*front[0]*deltax),(GLdouble)(point[1][1]+front[1]*point[2][0]+front[2]*front[1]*deltay),(GLdouble)zmid);
886 glVertex3d((GLdouble)(point[0][0]-front[0]*point[2][0]-front[2]*front[0]*deltax),(GLdouble)(point[0][1]-front[1]*point[2][0]-front[2]*front[1]*deltay),(GLdouble)zmid);
887 glVertex3d((GLdouble)(point[1][0]-front[0]*point[2][0]-front[2]*front[0]*deltax),(GLdouble)(point[1][1]-front[1]*point[2][0]-front[2]*front[1]*deltay),(GLdouble)zmid); }
888 for(p=0;p<srf->npanel[5];p++) { // 2-D disks front
889 point=srf->panels[5][p]->point;
890 front=srf->panels[5][p]->front;
891 glVertex3d((GLdouble)(point[0][0]+point[1][0]*front[1]+front[0]*deltax),(GLdouble)(point[0][1]-point[1][0]*front[0]+front[1]*deltay),(GLdouble)zmid);
892 glVertex3d((GLdouble)(point[0][0]-point[1][0]*front[1]+front[0]*deltax),(GLdouble)(point[0][1]+point[1][0]*front[0]+front[1]*deltay),(GLdouble)zmid); }
893 glEnd();
894 for(p=0;p<srf->npanel[2];p++) { // 2-D spheres front
895 point=srf->panels[2][p]->point;
896 front=srf->panels[2][p]->front;
897 if(fdrawmode&DMvert) gl2DrawCircleD(point[0],point[1][0],(int)point[1][1],'v',2);
898 if(fdrawmode&DMface) gl2DrawCircleD(point[0],point[1][0],(int)point[1][1],'f',2);
899 if(fdrawmode&DMedge) gl2DrawCircleD(point[0],point[1][0]+front[0]*deltax,(int)point[1][1],'e',2); }
900 for(p=0;p<srf->npanel[4];p++) { // 2-D hemispheres front
901 point=srf->panels[4][p]->point;
902 front=srf->panels[4][p]->front;
903 theta=atan2(point[2][1],point[2][0])+PI/2.0;
904 if(fdrawmode&DMvert) gl2DrawArcD(point[0],point[1][0],theta,theta+PI,(int)point[1][1],'v',2);
905 if(fdrawmode&DMface) gl2DrawArcD(point[0],point[1][0],theta,theta+PI,(int)point[1][1],'f',2);
906 if(fdrawmode&DMedge) gl2DrawArcD(point[0],point[1][0]+front[0]*deltax,theta,theta+PI,(int)point[1][1],'e',2); }
907
908 if(fdrawmode&DMedge || fdrawmode&DMface) {
909 deltax*=-1;
910 deltay*=-1;
911 glColor4fv(gl2Double2GLfloat(srf->bcolor,glfvect,4));
912 glBegin(GL_LINES);
913 for(p=0;p<srf->npanel[0];p++) { // 2-D rectangles back
914 point=srf->panels[0][p]->point;
915 front=srf->panels[0][p]->front;
916 if(front[1]==0) {
917 glVertex3d((GLdouble)(point[0][0]+front[0]*deltax),(GLdouble)(point[0][1]),(GLdouble)zmid);
918 glVertex3d((GLdouble)(point[1][0]+front[0]*deltax),(GLdouble)(point[1][1]),(GLdouble)zmid); }
919 else {
920 glVertex3d((GLdouble)(point[0][0]),(GLdouble)(point[0][1]+front[0]*deltay),(GLdouble)zmid);
921 glVertex3d((GLdouble)(point[1][0]),(GLdouble)(point[1][1]+front[0]*deltay),(GLdouble)zmid); }}
922 for(p=0;p<srf->npanel[1];p++) { // 2-D triangles back
923 point=srf->panels[1][p]->point;
924 front=srf->panels[1][p]->front;
925 glVertex3d((GLdouble)(point[0][0]+front[0]*deltax),(GLdouble)(point[0][1]+front[1]*deltay),(GLdouble)zmid);
926 glVertex3d((GLdouble)(point[1][0]+front[0]*deltax),(GLdouble)(point[1][1]+front[1]*deltay),(GLdouble)zmid); }
927 for(p=0;p<srf->npanel[3];p++) { // 2-D cylinders back
928 point=srf->panels[3][p]->point;
929 front=srf->panels[3][p]->front;
930 glVertex3d((GLdouble)(point[0][0]+front[0]*point[2][0]+front[2]*front[0]*deltax),(GLdouble)(point[0][1]+front[1]*point[2][0]+front[2]*front[1]*deltay),(GLdouble)zmid);
931 glVertex3d((GLdouble)(point[1][0]+front[0]*point[2][0]+front[2]*front[0]*deltax),(GLdouble)(point[1][1]+front[1]*point[2][0]+front[2]*front[1]*deltay),(GLdouble)zmid);
932 glVertex3d((GLdouble)(point[0][0]-front[0]*point[2][0]-front[2]*front[0]*deltax),(GLdouble)(point[0][1]-front[1]*point[2][0]-front[2]*front[1]*deltay),(GLdouble)zmid);
933 glVertex3d((GLdouble)(point[1][0]-front[0]*point[2][0]-front[2]*front[0]*deltax),(GLdouble)(point[1][1]-front[1]*point[2][0]-front[2]*front[1]*deltay),(GLdouble)zmid); }
934 for(p=0;p<srf->npanel[5];p++) { // 2-D disks back
935 point=srf->panels[5][p]->point;
936 front=srf->panels[5][p]->front;
937 glVertex3d((GLdouble)(point[0][0]+point[1][0]*front[1]+front[0]*deltax),(GLdouble)(point[0][1]-point[1][0]*front[0]+front[1]*deltay),(GLdouble)zmid);
938 glVertex3d((GLdouble)(point[0][0]-point[1][0]*front[1]+front[0]*deltax),(GLdouble)(point[0][1]+point[1][0]*front[0]+front[1]*deltay),(GLdouble)zmid); }
939 glEnd();
940 for(p=0;p<srf->npanel[2];p++) { // 2-D spheres back
941 point=srf->panels[2][p]->point;
942 front=srf->panels[2][p]->front;
943 if(bdrawmode&DMedge) gl2DrawCircleD(point[0],point[1][0]+front[0]*deltax,(int)point[1][1],'e',2); }
944 for(p=0;p<srf->npanel[4];p++) { // 2-D hemispheres back
945 point=srf->panels[4][p]->point;
946 front=srf->panels[4][p]->front;
947 theta=atan2(point[2][1],point[2][0])+PI/2.0;
948 if(bdrawmode&DMedge) gl2DrawArcD(point[0],point[1][0]+front[0]*deltax,theta,theta+PI,(int)point[1][1],'e',2); }}}}}
949
950 else if(sim->dim==3) {
951 for(s=0;s<srfss->nsrf;s++) {
952 srf=srfss->srflist[s];
953 fdrawmode=srf->fdrawmode;
954 bdrawmode=srf->bdrawmode;
955 for(c=0;c<4;c++) flcolor[c]=srf->fcolor[c];
956 for(c=0;c<4;c++) blcolor[c]=srf->bcolor[c];
957
958 if(fdrawmode&DMface) fdm=DMface;
959 else if(fdrawmode&DMedge) fdm=DMedge;
960 else if(fdrawmode&DMvert) fdm=DMvert;
961 else fdm=DMno;
962
963 if(bdrawmode&DMface) bdm=DMface;
964 else if(bdrawmode&DMedge) bdm=DMedge;
965 else if(bdrawmode&DMvert) bdm=DMvert;
966 else bdm=DMno;
967
968 while(fdm || bdm) {
969 if(fdm==DMface) glPolygonMode(GL_FRONT,GL_FILL);
970 else if(fdm==DMedge) glPolygonMode(GL_FRONT,GL_LINE);
971 else if(fdm==DMvert) glPolygonMode(GL_FRONT,GL_POINT);
972 else glCullFace(GL_FRONT);
973
974 if(bdm==DMface) glPolygonMode(GL_BACK,GL_FILL);
975 else if(bdm==DMedge) glPolygonMode(GL_BACK,GL_LINE);
976 else if(bdm==DMvert) glPolygonMode(GL_BACK,GL_POINT);
977 else glCullFace(GL_BACK);
978
979 glColor4fv(gl2Double2GLfloat(flcolor,glfvect,4));
980 glLineWidth((GLfloat)srf->edgepts);
981 if(graphics>=2 && srf->edgestipple[1]!=0xFFFF) {
982 glEnable(GL_LINE_STIPPLE);
983 glLineStipple((GLint)srf->edgestipple[0],(GLushort)srf->edgestipple[1]); }
984
985 if(graphics>=3) {
986 glMaterialfv(GL_FRONT,GL_SPECULAR,gl2Double2GLfloat(flcolor,glfvect,4));
987 glMaterialfv(GL_BACK,GL_SPECULAR,gl2Double2GLfloat(blcolor,glfvect,4));
988 glMateriali(GL_FRONT,GL_SHININESS,(GLint)srf->fshiny);
989 glMateriali(GL_BACK,GL_SHININESS,(GLint)srf->bshiny); }
990
991 if(srf->npanel[PSrect]) {
992 glBegin(GL_QUADS); // 3-D rectangles
993 for(p=0;p<srf->npanel[PSrect];p++) {
994 if(graphics>=3) {
995 gldvect[0]=gldvect[1]=gldvect[2]=0;
996 front=srf->panels[PSrect][p]->front;
997 gldvect[(int)front[1]]=(GLdouble)front[0];
998 glNormal3dv(gldvect); }
999 point=srf->panels[PSrect][p]->point;
1000 glVertex3d((GLdouble)(point[0][0]),(GLdouble)(point[0][1]),(GLdouble)(point[0][2]));
1001 glVertex3d((GLdouble)(point[1][0]),(GLdouble)(point[1][1]),(GLdouble)(point[1][2]));
1002 glVertex3d((GLdouble)(point[2][0]),(GLdouble)(point[2][1]),(GLdouble)(point[2][2]));
1003 glVertex3d((GLdouble)(point[3][0]),(GLdouble)(point[3][1]),(GLdouble)(point[3][2])); }
1004 glEnd(); }
1005
1006 if(srf->npanel[PStri]) {
1007 glBegin(GL_TRIANGLES); // 3-D triangles
1008 for(p=0;p<srf->npanel[PStri];p++) {
1009 if(graphics>=3) glNormal3fv(gl2Double2GLfloat(srf->panels[PStri][p]->front,glfvect,4));
1010 point=srf->panels[PStri][p]->point;
1011 glVertex3d((GLdouble)(point[0][0]),(GLdouble)(point[0][1]),(GLdouble)(point[0][2]));
1012 glVertex3d((GLdouble)(point[1][0]),(GLdouble)(point[1][1]),(GLdouble)(point[1][2]));
1013 glVertex3d((GLdouble)(point[2][0]),(GLdouble)(point[2][1]),(GLdouble)(point[2][2])); }
1014 glEnd(); }
1015
1016 for(p=0;p<srf->npanel[PSsph];p++) { // 3-D spheres
1017 point=srf->panels[PSsph][p]->point;
1018 front=srf->panels[PSsph][p]->front;
1019 glMatrixMode(GL_MODELVIEW);
1020 glPushMatrix();
1021 glTranslated((GLdouble)(point[0][0]),(GLdouble)(point[0][1]),(GLdouble)(point[0][2]));
1022 gl2DrawSphere(point[1][0],(int)point[1][1],(int)point[1][2],front[0]>0?0:1,graphics>=3?1:0);
1023 glPopMatrix(); }
1024
1025 for(p=0;p<srf->npanel[PScyl];p++) { // 3-D cylinders
1026 point=srf->panels[PScyl][p]->point;
1027 front=srf->panels[PScyl][p]->front;
1028 glMatrixMode(GL_MODELVIEW);
1029 glPushMatrix();
1030 glTranslated((GLdouble)(point[0][0]),(GLdouble)(point[0][1]),(GLdouble)(point[0][2]));
1031 vect[0]=vect[1]=0;
1032 vect[2]=1;
1033 vect2[0]=point[1][0]-point[0][0];
1034 vect2[1]=point[1][1]-point[0][1];
1035 vect2[2]=point[1][2]-point[0][2];
1036 height=sqrt(vect2[0]*vect2[0]+vect2[1]*vect2[1]+vect2[2]*vect2[2]);
1037 normalizeVD(vect2,3);
1038 theta=gl2FindRotateD(vect,vect2,axis);
1039 glRotated((GLdouble)theta,(GLdouble)(axis[0]),(GLdouble)(axis[1]),(GLdouble)(axis[2]));
1040 gl2DrawCylinder(point[2][0],point[2][0],height,(int)point[2][1],(int)point[2][2],front[0]>0?0:1,graphics>=3?1:0);
1041 glPopMatrix(); }
1042
1043 for(p=0;p<srf->npanel[PShemi];p++) { // 3-D hemispheres
1044 point=srf->panels[PShemi][p]->point;
1045 front=srf->panels[PShemi][p]->front;
1046 glMatrixMode(GL_MODELVIEW);
1047 glPushMatrix();
1048 glTranslated((GLdouble)(point[0][0]),(GLdouble)(point[0][1]),(GLdouble)(point[0][2]));
1049 vect[0]=vect[1]=0;
1050 vect[2]=-1;
1051 theta=gl2FindRotateD(vect,point[2],axis);
1052 glRotated((GLdouble)theta,(GLdouble)(axis[0]),(GLdouble)(axis[1]),(GLdouble)(axis[2]));
1053 gl2DrawHemisphere(point[1][0],(int)point[1][1],(int)point[1][2],front[0]>0?0:1,graphics>=3?1:0);
1054 glPopMatrix(); }
1055
1056 for(p=0;p<srf->npanel[PSdisk];p++) { // 3-D disks
1057 point=srf->panels[PSdisk][p]->point;
1058 front=srf->panels[PSdisk][p]->front;
1059 glMatrixMode(GL_MODELVIEW);
1060 glPushMatrix();
1061 glTranslated((GLdouble)(point[0][0]),(GLdouble)(point[0][1]),(GLdouble)(point[0][2]));
1062 vect[0]=vect[1]=0;
1063 vect[2]=-1;
1064 theta=gl2FindRotateD(vect,front,axis);
1065 glRotated((GLdouble)theta,(GLdouble)(axis[0]),(GLdouble)(axis[1]),(GLdouble)(axis[2]));
1066 vect2[0]=vect2[1]=vect2[2]=0;
1067 gl2DrawCircleD(vect2,point[1][0],(int)point[1][1],'f',3); //?? 'f' isn't right
1068 glPopMatrix(); }
1069
1070 fdone=0;
1071 if(fdm==DMface && fdrawmode&DMedge) fdm=DMedge;
1072 else if((fdm==DMface || fdm==DMedge) && fdrawmode&DMvert) fdm=DMvert;
1073 else fdone=1;
1074
1075 bdone=0;
1076 if(bdm==DMface && bdrawmode&DMedge) bdm=DMedge;
1077 else if((bdm==DMface || bdm==DMedge) && bdrawmode&DMvert) bdm=DMvert;
1078 else bdone=1;
1079
1080 if(fdone && bdone) fdm=bdm=DMno;
1081 else {
1082 for(c=0;c<3;c++) flcolor[c]=blcolor[c]=0;
1083 flcolor[3]=blcolor[3]=1; }}
1084
1085 if((fdrawmode || bdrawmode) && glIsEnabled(GL_LINE_STIPPLE))
1086 glDisable(GL_LINE_STIPPLE); }}
1087 #endif
1088 return; }
1089
1090
1091 /* RenderFilaments */
RenderFilaments(simptr sim)1092 void RenderFilaments(simptr sim) {
1093 #ifdef __gl_h_
1094 filamentssptr filss;
1095 filamenttypeptr filtype;
1096 filamentptr fil;
1097 int f,vtx,graphics,ft;
1098 double *point;
1099 enum DrawMode drawmode;
1100 GLfloat glfvect[4];
1101
1102 filss=sim->filss;
1103 if(!filss) return;
1104 graphics=sim->graphss->graphics;
1105
1106 for(ft=0;ft<filss->ntype;ft++) {
1107 filtype=filss->filtypes[ft];
1108 drawmode=filtype->drawmode;
1109
1110 for(f=0;f<filtype->nfil;f++) {
1111 fil=filtype->fillist[f];
1112 if(drawmode==DMno);
1113
1114 else if(drawmode&DMvert || drawmode&DMedge) {
1115 glColor4fv(gl2Double2GLfloat(filtype->color,glfvect,4));
1116 if(graphics>=2 && filtype->edgestipple[1]!=0xFFFF) {
1117 glEnable(GL_LINE_STIPPLE);
1118 glLineStipple((GLint)filtype->edgestipple[0],(GLushort)filtype->edgestipple[1]); }
1119 if(drawmode&DMedge) {
1120 glLineWidth((GLfloat)filtype->edgepts);
1121 glBegin(GL_LINE_STRIP); }
1122 else {
1123 glPointSize((GLfloat)filtype->edgepts);
1124 glBegin(GL_POINTS); }
1125
1126 for(vtx=fil->frontbs;vtx<fil->nbs+fil->frontbs;vtx++) {
1127 if(filtype->isbead)
1128 point=fil->beads[vtx]->xyz;
1129 else
1130 point=fil->segments[vtx]->xyzfront;
1131 glVertex3d((GLdouble)(point[0]),(GLdouble)(point[1]),(GLdouble)(point[2])); }
1132 if(!filtype->isbead) {
1133 point=fil->segments[vtx-1]->xyzback;
1134 glVertex3d((GLdouble)(point[0]),(GLdouble)(point[1]),(GLdouble)(point[2])); }
1135 glEnd(); }
1136
1137 else if(drawmode&DMface) {
1138 glPolygonMode(GL_FRONT,GL_FILL);
1139 glCullFace(GL_BACK);
1140 if(graphics>=3) {
1141 //glMaterialfv(GL_FRONT,GL_SPECULAR,gl2Double2GLfloat(srf->fcolor,glfvect,4));
1142 //glMaterialfv(GL_BACK,GL_SPECULAR,gl2Double2GLfloat(srf->bcolor,glfvect,4));
1143 glMateriali(GL_FRONT,GL_SHININESS,(GLint)filtype->shiny); }
1144 for(vtx=fil->frontbs;vtx<fil->nbs+fil->frontbs;vtx++)
1145 /*gl2drawtwistprism(fil->px[vtx],fil->px[vtx+1],fil->nface,fil->po[vtx],twist,fil->radius,fil->facecolor)*/; }
1146 if(glIsEnabled(GL_LINE_STIPPLE))
1147 glDisable(GL_LINE_STIPPLE); }}
1148
1149 #endif
1150 return; }
1151
1152
1153 /* RenderMolecs */
RenderMolecs(simptr sim)1154 void RenderMolecs(simptr sim) {
1155 #ifdef __gl_h_
1156 molssptr mols;
1157 moleculeptr mptr;
1158 int ll,m,i,dim;
1159 double ymid,zmid;
1160 enum MolecState ms;
1161 GLfloat whitecolor[]={1,1,1,1};
1162 GLfloat glf1[4];
1163
1164 dim=sim->dim;
1165 mols=sim->mols;
1166 if(!mols) return;
1167 ymid=gl2GetNumber("ClipMidy");
1168 zmid=gl2GetNumber("ClipMidz");
1169
1170 if(sim->graphss->graphics==1) {
1171 for(ll=0;ll<sim->mols->nlist;ll++)
1172 if(sim->mols->listtype[ll]==MLTsystem)
1173 for(m=0;m<mols->nl[ll];m++) {
1174 mptr=mols->live[ll][m];
1175 i=mptr->ident;
1176 ms=mptr->mstate;
1177 if(mols->display[i][ms]>0) {
1178 glPointSize((GLfloat)mols->display[i][ms]);
1179 glColor3fv(gl2Double2GLfloat(mols->color[i][ms],glf1,3));
1180 glBegin(GL_POINTS);
1181 if(dim==1) glVertex3d((GLdouble)mptr->pos[0],(GLdouble)ymid,(GLdouble)zmid);
1182 else if(dim==2) glVertex3d((GLdouble)(mptr->pos[0]),(GLdouble)(mptr->pos[1]),(GLdouble)zmid);
1183 else glVertex3fv(gl2Double2GLfloat(mptr->pos,glf1,3));
1184 glEnd(); }}}
1185
1186 else if(sim->graphss->graphics>=2) {
1187 glMatrixMode(GL_MODELVIEW);
1188 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
1189 if(sim->graphss->graphics>=3) {
1190 glMaterialfv(GL_FRONT,GL_SPECULAR,whitecolor);
1191 glMateriali(GL_FRONT,GL_SHININESS,30); }
1192 for(ll=0;ll<sim->mols->nlist;ll++)
1193 if(sim->mols->listtype[ll]==MLTsystem)
1194 for(m=0;m<mols->nl[ll];m++) {
1195 mptr=mols->live[ll][m];
1196 i=mptr->ident;
1197 ms=mptr->mstate;
1198 if(mols->display[i][ms]>0) {
1199 glColor3fv(gl2Double2GLfloat(mols->color[i][ms],glf1,3));
1200 glPushMatrix();
1201 if(dim==1) glTranslated((GLdouble)(mptr->pos[0]),(GLdouble)ymid,(GLdouble)zmid);
1202 else if(dim==2) glTranslated((GLdouble)(mptr->pos[0]),(GLdouble)(mptr->pos[1]),(GLdouble)zmid);
1203 else glTranslated((GLdouble)(mptr->pos[0]),(GLdouble)(mptr->pos[1]),(GLdouble)(mptr->pos[2]));
1204 glutSolidSphere((GLdouble)(mols->display[i][ms]),15,15);
1205 glPopMatrix(); }}}
1206
1207 #endif
1208 return; }
1209
1210
1211 /* RenderLattice */
RenderLattice(simptr sim)1212 void RenderLattice(simptr sim) {
1213 #ifdef __gl_h_
1214 latticeptr lattice;
1215 int lat,n,ilat,ismol,i,dim;
1216 const int *copy_numbers;
1217 const double* positions;
1218 molssptr mols;
1219 GLfloat glf1[4];
1220 double poslo[3],poshi[3],deltay;
1221
1222 mols=sim->mols;
1223 dim=sim->dim;
1224 poslo[0]=poshi[0]=gl2GetNumber("ClipMidx");
1225 poslo[1]=poshi[1]=gl2GetNumber("ClipMidy");
1226 poslo[2]=poshi[2]=gl2GetNumber("ClipMidz");
1227 for(lat=0;lat<sim->latticess->nlattice;lat++) {
1228 lattice = sim->latticess->latticelist[lat];
1229 positions=NULL;
1230 copy_numbers=NULL;
1231 n=0;
1232 for(ilat=0;ilat<lattice->nspecies;ilat++) { // ilat is the species identity
1233 ismol=lattice->species_index[ilat];
1234 NSV_CALL(n = nsv_get_species_copy_numbers(lattice->nsv, ismol,©_numbers,&positions));
1235 for (i=0;i<n;++i) { // n is the total number of molecules of this species, copy_numbers is how many in each site, and positions are the site positions
1236 if((mols->display[ismol][MSsoln]>0)&&(copy_numbers[i]>0)) {
1237 poslo[0]=positions[3*i+0]-0.5*lattice->dx[0];
1238 poshi[0]=positions[3*i+0]+0.5*lattice->dx[0];
1239 if(dim==1) {
1240 deltay=0.025*(gl2GetNumber("ClipTop")-gl2GetNumber("ClipBot"));
1241 poslo[1]-=deltay;
1242 poshi[1]+=deltay; }
1243 else if(dim>1) {
1244 poslo[1]=positions[3*i+1]-0.5*lattice->dx[1];
1245 poshi[1]=positions[3*i+1]+0.5*lattice->dx[1]; }
1246 if(dim>2) {
1247 poslo[2]=positions[3*i+2]-0.5*lattice->dx[2];
1248 poshi[2]=positions[3*i+2]+0.5*lattice->dx[2]; }
1249 glColor3fv(gl2Double2GLfloat(mols->color[ismol][MSsoln],glf1,3));
1250 gl2DrawBoxFaceD(poslo,poshi,dim==3?3:2); }}}}
1251 #endif
1252 return; }
1253
1254
1255 /* RenderText */
RenderText(simptr sim)1256 void RenderText(simptr sim) {
1257 #ifdef __gl_h_
1258 graphicsssptr graphss;
1259 int item,i,*index;
1260 char *itemname,string[STRCHAR],string2[STRCHAR];
1261 enum MolecState ms;
1262
1263 graphss=sim->graphss;
1264 string2[0]='\0';
1265 for(item=0;item<graphss->ntextitems;item++) {
1266 itemname=graphss->textitems[item];
1267 if(!strcmp(itemname,"time"))
1268 snprintf(string,STRCHAR,"time: %g",sim->time);
1269 else if((i=molstring2index1(sim,itemname,&ms,&index))>=0 || i==-5)
1270 snprintf(string,STRCHAR,"%s: %i",itemname,molcount(sim,i,index,ms,-1));
1271 else if(sim->ruless)
1272 snprintf(string,STRCHAR,"%s: 0",itemname);
1273 else
1274 snprintf(string,STRCHAR,"syntax error");
1275
1276 if(STRCHAR-strlen(string2)>strlen(string))
1277 strcat(string2,string);
1278 if(item+1<graphss->ntextitems)
1279 strncat(string2,", ",STRCHAR-3); }
1280 gl2DrawTextD(5,95,graphss->textcolor,GLUT_BITMAP_HELVETICA_12,string2,-1);
1281 #endif
1282 return; }
1283
1284
1285 /* RenderSim */
RenderSim(simptr sim)1286 void RenderSim(simptr sim) {
1287 #ifdef __gl_h_
1288 graphicsssptr graphss;
1289 double pt1[DIMMAX],pt2[DIMMAX];
1290 int dim;
1291 wallptr *wlist;
1292 GLfloat glf1[4];
1293
1294 graphss=sim->graphss;
1295 if(!graphss || graphss->graphics==0) return;
1296 dim=sim->dim;
1297 wlist=sim->wlist;
1298 if(dim<3) glClear(GL_COLOR_BUFFER_BIT);
1299 else glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1300
1301 if(dim==3) RenderMolecs(sim);
1302
1303 if(graphss->framepts) { // draw bounding box
1304 pt1[0]=wlist[0]->pos;
1305 pt2[0]=wlist[1]->pos;
1306 pt1[1]=dim>1?wlist[2]->pos:0;
1307 pt2[1]=dim>1?wlist[3]->pos:0;
1308 pt1[2]=dim>2?wlist[4]->pos:0;
1309 pt2[2]=dim>2?wlist[5]->pos:0;
1310 glColor4fv(gl2Double2GLfloat(graphss->framecolor,glf1,4));
1311 glLineWidth((GLfloat)graphss->framepts);
1312 gl2DrawBoxD(pt1,pt2,dim); }
1313
1314 if(graphss->gridpts) {
1315 pt1[0]=sim->boxs->min[0];
1316 pt2[0]=pt1[0]+sim->boxs->size[0]*sim->boxs->side[0];
1317 pt1[1]=dim>1?sim->boxs->min[1]:0;
1318 pt2[1]=dim>1?pt1[1]+sim->boxs->size[1]*sim->boxs->side[1]:0;
1319 pt1[2]=dim>2?sim->boxs->min[2]:0;
1320 pt2[2]=dim>2?pt1[2]+sim->boxs->size[2]*sim->boxs->side[2]:0;
1321 glColor4fv(gl2Double2GLfloat(graphss->gridcolor,glf1,4));
1322 if(dim==1) glPointSize((GLfloat)graphss->gridpts);
1323 else glLineWidth((GLfloat)graphss->gridpts);
1324 gl2DrawGridD(pt1,pt2,sim->boxs->side,dim); }
1325
1326 if(dim<3) RenderMolecs(sim);
1327
1328 if(sim->srfss) RenderSurfaces(sim);
1329 if(sim->filss) RenderFilaments(sim);
1330 if(sim->latticess) RenderLattice(sim);
1331 if(graphss->ntextitems) RenderText(sim);
1332
1333 glutSwapBuffers();
1334 #endif
1335 return; }
1336
1337
1338 /******************************************************************************/
1339 /************************** Top level OpenGL functions ************************/
1340 /******************************************************************************/
1341
1342
1343 void RenderScene(void);
1344 void TimerFunction(int state);
1345
1346 simptr Sim;
1347
1348
1349 /* smolPostRedisplay */
smolPostRedisplay(void)1350 void smolPostRedisplay(void) { //??
1351 #ifdef __gl_h_
1352 glutPostRedisplay();
1353 #endif
1354 return; }
1355
1356
1357 /* RenderScene */
RenderScene(void)1358 void RenderScene(void) {
1359 RenderSim(Sim);
1360 return; }
1361
1362
1363 /* TimerFunction */
TimerFunction(int state)1364 void TimerFunction(int state) {
1365 #ifdef __gl_h_
1366 static int oldstate=0;
1367 unsigned int delay;
1368 int it;
1369 simptr sim;
1370 graphicsssptr graphss;
1371
1372 sim=Sim;
1373 graphss=sim->graphss;
1374 //qflag=strchr(sim->flags,'q')?1:0;
1375 delay=graphss->graphicdelay;
1376
1377 if(oldstate==1 && gl2State(-1)==0) { // leave pause state
1378 oldstate=0;
1379 sim->clockstt=time(NULL);
1380 simLog(sim,2,"Simulation running\n"); }
1381
1382 if(state==0 && gl2State(-1)==0) { // normal run mode
1383 it=graphss->currentit;
1384 if(!(it%graphss->graphicit)) glutPostRedisplay();
1385 if(graphss->tiffit>0 && it>0 && !((it-1)%graphss->tiffit)) gl2SetKeyPush('T');
1386 state=simulatetimestep(sim);
1387 graphss->currentit++; }
1388 else if(state>0 || (state==0 && gl2State(-1)==2)) { // stop the simulation
1389 if(oldstate==0) sim->elapsedtime+=difftime(time(NULL),sim->clockstt);
1390 scmdpop(sim->cmds,sim->tmax);
1391 scmdexecute(sim->cmds,sim->time,sim->dt,-1,1);
1392 scmdsetcondition(sim->cmds,0,0);
1393 endsimulate(sim,state);
1394 if(sim->quitatend) gl2SetKeyPush('Q'); //??
1395 state=-1; }
1396 else if(oldstate==0 && gl2State(-1)==1) { // enter pause state
1397 sim->elapsedtime+=difftime(time(NULL),sim->clockstt);
1398 oldstate=1;
1399 delay=20;
1400 simLog(sim,2,"Simulation paused at simulation time: %g\n",sim->time); }
1401 else { // still in pause state or simulation is over
1402 glutPostRedisplay();
1403 delay=20; }
1404
1405 glutTimerFunc(delay,TimerFunction,state);
1406 #endif
1407 return; }
1408
1409
1410
1411 /* smolsimulategl */
smolsimulategl(simptr sim)1412 void smolsimulategl(simptr sim) {
1413 #ifdef __gl_h_
1414 int er;
1415
1416 glutTimerFunc((unsigned int)0,TimerFunction,0);
1417 Sim=sim;
1418 sim->clockstt=time(NULL);
1419 er=simdocommands(sim);
1420 if(er) endsimulate(sim,er);
1421 glutDisplayFunc(RenderScene);
1422 glutMainLoop();
1423 #else
1424 simLog(sim,5,"Graphics are unavailable, so performing non-graphics simulation.\n");
1425 smolsimulate(sim);
1426 #endif
1427 return; }
1428